Skip to content

Commit

Permalink
Rollup merge of #66014 - dkadashev:47319-type-param-def-location, r=e…
Browse files Browse the repository at this point in the history
…stebank

Show type parameter name and definition in type mismatch error messages

Fixes #47319

r? estebank
  • Loading branch information
Centril authored Nov 6, 2019
2 parents 5910116 + 774e60b commit f746d99
Show file tree
Hide file tree
Showing 21 changed files with 141 additions and 44 deletions.
10 changes: 9 additions & 1 deletion src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1234,8 +1234,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}

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

// It reads better to have the error origin as the final
// thing.
Expand Down
21 changes: 18 additions & 3 deletions src/librustc/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ impl<'tcx> ty::TyS<'tcx> {
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
ty::Projection(_) => "associated type".into(),
ty::UnnormalizedProjection(_) => "non-normalized associated type".into(),
ty::Param(_) => "type parameter".into(),
ty::Param(p) => format!("type parameter `{}`", p).into(),
ty::Opaque(..) => "opaque type".into(),
ty::Error => "type error".into(),
}
Expand All @@ -254,6 +254,7 @@ impl<'tcx> TyCtxt<'tcx> {
db: &mut DiagnosticBuilder<'_>,
err: &TypeError<'tcx>,
sp: Span,
body_owner_def_id: DefId,
) {
use self::TypeError::*;

Expand Down Expand Up @@ -288,7 +289,16 @@ impl<'tcx> TyCtxt<'tcx> {
);
}
},
(ty::Param(_), ty::Param(_)) => {
(ty::Param(expected), ty::Param(found)) => {
let generics = self.generics_of(body_owner_def_id);
let e_span = self.def_span(generics.type_param(expected, self).def_id);
if !sp.contains(e_span) {
db.span_label(e_span, "expected type parameter");
}
let f_span = self.def_span(generics.type_param(found, self).def_id);
if !sp.contains(f_span) {
db.span_label(f_span, "found type parameter");
}
db.note("a type parameter was expected, but a different one was found; \
you might be missing a type parameter or trait bound");
db.note("for more information, visit \
Expand All @@ -301,7 +311,12 @@ impl<'tcx> TyCtxt<'tcx> {
(ty::Param(_), ty::Projection(_)) | (ty::Projection(_), ty::Param(_)) => {
db.note("you might be missing a type parameter or trait bound");
}
(ty::Param(_), _) | (_, ty::Param(_)) => {
(ty::Param(p), _) | (_, ty::Param(p)) => {
let generics = self.generics_of(body_owner_def_id);
let p_span = self.def_span(generics.type_param(p, self).def_id);
if !sp.contains(p_span) {
db.span_label(p_span, "this type parameter");
}
db.help("type parameters must be constrained to match other types");
if self.sess.teach(&db.get_code().unwrap()) {
db.help("given a type parameter `T` and a method `foo`:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == std::op
LL | fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
| -------------- ------ required by this bound in `is_iterator_of`
...
LL | fn test_adapter<T, I: Iterator<Item=Option<T>>>(it: I) {
| - this type parameter
...
LL | is_iterator_of::<Option<T>, _>(&adapter);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::option::Option`, found type parameter
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::option::Option`, found type parameter `T`
|
= note: expected type `std::option::Option<T>`
found type `T`
Expand Down
5 changes: 4 additions & 1 deletion src/test/ui/compare-method/reordered-type-param.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ LL | fn b<C:Clone,D>(&self, x: C) -> C;
| - type in trait
...
LL | fn b<F:Clone,G>(&self, _x: G) -> G { panic!() }
| ^ expected type parameter, found a different type parameter
| - - ^ expected type parameter `F`, found type parameter `G`
| | |
| | found type parameter
| expected type parameter
|
= note: expected type `fn(&E, F) -> F`
found type `fn(&E, G) -> G`
Expand Down
4 changes: 3 additions & 1 deletion src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ LL | fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
| -- type in trait
...
LL | fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
| ^^^^^^^^^^^ expected type parameter, found a different type parameter
| - ^^^^^^^^^^^ expected type parameter `B`, found type parameter `impl Debug`
| |
| expected type parameter
|
= note: expected type `fn(&(), &B, &impl Debug)`
found type `fn(&(), &impl Debug, &B)`
Expand Down
6 changes: 4 additions & 2 deletions src/test/ui/impl-trait/universal-mismatched-type.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ error[E0308]: mismatched types
--> $DIR/universal-mismatched-type.rs:4:5
|
LL | fn foo(x: impl Debug) -> String {
| ------ expected `std::string::String` because of return type
| ---------- ------ expected `std::string::String` because of return type
| |
| this type parameter
LL | x
| ^ expected struct `std::string::String`, found type parameter
| ^ expected struct `std::string::String`, found type parameter `impl Debug`
|
= note: expected type `std::string::String`
found type `impl Debug`
Expand Down
11 changes: 8 additions & 3 deletions src/test/ui/impl-trait/universal-two-impl-traits.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
error[E0308]: mismatched types
--> $DIR/universal-two-impl-traits.rs:5:9
|
LL | fn foo(x: impl Debug, y: impl Debug) -> String {
| ---------- ---------- found type parameter
| |
| expected type parameter
LL | let mut a = x;
LL | a = y;
| ^ expected type parameter, found a different type parameter
| ^ expected type parameter `impl Debug`, found a different type parameter `impl Debug`
|
= note: expected type `impl Debug` (type parameter)
found type `impl Debug` (type parameter)
= note: expected type `impl Debug` (type parameter `impl Debug`)
found type `impl Debug` (type parameter `impl Debug`)
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/issues/issue-13853.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ error[E0308]: mismatched types
--> $DIR/issue-13853.rs:14:9
|
LL | fn nodes<'a, I: Iterator<Item=&'a N>>(&self) -> I
| - expected `I` because of return type
| - this type parameter - expected `I` because of return type
...
LL | self.iter()
| ^^^^^^^^^^^ expected type parameter, found struct `std::slice::Iter`
| ^^^^^^^^^^^ expected type parameter `I`, found struct `std::slice::Iter`
|
= note: expected type `I`
found type `std::slice::Iter<'_, N>`
Expand Down
13 changes: 10 additions & 3 deletions src/test/ui/issues/issue-20225.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error[E0053]: method `call` has an incompatible type for trait
--> $DIR/issue-20225.rs:6:3
|
LL | impl<'a, T> Fn<(&'a T,)> for Foo {
| - this type parameter
LL | extern "rust-call" fn call(&self, (_,): (T,)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter `T`
|
= note: expected type `extern "rust-call" fn(&Foo, (&'a T,))`
found type `extern "rust-call" fn(&Foo, (T,))`
Expand All @@ -12,8 +14,10 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {}
error[E0053]: method `call_mut` has an incompatible type for trait
--> $DIR/issue-20225.rs:12:3
|
LL | impl<'a, T> FnMut<(&'a T,)> for Foo {
| - this type parameter
LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter `T`
|
= note: expected type `extern "rust-call" fn(&mut Foo, (&'a T,))`
found type `extern "rust-call" fn(&mut Foo, (T,))`
Expand All @@ -23,8 +27,11 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
error[E0053]: method `call_once` has an incompatible type for trait
--> $DIR/issue-20225.rs:20:3
|
LL | impl<'a, T> FnOnce<(&'a T,)> for Foo {
| - this type parameter
...
LL | extern "rust-call" fn call_once(self, (_,): (T,)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter `T`
|
= note: expected type `extern "rust-call" fn(Foo, (&'a T,))`
found type `extern "rust-call" fn(Foo, (T,))`
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-24204.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | trait Trait: Sized {
| ------------------ required by `Trait`
...
LL | fn test<T: Trait<B=i32>>(b: i32) -> T where T::A: MultiDispatch<i32> { T::new(b) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found associated type
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type
|
= note: expected type `T`
found type `<<T as Trait>::A as MultiDispatch<i32>>::O`
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-2951.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ fn foo<T, U>(x: T, y: U) {
//~^ ERROR mismatched types
//~| expected type `T`
//~| found type `U`
//~| expected type parameter, found a different type parameter
//~| expected type parameter `T`, found type parameter `U`
}

fn main() {
Expand Down
7 changes: 6 additions & 1 deletion src/test/ui/issues/issue-2951.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
error[E0308]: mismatched types
--> $DIR/issue-2951.rs:3:10
|
LL | fn foo<T, U>(x: T, y: U) {
| - - found type parameter
| |
| expected type parameter
LL | let mut xx = x;
LL | xx = y;
| ^ expected type parameter, found a different type parameter
| ^ expected type parameter `T`, found type parameter `U`
|
= note: expected type `T`
found type `U`
Expand Down
7 changes: 5 additions & 2 deletions src/test/ui/mismatched_types/issue-35030.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
error[E0308]: mismatched types
--> $DIR/issue-35030.rs:9:14
|
LL | impl<bool> Parser<bool> for bool {
| ---- this type parameter
LL | fn parse(text: &str) -> Option<bool> {
LL | Some(true)
| ^^^^ expected type parameter, found bool
| ^^^^ expected type parameter `bool`, found bool
|
= note: expected type `bool` (type parameter)
= note: expected type `bool` (type parameter `bool`)
found type `bool` (bool)
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
Expand Down
15 changes: 12 additions & 3 deletions src/test/ui/structs/struct-path-self-type-mismatch.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ LL | Self { inner: 1.5f32 };
error[E0308]: mismatched types
--> $DIR/struct-path-self-type-mismatch.rs:15:20
|
LL | impl<T> Foo<T> {
| - expected type parameter
LL | fn new<U>(u: U) -> Foo<U> {
| - found type parameter
...
LL | inner: u
| ^ expected type parameter, found a different type parameter
| ^ expected type parameter `T`, found type parameter `U`
|
= note: expected type `T`
found type `U`
Expand All @@ -18,14 +23,18 @@ LL | inner: u
error[E0308]: mismatched types
--> $DIR/struct-path-self-type-mismatch.rs:13:9
|
LL | impl<T> Foo<T> {
| - found type parameter
LL | fn new<U>(u: U) -> Foo<U> {
| ------ expected `Foo<U>` because of return type
| - ------ expected `Foo<U>` because of return type
| |
| expected type parameter
LL | / Self {
LL | |
LL | | inner: u
LL | |
LL | | }
| |_________^ expected type parameter, found a different type parameter
| |_________^ expected type parameter `U`, found type parameter `T`
|
= note: expected type `Foo<U>`
found type `Foo<T>`
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/structs/struct-path-self.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0071]: expected struct, variant or union type, found type parameter
error[E0071]: expected struct, variant or union type, found type parameter `Self`
--> $DIR/struct-path-self.rs:5:17
|
LL | let s = Self {};
Expand All @@ -10,13 +10,13 @@ error[E0109]: type arguments are not allowed for this type
LL | let z = Self::<u8> {};
| ^^ type argument not allowed

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

error[E0071]: expected struct, variant or union type, found type parameter
error[E0071]: expected struct, variant or union type, found type parameter `Self`
--> $DIR/struct-path-self.rs:11:13
|
LL | Self { .. } => {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
error[E0308]: mismatched types
--> $DIR/enum-variant-generic-args.rs:13:25
|
LL | impl<T> Enum<T> {
| - this type parameter
LL | fn ts_variant() {
LL | Self::TSVariant(());
| ^^ expected type parameter, found ()
| ^^ expected type parameter `T`, found ()
|
= note: expected type `T`
found type `()`
Expand All @@ -24,8 +27,11 @@ LL | Self::<()>::TSVariant(());
error[E0308]: mismatched types
--> $DIR/enum-variant-generic-args.rs:17:31
|
LL | impl<T> Enum<T> {
| - this type parameter
...
LL | Self::<()>::TSVariant(());
| ^^ expected type parameter, found ()
| ^^ expected type parameter `T`, found ()
|
= note: expected type `T`
found type `()`
Expand All @@ -47,8 +53,11 @@ LL | Self::<()>::TSVariant::<()>(());
error[E0308]: mismatched types
--> $DIR/enum-variant-generic-args.rs:26:29
|
LL | impl<T> Enum<T> {
| - this type parameter
...
LL | Self::SVariant { v: () };
| ^^ expected type parameter, found ()
| ^^ expected type parameter `T`, found ()
|
= note: expected type `T`
found type `()`
Expand All @@ -64,8 +73,11 @@ LL | Self::SVariant::<()> { v: () };
error[E0308]: mismatched types
--> $DIR/enum-variant-generic-args.rs:28:35
|
LL | impl<T> Enum<T> {
| - this type parameter
...
LL | Self::SVariant::<()> { v: () };
| ^^ expected type parameter, found ()
| ^^ expected type parameter `T`, found ()
|
= note: expected type `T`
found type `()`
Expand All @@ -81,8 +93,11 @@ LL | Self::<()>::SVariant { v: () };
error[E0308]: mismatched types
--> $DIR/enum-variant-generic-args.rs:31:35
|
LL | impl<T> Enum<T> {
| - this type parameter
...
LL | Self::<()>::SVariant { v: () };
| ^^ expected type parameter, found ()
| ^^ expected type parameter `T`, found ()
|
= note: expected type `T`
found type `()`
Expand All @@ -104,8 +119,11 @@ LL | Self::<()>::SVariant::<()> { v: () };
error[E0308]: mismatched types
--> $DIR/enum-variant-generic-args.rs:34:41
|
LL | impl<T> Enum<T> {
| - this type parameter
...
LL | Self::<()>::SVariant::<()> { v: () };
| ^^ expected type parameter, found ()
| ^^ expected type parameter `T`, found ()
|
= note: expected type `T`
found type `()`
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/type/type-parameter-names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ fn foo<Foo, Bar>(x: Foo) -> Bar {
//~^ ERROR mismatched types
//~| expected type `Bar`
//~| found type `Foo`
//~| expected type parameter, found a different type parameter
//~| expected type parameter `Bar`, found type parameter `Foo`
}

fn main() {}
7 changes: 5 additions & 2 deletions src/test/ui/type/type-parameter-names.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ error[E0308]: mismatched types
--> $DIR/type-parameter-names.rs:5:5
|
LL | fn foo<Foo, Bar>(x: Foo) -> Bar {
| --- expected `Bar` because of return type
| --- --- --- expected `Bar` because of return type
| | |
| | expected type parameter
| found type parameter
LL | x
| ^ expected type parameter, found a different type parameter
| ^ expected type parameter `Bar`, found type parameter `Foo`
|
= note: expected type `Bar`
found type `Foo`
Expand Down
Loading

0 comments on commit f746d99

Please sign in to comment.