Skip to content

Commit 762a661

Browse files
authored
Rollup merge of #133493 - lcnr:fulfill-fudge, r=compiler-errors
do not constrain infer vars in `find_best_leaf_obligation` This ended up causing an ICE by making the following code path reachable by incorrectly constraining an inference variable while computing the best obligation for a preceding ambiguity. Closes #129444. https://github.com/rust-lang/rust/blob/f2abf827c128120ed7a874d02973947968c158b8/compiler/rustc_trait_selection/src/solve/fulfill.rs#L312-L314 I have to be honest, I don't fully understand how that change removes all the additional diagnostics :3 r? `@compiler-errors`
2 parents 3cce78b + fa66288 commit 762a661

13 files changed

+114
-138
lines changed

compiler/rustc_trait_selection/src/solve/fulfill.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -346,12 +346,21 @@ fn find_best_leaf_obligation<'tcx>(
346346
consider_ambiguities: bool,
347347
) -> PredicateObligation<'tcx> {
348348
let obligation = infcx.resolve_vars_if_possible(obligation.clone());
349+
// FIXME: we use a probe here as the `BestObligation` visitor does not
350+
// check whether it uses candidates which get shadowed by where-bounds.
351+
//
352+
// We should probably fix the visitor to not do so instead, as this also
353+
// means the leaf obligation may be incorrect.
349354
infcx
350-
.visit_proof_tree(obligation.clone().into(), &mut BestObligation {
351-
obligation: obligation.clone(),
352-
consider_ambiguities,
355+
.fudge_inference_if_ok(|| {
356+
infcx
357+
.visit_proof_tree(obligation.clone().into(), &mut BestObligation {
358+
obligation: obligation.clone(),
359+
consider_ambiguities,
360+
})
361+
.break_value()
362+
.ok_or(())
353363
})
354-
.break_value()
355364
.unwrap_or(obligation)
356365
}
357366

tests/crashes/129444.rs

-15
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// A regression test for #129444. This previously ICE'd as
2+
// computing the best obligation for one ambiguous obligation
3+
// added spurious inference constraints which caused another
4+
// candidate to pass.
5+
trait Trait {
6+
type Assoc;
7+
}
8+
9+
struct W<T: Trait>(*mut T);
10+
impl<T> Trait for W<W<W<T>>> {}
11+
//~^ ERROR the trait bound `W<W<T>>: Trait` is not satisfied
12+
//~| ERROR the trait bound `W<T>: Trait` is not satisfied
13+
//~| ERROR the trait bound `T: Trait` is not satisfied
14+
//~| ERROR not all trait items implemented, missing: `Assoc`
15+
16+
trait NoOverlap {}
17+
impl<T: Trait> NoOverlap for T {}
18+
impl<T: Trait<Assoc = u32>> NoOverlap for W<T> {}
19+
//~^ ERROR conflicting implementations of trait `NoOverlap` for type `W<W<W<W<_>>>>`
20+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
error[E0277]: the trait bound `W<W<T>>: Trait` is not satisfied
2+
--> $DIR/best-obligation-ICE.rs:10:19
3+
|
4+
LL | impl<T> Trait for W<W<W<T>>> {}
5+
| ^^^^^^^^^^ the trait `Trait` is not implemented for `W<W<T>>`
6+
|
7+
note: required by a bound in `W`
8+
--> $DIR/best-obligation-ICE.rs:9:13
9+
|
10+
LL | struct W<T: Trait>(*mut T);
11+
| ^^^^^ required by this bound in `W`
12+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
13+
|
14+
LL | impl<T> Trait for W<W<W<T>>> where W<W<T>>: Trait {}
15+
| ++++++++++++++++++++
16+
17+
error[E0277]: the trait bound `W<T>: Trait` is not satisfied
18+
--> $DIR/best-obligation-ICE.rs:10:19
19+
|
20+
LL | impl<T> Trait for W<W<W<T>>> {}
21+
| ^^^^^^^^^^ the trait `Trait` is not implemented for `W<T>`
22+
|
23+
note: required by a bound in `W`
24+
--> $DIR/best-obligation-ICE.rs:9:13
25+
|
26+
LL | struct W<T: Trait>(*mut T);
27+
| ^^^^^ required by this bound in `W`
28+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
29+
|
30+
LL | impl<T> Trait for W<W<W<T>>> where W<T>: Trait {}
31+
| +++++++++++++++++
32+
33+
error[E0277]: the trait bound `T: Trait` is not satisfied
34+
--> $DIR/best-obligation-ICE.rs:10:19
35+
|
36+
LL | impl<T> Trait for W<W<W<T>>> {}
37+
| ^^^^^^^^^^ the trait `Trait` is not implemented for `T`
38+
|
39+
note: required by a bound in `W`
40+
--> $DIR/best-obligation-ICE.rs:9:13
41+
|
42+
LL | struct W<T: Trait>(*mut T);
43+
| ^^^^^ required by this bound in `W`
44+
help: consider restricting type parameter `T`
45+
|
46+
LL | impl<T: Trait> Trait for W<W<W<T>>> {}
47+
| +++++++
48+
49+
error[E0046]: not all trait items implemented, missing: `Assoc`
50+
--> $DIR/best-obligation-ICE.rs:10:1
51+
|
52+
LL | type Assoc;
53+
| ---------- `Assoc` from trait
54+
...
55+
LL | impl<T> Trait for W<W<W<T>>> {}
56+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Assoc` in implementation
57+
58+
error[E0119]: conflicting implementations of trait `NoOverlap` for type `W<W<W<W<_>>>>`
59+
--> $DIR/best-obligation-ICE.rs:18:1
60+
|
61+
LL | impl<T: Trait> NoOverlap for T {}
62+
| ------------------------------ first implementation here
63+
LL | impl<T: Trait<Assoc = u32>> NoOverlap for W<T> {}
64+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<_>>>>`
65+
66+
error: aborting due to 5 previous errors
67+
68+
Some errors have detailed explanations: E0046, E0119, E0277.
69+
For more information about an error, try `rustc --explain E0046`.
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,11 @@
11
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
2-
--> $DIR/unsized_coercion.rs:15:17
2+
--> $DIR/unsized_coercion.rs:14:17
33
|
44
LL | let x = hello();
55
| ^^^^^^^ doesn't have a size known at compile-time
66
|
77
= help: the trait `Sized` is not implemented for `dyn Trait`
88

9-
error[E0308]: mismatched types
10-
--> $DIR/unsized_coercion.rs:19:5
11-
|
12-
LL | fn hello() -> Box<impl Trait> {
13-
| ---------------
14-
| | |
15-
| | the expected opaque type
16-
| expected `Box<impl Trait>` because of return type
17-
...
18-
LL | Box::new(1u32)
19-
| ^^^^^^^^^^^^^^ types differ
20-
|
21-
= note: expected struct `Box<impl Trait>`
22-
found struct `Box<u32>`
23-
24-
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
25-
--> $DIR/unsized_coercion.rs:12:1
26-
|
27-
LL | fn hello() -> Box<impl Trait> {
28-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
29-
|
30-
= help: the trait `Sized` is not implemented for `dyn Trait`
31-
32-
error: aborting due to 3 previous errors
9+
error: aborting due to 1 previous error
3310

34-
Some errors have detailed explanations: E0277, E0308.
35-
For more information about an error, try `rustc --explain E0277`.
11+
For more information about this error, try `rustc --explain E0277`.

tests/ui/impl-trait/unsized_coercion.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@ trait Trait {}
1010
impl Trait for u32 {}
1111

1212
fn hello() -> Box<impl Trait> {
13-
//[next]~^ ERROR the size for values of type `dyn Trait` cannot be known at compilation time
1413
if true {
1514
let x = hello();
1615
//[next]~^ ERROR: the size for values of type `dyn Trait` cannot be known at compilation time
1716
let y: Box<dyn Trait> = x;
1817
}
19-
Box::new(1u32) //[next]~ ERROR: mismatched types
18+
Box::new(1u32)
2019
}
2120

2221
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,11 @@
11
error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
2-
--> $DIR/unsized_coercion3.rs:14:17
2+
--> $DIR/unsized_coercion3.rs:13:17
33
|
44
LL | let x = hello();
55
| ^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
66
|
77
= help: the trait `Trait` is implemented for `u32`
88

9-
error[E0308]: mismatched types
10-
--> $DIR/unsized_coercion3.rs:19:5
11-
|
12-
LL | fn hello() -> Box<impl Trait + ?Sized> {
13-
| ------------------------
14-
| | |
15-
| | the expected opaque type
16-
| expected `Box<impl Trait + ?Sized>` because of return type
17-
...
18-
LL | Box::new(1u32)
19-
| ^^^^^^^^^^^^^^ types differ
20-
|
21-
= note: expected struct `Box<impl Trait + ?Sized>`
22-
found struct `Box<u32>`
23-
24-
error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
25-
--> $DIR/unsized_coercion3.rs:11:1
26-
|
27-
LL | fn hello() -> Box<impl Trait + ?Sized> {
28-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
29-
|
30-
= help: the trait `Trait` is implemented for `u32`
31-
32-
error: aborting due to 3 previous errors
9+
error: aborting due to 1 previous error
3310

34-
Some errors have detailed explanations: E0277, E0308.
35-
For more information about an error, try `rustc --explain E0277`.
11+
For more information about this error, try `rustc --explain E0277`.

tests/ui/impl-trait/unsized_coercion3.old.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
2-
--> $DIR/unsized_coercion3.rs:16:32
2+
--> $DIR/unsized_coercion3.rs:15:32
33
|
44
LL | let y: Box<dyn Send> = x;
55
| ^ doesn't have a size known at compile-time

tests/ui/impl-trait/unsized_coercion3.rs

-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@ trait Trait {}
99
impl Trait for u32 {}
1010

1111
fn hello() -> Box<impl Trait + ?Sized> {
12-
//[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
1312
if true {
1413
let x = hello();
1514
//[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
1615
let y: Box<dyn Send> = x;
1716
//[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
1817
}
1918
Box::new(1u32)
20-
//[next]~^ ERROR: mismatched types
2119
}
2220

2321
fn main() {}

tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs

-6
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,7 @@ fn main() {
1414

1515
fn weird0() -> impl Sized + !Sized {}
1616
//~^ ERROR the trait bound `(): !Sized` is not satisfied
17-
//~| ERROR the trait bound `(): !Sized` is not satisfied
18-
//~| ERROR the trait bound `(): !Sized` is not satisfied
1917
fn weird1() -> impl !Sized + Sized {}
2018
//~^ ERROR the trait bound `(): !Sized` is not satisfied
21-
//~| ERROR the trait bound `(): !Sized` is not satisfied
22-
//~| ERROR the trait bound `(): !Sized` is not satisfied
2319
fn weird2() -> impl !Sized {}
2420
//~^ ERROR the trait bound `(): !Sized` is not satisfied
25-
//~| ERROR the trait bound `(): !Sized` is not satisfied
26-
//~| ERROR the trait bound `(): !Sized` is not satisfied

tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr

+3-39
Original file line numberDiff line numberDiff line change
@@ -5,53 +5,17 @@ LL | fn weird0() -> impl Sized + !Sized {}
55
| ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
66

77
error[E0277]: the trait bound `(): !Sized` is not satisfied
8-
--> $DIR/opaque-type-unsatisfied-bound.rs:15:36
9-
|
10-
LL | fn weird0() -> impl Sized + !Sized {}
11-
| ^^ the trait bound `(): !Sized` is not satisfied
12-
13-
error[E0277]: the trait bound `(): !Sized` is not satisfied
14-
--> $DIR/opaque-type-unsatisfied-bound.rs:15:1
15-
|
16-
LL | fn weird0() -> impl Sized + !Sized {}
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
18-
19-
error[E0277]: the trait bound `(): !Sized` is not satisfied
20-
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
8+
--> $DIR/opaque-type-unsatisfied-bound.rs:17:16
219
|
2210
LL | fn weird1() -> impl !Sized + Sized {}
2311
| ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
2412

2513
error[E0277]: the trait bound `(): !Sized` is not satisfied
26-
--> $DIR/opaque-type-unsatisfied-bound.rs:19:36
27-
|
28-
LL | fn weird1() -> impl !Sized + Sized {}
29-
| ^^ the trait bound `(): !Sized` is not satisfied
30-
31-
error[E0277]: the trait bound `(): !Sized` is not satisfied
32-
--> $DIR/opaque-type-unsatisfied-bound.rs:19:1
33-
|
34-
LL | fn weird1() -> impl !Sized + Sized {}
35-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
36-
37-
error[E0277]: the trait bound `(): !Sized` is not satisfied
38-
--> $DIR/opaque-type-unsatisfied-bound.rs:23:16
14+
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
3915
|
4016
LL | fn weird2() -> impl !Sized {}
4117
| ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
4218

43-
error[E0277]: the trait bound `(): !Sized` is not satisfied
44-
--> $DIR/opaque-type-unsatisfied-bound.rs:23:28
45-
|
46-
LL | fn weird2() -> impl !Sized {}
47-
| ^^ the trait bound `(): !Sized` is not satisfied
48-
49-
error[E0277]: the trait bound `(): !Sized` is not satisfied
50-
--> $DIR/opaque-type-unsatisfied-bound.rs:23:1
51-
|
52-
LL | fn weird2() -> impl !Sized {}
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
54-
5519
error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
5620
--> $DIR/opaque-type-unsatisfied-bound.rs:12:13
5721
|
@@ -66,6 +30,6 @@ note: required by a bound in `consume`
6630
LL | fn consume(_: impl Trait) {}
6731
| ^^^^^ required by this bound in `consume`
6832

69-
error: aborting due to 10 previous errors
33+
error: aborting due to 4 previous errors
7034

7135
For more information about this error, try `rustc --explain E0277`.

tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs

-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,5 @@
44

55
fn produce() -> impl !Fn<(u32,)> {}
66
//~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied
7-
//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
8-
//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
97

108
fn main() {}

tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr

+1-13
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,6 @@ error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
44
LL | fn produce() -> impl !Fn<(u32,)> {}
55
| ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
66

7-
error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
8-
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34
9-
|
10-
LL | fn produce() -> impl !Fn<(u32,)> {}
11-
| ^^ the trait bound `(): !Fn(u32)` is not satisfied
12-
13-
error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
14-
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1
15-
|
16-
LL | fn produce() -> impl !Fn<(u32,)> {}
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
18-
19-
error: aborting due to 3 previous errors
7+
error: aborting due to 1 previous error
208

219
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)