Skip to content

Commit f746d99

Browse files
authored
Rollup merge of #66014 - dkadashev:47319-type-param-def-location, r=estebank
Show type parameter name and definition in type mismatch error messages Fixes #47319 r? estebank
2 parents 5910116 + 774e60b commit f746d99

21 files changed

+141
-44
lines changed

src/librustc/infer/error_reporting/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1234,8 +1234,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
12341234
}
12351235
}
12361236

1237+
// In some (most?) cases cause.body_id points to actual body, but in some cases
1238+
// it's a actual definition. According to the comments (e.g. in
1239+
// librustc_typeck/check/compare_method.rs:compare_predicate_entailment) the latter
1240+
// is relied upon by some other code. This might (or might not) need cleanup.
1241+
let body_owner_def_id = self.tcx.hir().opt_local_def_id(cause.body_id)
1242+
.unwrap_or_else(|| {
1243+
self.tcx.hir().body_owner_def_id(hir::BodyId { hir_id: cause.body_id })
1244+
});
12371245
self.check_and_note_conflicting_crates(diag, terr, span);
1238-
self.tcx.note_and_explain_type_err(diag, terr, span);
1246+
self.tcx.note_and_explain_type_err(diag, terr, span, body_owner_def_id);
12391247

12401248
// It reads better to have the error origin as the final
12411249
// thing.

src/librustc/ty/error.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ impl<'tcx> ty::TyS<'tcx> {
241241
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
242242
ty::Projection(_) => "associated type".into(),
243243
ty::UnnormalizedProjection(_) => "non-normalized associated type".into(),
244-
ty::Param(_) => "type parameter".into(),
244+
ty::Param(p) => format!("type parameter `{}`", p).into(),
245245
ty::Opaque(..) => "opaque type".into(),
246246
ty::Error => "type error".into(),
247247
}
@@ -254,6 +254,7 @@ impl<'tcx> TyCtxt<'tcx> {
254254
db: &mut DiagnosticBuilder<'_>,
255255
err: &TypeError<'tcx>,
256256
sp: Span,
257+
body_owner_def_id: DefId,
257258
) {
258259
use self::TypeError::*;
259260

@@ -288,7 +289,16 @@ impl<'tcx> TyCtxt<'tcx> {
288289
);
289290
}
290291
},
291-
(ty::Param(_), ty::Param(_)) => {
292+
(ty::Param(expected), ty::Param(found)) => {
293+
let generics = self.generics_of(body_owner_def_id);
294+
let e_span = self.def_span(generics.type_param(expected, self).def_id);
295+
if !sp.contains(e_span) {
296+
db.span_label(e_span, "expected type parameter");
297+
}
298+
let f_span = self.def_span(generics.type_param(found, self).def_id);
299+
if !sp.contains(f_span) {
300+
db.span_label(f_span, "found type parameter");
301+
}
292302
db.note("a type parameter was expected, but a different one was found; \
293303
you might be missing a type parameter or trait bound");
294304
db.note("for more information, visit \
@@ -301,7 +311,12 @@ impl<'tcx> TyCtxt<'tcx> {
301311
(ty::Param(_), ty::Projection(_)) | (ty::Projection(_), ty::Param(_)) => {
302312
db.note("you might be missing a type parameter or trait bound");
303313
}
304-
(ty::Param(_), _) | (_, ty::Param(_)) => {
314+
(ty::Param(p), _) | (_, ty::Param(p)) => {
315+
let generics = self.generics_of(body_owner_def_id);
316+
let p_span = self.def_span(generics.type_param(p, self).def_id);
317+
if !sp.contains(p_span) {
318+
db.span_label(p_span, "this type parameter");
319+
}
305320
db.help("type parameters must be constrained to match other types");
306321
if self.sess.teach(&db.get_code().unwrap()) {
307322
db.help("given a type parameter `T` and a method `foo`:

src/test/ui/associated-types/associated-types-issue-20346.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == std::op
44
LL | fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
55
| -------------- ------ required by this bound in `is_iterator_of`
66
...
7+
LL | fn test_adapter<T, I: Iterator<Item=Option<T>>>(it: I) {
8+
| - this type parameter
9+
...
710
LL | is_iterator_of::<Option<T>, _>(&adapter);
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::option::Option`, found type parameter
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::option::Option`, found type parameter `T`
912
|
1013
= note: expected type `std::option::Option<T>`
1114
found type `T`

src/test/ui/compare-method/reordered-type-param.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ LL | fn b<C:Clone,D>(&self, x: C) -> C;
55
| - type in trait
66
...
77
LL | fn b<F:Clone,G>(&self, _x: G) -> G { panic!() }
8-
| ^ expected type parameter, found a different type parameter
8+
| - - ^ expected type parameter `F`, found type parameter `G`
9+
| | |
10+
| | found type parameter
11+
| expected type parameter
912
|
1013
= note: expected type `fn(&E, F) -> F`
1114
found type `fn(&E, G) -> G`

src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ LL | fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
55
| -- type in trait
66
...
77
LL | fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
8-
| ^^^^^^^^^^^ expected type parameter, found a different type parameter
8+
| - ^^^^^^^^^^^ expected type parameter `B`, found type parameter `impl Debug`
9+
| |
10+
| expected type parameter
911
|
1012
= note: expected type `fn(&(), &B, &impl Debug)`
1113
found type `fn(&(), &impl Debug, &B)`

src/test/ui/impl-trait/universal-mismatched-type.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ error[E0308]: mismatched types
22
--> $DIR/universal-mismatched-type.rs:4:5
33
|
44
LL | fn foo(x: impl Debug) -> String {
5-
| ------ expected `std::string::String` because of return type
5+
| ---------- ------ expected `std::string::String` because of return type
6+
| |
7+
| this type parameter
68
LL | x
7-
| ^ expected struct `std::string::String`, found type parameter
9+
| ^ expected struct `std::string::String`, found type parameter `impl Debug`
810
|
911
= note: expected type `std::string::String`
1012
found type `impl Debug`

src/test/ui/impl-trait/universal-two-impl-traits.stderr

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
error[E0308]: mismatched types
22
--> $DIR/universal-two-impl-traits.rs:5:9
33
|
4+
LL | fn foo(x: impl Debug, y: impl Debug) -> String {
5+
| ---------- ---------- found type parameter
6+
| |
7+
| expected type parameter
8+
LL | let mut a = x;
49
LL | a = y;
5-
| ^ expected type parameter, found a different type parameter
10+
| ^ expected type parameter `impl Debug`, found a different type parameter `impl Debug`
611
|
7-
= note: expected type `impl Debug` (type parameter)
8-
found type `impl Debug` (type parameter)
12+
= note: expected type `impl Debug` (type parameter `impl Debug`)
13+
found type `impl Debug` (type parameter `impl Debug`)
914
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
1015
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
1116

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ error[E0308]: mismatched types
22
--> $DIR/issue-13853.rs:14:9
33
|
44
LL | fn nodes<'a, I: Iterator<Item=&'a N>>(&self) -> I
5-
| - expected `I` because of return type
5+
| - this type parameter - expected `I` because of return type
66
...
77
LL | self.iter()
8-
| ^^^^^^^^^^^ expected type parameter, found struct `std::slice::Iter`
8+
| ^^^^^^^^^^^ expected type parameter `I`, found struct `std::slice::Iter`
99
|
1010
= note: expected type `I`
1111
found type `std::slice::Iter<'_, N>`

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
error[E0053]: method `call` has an incompatible type for trait
22
--> $DIR/issue-20225.rs:6:3
33
|
4+
LL | impl<'a, T> Fn<(&'a T,)> for Foo {
5+
| - this type parameter
46
LL | extern "rust-call" fn call(&self, (_,): (T,)) {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter `T`
68
|
79
= note: expected type `extern "rust-call" fn(&Foo, (&'a T,))`
810
found type `extern "rust-call" fn(&Foo, (T,))`
@@ -12,8 +14,10 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {}
1214
error[E0053]: method `call_mut` has an incompatible type for trait
1315
--> $DIR/issue-20225.rs:12:3
1416
|
17+
LL | impl<'a, T> FnMut<(&'a T,)> for Foo {
18+
| - this type parameter
1519
LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
16-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter `T`
1721
|
1822
= note: expected type `extern "rust-call" fn(&mut Foo, (&'a T,))`
1923
found type `extern "rust-call" fn(&mut Foo, (T,))`
@@ -23,8 +27,11 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
2327
error[E0053]: method `call_once` has an incompatible type for trait
2428
--> $DIR/issue-20225.rs:20:3
2529
|
30+
LL | impl<'a, T> FnOnce<(&'a T,)> for Foo {
31+
| - this type parameter
32+
...
2633
LL | extern "rust-call" fn call_once(self, (_,): (T,)) {}
27-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter
34+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter `T`
2835
|
2936
= note: expected type `extern "rust-call" fn(Foo, (&'a T,))`
3037
found type `extern "rust-call" fn(Foo, (T,))`

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | trait Trait: Sized {
55
| ------------------ required by `Trait`
66
...
77
LL | fn test<T: Trait<B=i32>>(b: i32) -> T where T::A: MultiDispatch<i32> { T::new(b) }
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found associated type
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type
99
|
1010
= note: expected type `T`
1111
found type `<<T as Trait>::A as MultiDispatch<i32>>::O`

0 commit comments

Comments
 (0)