Skip to content

Commit f746d99

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

21 files changed

+141
-44
lines changed

src/librustc/infer/error_reporting/mod.rs

+9-1
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

+18-3
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

+4-1
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

+4-1
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

+3-1
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

+4-2
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

+8-3
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

+2-2
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

+10-3
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

+1-1
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`

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ fn foo<T, U>(x: T, y: U) {
44
//~^ ERROR mismatched types
55
//~| expected type `T`
66
//~| found type `U`
7-
//~| expected type parameter, found a different type parameter
7+
//~| expected type parameter `T`, found type parameter `U`
88
}
99

1010
fn main() {

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
error[E0308]: mismatched types
22
--> $DIR/issue-2951.rs:3:10
33
|
4+
LL | fn foo<T, U>(x: T, y: U) {
5+
| - - found type parameter
6+
| |
7+
| expected type parameter
8+
LL | let mut xx = x;
49
LL | xx = y;
5-
| ^ expected type parameter, found a different type parameter
10+
| ^ expected type parameter `T`, found type parameter `U`
611
|
712
= note: expected type `T`
813
found type `U`

src/test/ui/mismatched_types/issue-35030.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
error[E0308]: mismatched types
22
--> $DIR/issue-35030.rs:9:14
33
|
4+
LL | impl<bool> Parser<bool> for bool {
5+
| ---- this type parameter
6+
LL | fn parse(text: &str) -> Option<bool> {
47
LL | Some(true)
5-
| ^^^^ expected type parameter, found bool
8+
| ^^^^ expected type parameter `bool`, found bool
69
|
7-
= note: expected type `bool` (type parameter)
10+
= note: expected type `bool` (type parameter `bool`)
811
found type `bool` (bool)
912
= help: type parameters must be constrained to match other types
1013
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

src/test/ui/structs/struct-path-self-type-mismatch.stderr

+12-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ LL | Self { inner: 1.5f32 };
77
error[E0308]: mismatched types
88
--> $DIR/struct-path-self-type-mismatch.rs:15:20
99
|
10+
LL | impl<T> Foo<T> {
11+
| - expected type parameter
12+
LL | fn new<U>(u: U) -> Foo<U> {
13+
| - found type parameter
14+
...
1015
LL | inner: u
11-
| ^ expected type parameter, found a different type parameter
16+
| ^ expected type parameter `T`, found type parameter `U`
1217
|
1318
= note: expected type `T`
1419
found type `U`
@@ -18,14 +23,18 @@ LL | inner: u
1823
error[E0308]: mismatched types
1924
--> $DIR/struct-path-self-type-mismatch.rs:13:9
2025
|
26+
LL | impl<T> Foo<T> {
27+
| - found type parameter
2128
LL | fn new<U>(u: U) -> Foo<U> {
22-
| ------ expected `Foo<U>` because of return type
29+
| - ------ expected `Foo<U>` because of return type
30+
| |
31+
| expected type parameter
2332
LL | / Self {
2433
LL | |
2534
LL | | inner: u
2635
LL | |
2736
LL | | }
28-
| |_________^ expected type parameter, found a different type parameter
37+
| |_________^ expected type parameter `U`, found type parameter `T`
2938
|
3039
= note: expected type `Foo<U>`
3140
found type `Foo<T>`

src/test/ui/structs/struct-path-self.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0071]: expected struct, variant or union type, found type parameter
1+
error[E0071]: expected struct, variant or union type, found type parameter `Self`
22
--> $DIR/struct-path-self.rs:5:17
33
|
44
LL | let s = Self {};
@@ -10,13 +10,13 @@ error[E0109]: type arguments are not allowed for this type
1010
LL | let z = Self::<u8> {};
1111
| ^^ type argument not allowed
1212

13-
error[E0071]: expected struct, variant or union type, found type parameter
13+
error[E0071]: expected struct, variant or union type, found type parameter `Self`
1414
--> $DIR/struct-path-self.rs:7:17
1515
|
1616
LL | let z = Self::<u8> {};
1717
| ^^^^^^^^^^ not a struct
1818

19-
error[E0071]: expected struct, variant or union type, found type parameter
19+
error[E0071]: expected struct, variant or union type, found type parameter `Self`
2020
--> $DIR/struct-path-self.rs:11:13
2121
|
2222
LL | Self { .. } => {}

src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr

+24-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
error[E0308]: mismatched types
22
--> $DIR/enum-variant-generic-args.rs:13:25
33
|
4+
LL | impl<T> Enum<T> {
5+
| - this type parameter
6+
LL | fn ts_variant() {
47
LL | Self::TSVariant(());
5-
| ^^ expected type parameter, found ()
8+
| ^^ expected type parameter `T`, found ()
69
|
710
= note: expected type `T`
811
found type `()`
@@ -24,8 +27,11 @@ LL | Self::<()>::TSVariant(());
2427
error[E0308]: mismatched types
2528
--> $DIR/enum-variant-generic-args.rs:17:31
2629
|
30+
LL | impl<T> Enum<T> {
31+
| - this type parameter
32+
...
2733
LL | Self::<()>::TSVariant(());
28-
| ^^ expected type parameter, found ()
34+
| ^^ expected type parameter `T`, found ()
2935
|
3036
= note: expected type `T`
3137
found type `()`
@@ -47,8 +53,11 @@ LL | Self::<()>::TSVariant::<()>(());
4753
error[E0308]: mismatched types
4854
--> $DIR/enum-variant-generic-args.rs:26:29
4955
|
56+
LL | impl<T> Enum<T> {
57+
| - this type parameter
58+
...
5059
LL | Self::SVariant { v: () };
51-
| ^^ expected type parameter, found ()
60+
| ^^ expected type parameter `T`, found ()
5261
|
5362
= note: expected type `T`
5463
found type `()`
@@ -64,8 +73,11 @@ LL | Self::SVariant::<()> { v: () };
6473
error[E0308]: mismatched types
6574
--> $DIR/enum-variant-generic-args.rs:28:35
6675
|
76+
LL | impl<T> Enum<T> {
77+
| - this type parameter
78+
...
6779
LL | Self::SVariant::<()> { v: () };
68-
| ^^ expected type parameter, found ()
80+
| ^^ expected type parameter `T`, found ()
6981
|
7082
= note: expected type `T`
7183
found type `()`
@@ -81,8 +93,11 @@ LL | Self::<()>::SVariant { v: () };
8193
error[E0308]: mismatched types
8294
--> $DIR/enum-variant-generic-args.rs:31:35
8395
|
96+
LL | impl<T> Enum<T> {
97+
| - this type parameter
98+
...
8499
LL | Self::<()>::SVariant { v: () };
85-
| ^^ expected type parameter, found ()
100+
| ^^ expected type parameter `T`, found ()
86101
|
87102
= note: expected type `T`
88103
found type `()`
@@ -104,8 +119,11 @@ LL | Self::<()>::SVariant::<()> { v: () };
104119
error[E0308]: mismatched types
105120
--> $DIR/enum-variant-generic-args.rs:34:41
106121
|
122+
LL | impl<T> Enum<T> {
123+
| - this type parameter
124+
...
107125
LL | Self::<()>::SVariant::<()> { v: () };
108-
| ^^ expected type parameter, found ()
126+
| ^^ expected type parameter `T`, found ()
109127
|
110128
= note: expected type `T`
111129
found type `()`

src/test/ui/type/type-parameter-names.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ fn foo<Foo, Bar>(x: Foo) -> Bar {
66
//~^ ERROR mismatched types
77
//~| expected type `Bar`
88
//~| found type `Foo`
9-
//~| expected type parameter, found a different type parameter
9+
//~| expected type parameter `Bar`, found type parameter `Foo`
1010
}
1111

1212
fn main() {}

src/test/ui/type/type-parameter-names.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ error[E0308]: mismatched types
22
--> $DIR/type-parameter-names.rs:5:5
33
|
44
LL | fn foo<Foo, Bar>(x: Foo) -> Bar {
5-
| --- expected `Bar` because of return type
5+
| --- --- --- expected `Bar` because of return type
6+
| | |
7+
| | expected type parameter
8+
| found type parameter
69
LL | x
7-
| ^ expected type parameter, found a different type parameter
10+
| ^ expected type parameter `Bar`, found type parameter `Foo`
811
|
912
= note: expected type `Bar`
1013
found type `Foo`

0 commit comments

Comments
 (0)