Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1fcf2ea

Browse files
Uniquify ReError on input mode in canonicalizer
1 parent 1447f9d commit 1fcf2ea

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

‎compiler/rustc_next_trait_solver/src/canonicalizer.rs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
239239
// FIXME: We should investigate the perf implications of not uniquifying
240240
// `ReErased`. We may be able to short-circuit registering region
241241
// obligations if we encounter a `ReErased` on one side, for example.
242-
ty::ReStatic | ty::ReErased => match self.canonicalize_mode {
242+
ty::ReStatic | ty::ReErased | ty::ReError(_)=> match self.canonicalize_mode {
243243
CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT),
244244
CanonicalizeMode::Response { .. } => return r,
245245
},
@@ -277,7 +277,6 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
277277
}
278278
}
279279
}
280-
ty::ReError(_) => return r,
281280
};
282281

283282
let existing_bound_var = match self.canonicalize_mode {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//@ compile-flags: -Znext-solver
2+
3+
trait Tr<'a> {}
4+
5+
// Fulfillment in the new solver relies on an invariant to hold: Either
6+
// `has_changed` is true, or computing a goal's certainty is idempotent.
7+
// This isn't true for `ReError`, which we used to pass through in the
8+
// canonicalizer even on input mode, which can cause a goal to go from
9+
// ambig => pass, but we don't consider `has_changed` when the response
10+
// only contains region constraints (since we usually uniquify regions).
11+
//
12+
// In this test:
13+
// Implicit negative coherence tries to prove `W<?0>: Constrain<'?1>`,
14+
// which will then match with the impl below. This constrains `'?1` to
15+
// `ReError`, but still bails w/ ambiguity bc we can't prove `?0: Sized`.
16+
// Then, when we recompute the goal `W<?0>: Constrain<'error>`, when
17+
// collecting ambiguities and overflows, we end up assembling a default
18+
// error candidate w/o ambiguity, which causes the goal to pass, and ICE.
19+
impl<'a, A: ?Sized> Tr<'a> for W<A> {}
20+
struct W<A: ?Sized>(A);
21+
impl<'a, A: ?Sized> Tr<'a> for A where A: Constrain<'a> {}
22+
//~^ ERROR conflicting implementations of trait `Tr<'_>` for type `W<_>`
23+
24+
trait Constrain<'a> {}
25+
impl<A: Sized> Constrain<'missing> for W<A> {}
26+
//~^ ERROR use of undeclared lifetime name `'missing`
27+
28+
fn main() {}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0261]: use of undeclared lifetime name `'missing`
2+
--> $DIR/dont-canonicalize-re-error.rs:25:26
3+
|
4+
LL | impl<A: Sized> Constrain<'missing> for W<A> {}
5+
| - ^^^^^^^^ undeclared lifetime
6+
| |
7+
| help: consider introducing lifetime `'missing` here: `'missing,`
8+
9+
error[E0119]: conflicting implementations of trait `Tr<'_>` for type `W<_>`
10+
--> $DIR/dont-canonicalize-re-error.rs:21:1
11+
|
12+
LL | impl<'a, A: ?Sized> Tr<'a> for W<A> {}
13+
| ----------------------------------- first implementation here
14+
LL | struct W<A: ?Sized>(A);
15+
LL | impl<'a, A: ?Sized> Tr<'a> for A where A: Constrain<'a> {}
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<_>`
17+
18+
error: aborting due to 2 previous errors
19+
20+
Some errors have detailed explanations: E0119, E0261.
21+
For more information about an error, try `rustc --explain E0119`.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /