Skip to content

Commit 68dfa07

Browse files
committed
Auto merge of rust-lang#89633 - rhysd:issue-65230, r=petrochenkov
Show detailed expected/found types in error message when trait paths are the same Fixes rust-lang#65230. ### Issue solved by this PR ```rust trait T { type U; fn f(&self) -> Self::U; } struct X<'a>(&'a mut i32); impl<'a> T for X<'a> { type U = &'a i32; fn f(&self) -> Self::U { self.0 } } fn main() {} ``` Compiler generates the following note: ``` note: ...so that the types are compatible --> test.rs:10:28 | 10 | fn f(&self) -> Self::U { | ____________________________^ 11 | | self.0 12 | | } | |_____^ = note: expected `T` found `T` ``` This note is not useful since the expected type and the found type are the same. ### How this PR solve the issue When the expected type and the found type are exactly the same in string representation, the note falls back to the detailed string representation of trait ref: ``` note: ...so that the types are compatible --> test.rs:10:28 | 10 | fn f(&self) -> Self::U { | ____________________________^ 11 | | self.0 12 | | } | |_____^ = note: expected `<X<'a> as T>` found `<X<'_> as T>` ``` So that a user can notice what was different between the expected one and the found one.
2 parents 0c87288 + 9211bee commit 68dfa07

9 files changed

+59
-20
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -2060,14 +2060,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
20602060
expected: exp_found.expected.print_only_trait_path(),
20612061
found: exp_found.found.print_only_trait_path(),
20622062
};
2063-
self.expected_found_str(pretty_exp_found)
2063+
match self.expected_found_str(pretty_exp_found) {
2064+
Some((expected, found)) if expected == found => {
2065+
self.expected_found_str(exp_found)
2066+
}
2067+
ret => ret,
2068+
}
20642069
}
20652070
infer::PolyTraitRefs(exp_found) => {
20662071
let pretty_exp_found = ty::error::ExpectedFound {
20672072
expected: exp_found.expected.print_only_trait_path(),
20682073
found: exp_found.found.print_only_trait_path(),
20692074
};
2070-
self.expected_found_str(pretty_exp_found)
2075+
match self.expected_found_str(pretty_exp_found) {
2076+
Some((expected, found)) if expected == found => {
2077+
self.expected_found_str(exp_found)
2078+
}
2079+
ret => ret,
2080+
}
20712081
}
20722082
}
20732083
}

src/test/ui/error-codes/E0308-2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
44
LL | impl Eq for &dyn DynEq {}
55
| ^^ lifetime mismatch
66
|
7-
= note: expected trait `PartialEq`
8-
found trait `PartialEq`
7+
= note: expected trait `<&dyn DynEq as PartialEq>`
8+
found trait `<&(dyn DynEq + 'static) as PartialEq>`
99
note: the lifetime `'_` as defined on the impl at 9:13...
1010
--> $DIR/E0308-2.rs:9:13
1111
|

src/test/ui/issues/issue-20831-debruijn.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ note: ...so that the types are compatible
1919
|
2020
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
2121
| ^^^^^^^^^
22-
= note: expected `Publisher<'_>`
23-
found `Publisher<'_>`
22+
= note: expected `<MyStruct<'a> as Publisher<'_>>`
23+
found `<MyStruct<'_> as Publisher<'_>>`
2424

2525
error: aborting due to previous error
2626

src/test/ui/issues/issue-65230.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
trait T0 {}
2+
trait T1: T0 {}
3+
4+
trait T2 {}
5+
6+
impl<'a> T0 for &'a (dyn T2 + 'static) {}
7+
8+
impl T1 for &dyn T2 {}
9+
//~^ ERROR mismatched types
10+
11+
fn main() {}

src/test/ui/issues/issue-65230.stderr

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-65230.rs:8:6
3+
|
4+
LL | impl T1 for &dyn T2 {}
5+
| ^^ lifetime mismatch
6+
|
7+
= note: expected trait `<&dyn T2 as T0>`
8+
found trait `<&(dyn T2 + 'static) as T0>`
9+
note: the lifetime `'_` as defined on the impl at 8:13...
10+
--> $DIR/issue-65230.rs:8:13
11+
|
12+
LL | impl T1 for &dyn T2 {}
13+
| ^
14+
= note: ...does not necessarily outlive the static lifetime
15+
16+
error: aborting due to previous error
17+
18+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/nll/issue-50716.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
44
LL | let _x = *s;
55
| ^^ lifetime mismatch
66
|
7-
= note: expected type `Sized`
8-
found type `Sized`
7+
= note: expected type `<<&'a T as A>::X as Sized>`
8+
found type `<<&'static T as A>::X as Sized>`
99
note: the lifetime `'a` as defined on the function body at 9:8...
1010
--> $DIR/issue-50716.rs:9:8
1111
|

src/test/ui/variance/variance-contravariant-self-trait-match.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
44
LL | impls_get::<&'min G>();
55
| ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
66
|
7-
= note: expected type `Get`
8-
found type `Get`
7+
= note: expected type `<&'min G as Get>`
8+
found type `<&'max G as Get>`
99
note: the lifetime `'min` as defined on the function body at 10:21...
1010
--> $DIR/variance-contravariant-self-trait-match.rs:10:21
1111
|
@@ -23,8 +23,8 @@ error[E0308]: mismatched types
2323
LL | impls_get::<&'max G>();
2424
| ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
2525
|
26-
= note: expected type `Get`
27-
found type `Get`
26+
= note: expected type `<&'max G as Get>`
27+
found type `<&'min G as Get>`
2828
note: the lifetime `'min` as defined on the function body at 16:21...
2929
--> $DIR/variance-contravariant-self-trait-match.rs:16:21
3030
|

src/test/ui/variance/variance-covariant-self-trait-match.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
44
LL | impls_get::<&'min G>();
55
| ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
66
|
7-
= note: expected type `Get`
8-
found type `Get`
7+
= note: expected type `<&'min G as Get>`
8+
found type `<&'max G as Get>`
99
note: the lifetime `'min` as defined on the function body at 10:21...
1010
--> $DIR/variance-covariant-self-trait-match.rs:10:21
1111
|
@@ -23,8 +23,8 @@ error[E0308]: mismatched types
2323
LL | impls_get::<&'max G>();
2424
| ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
2525
|
26-
= note: expected type `Get`
27-
found type `Get`
26+
= note: expected type `<&'max G as Get>`
27+
found type `<&'min G as Get>`
2828
note: the lifetime `'min` as defined on the function body at 17:21...
2929
--> $DIR/variance-covariant-self-trait-match.rs:17:21
3030
|

src/test/ui/variance/variance-invariant-self-trait-match.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
44
LL | impls_get::<&'min G>();
55
| ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
66
|
7-
= note: expected type `Get`
8-
found type `Get`
7+
= note: expected type `<&'min G as Get>`
8+
found type `<&'max G as Get>`
99
note: the lifetime `'min` as defined on the function body at 7:21...
1010
--> $DIR/variance-invariant-self-trait-match.rs:7:21
1111
|
@@ -23,8 +23,8 @@ error[E0308]: mismatched types
2323
LL | impls_get::<&'max G>();
2424
| ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
2525
|
26-
= note: expected type `Get`
27-
found type `Get`
26+
= note: expected type `<&'max G as Get>`
27+
found type `<&'min G as Get>`
2828
note: the lifetime `'min` as defined on the function body at 13:21...
2929
--> $DIR/variance-invariant-self-trait-match.rs:13:21
3030
|

0 commit comments

Comments
 (0)