Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explanation to type mismatch involving type params and assoc types #63907

Merged
merged 1 commit into from
Sep 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,11 +655,11 @@ pub struct VtableTraitAliasData<'tcx, N> {
}

/// Creates predicate obligations from the generic bounds.
pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
generic_bounds: &ty::InstantiatedPredicates<'tcx>)
-> PredicateObligations<'tcx>
{
pub fn predicates_for_generics<'tcx>(
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
generic_bounds: &ty::InstantiatedPredicates<'tcx>,
) -> PredicateObligations<'tcx> {
util::predicates_for_generics(cause, 0, param_env, generic_bounds)
}

Expand Down
27 changes: 13 additions & 14 deletions src/librustc/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,20 +513,19 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>(
}

/// See [`super::obligations_for_generics`].
pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
recursion_depth: usize,
param_env: ty::ParamEnv<'tcx>,
generic_bounds: &ty::InstantiatedPredicates<'tcx>)
-> Vec<PredicateObligation<'tcx>>
{
debug!("predicates_for_generics(generic_bounds={:?})",
generic_bounds);

generic_bounds.predicates.iter().map(|predicate| {
Obligation { cause: cause.clone(),
recursion_depth,
param_env,
predicate: predicate.clone() }
pub fn predicates_for_generics<'tcx>(
cause: ObligationCause<'tcx>,
recursion_depth: usize,
param_env: ty::ParamEnv<'tcx>,
generic_bounds: &ty::InstantiatedPredicates<'tcx>,
) -> Vec<PredicateObligation<'tcx>> {
debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds);

generic_bounds.predicates.iter().map(|predicate| Obligation {
cause: cause.clone(),
recursion_depth,
param_env,
predicate: predicate.clone(),
}).collect()
}

Expand Down
96 changes: 92 additions & 4 deletions src/librustc/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,10 @@ impl<'tcx> TyCtxt<'tcx> {
`.await`ing on both of them");
}
}
if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) =
(&values.found.sty, &values.expected.sty) // Issue #53280
{
if let Ok(snippet) = self.sess.source_map().span_to_snippet(sp) {
match (&values.expected.sty, &values.found.sty) {
(ty::Float(_), ty::Infer(ty::IntVar(_))) => if let Ok( // Issue #53280
snippet,
) = self.sess.source_map().span_to_snippet(sp) {
if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
db.span_suggestion(
sp,
Expand All @@ -287,8 +287,96 @@ impl<'tcx> TyCtxt<'tcx> {
Applicability::MachineApplicable
);
}
},
(ty::Param(_), ty::Param(_)) => {
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 \
https://doc.rust-lang.org/book/ch10-02-traits.html\
#traits-as-parameters");
}
(ty::Projection(_), ty::Projection(_)) => {
db.note("an associated type was expected, but a different one was found");
}
(ty::Param(_), ty::Projection(_)) | (ty::Projection(_), ty::Param(_)) => {
db.note("you might be missing a type parameter or trait bound");
}
(ty::Param(_), _) | (_, ty::Param(_)) => {
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`:
```
trait Trait<T> { fn foo(&self) -> T; }
```
the only ways to implement method `foo` are:
- constrain `T` with an explicit type:
```
impl Trait<String> for X {
fn foo(&self) -> String { String::new() }
}
```
- add a trait bound to `T` and call a method on that trait that returns `Self`:
```
impl<T: std::default::Default> Trait<T> for X {
fn foo(&self) -> T { <T as std::default::Default>::default() }
}
```
- change `foo` to return an argument of type `T`:
```
impl<T> Trait<T> for X {
fn foo(&self, x: T) -> T { x }
}
```");
}
db.note("for more information, visit \
https://doc.rust-lang.org/book/ch10-02-traits.html\
#traits-as-parameters");
}
(ty::Projection(_), _) => {
db.note(&format!(
"consider constraining the associated type `{}` to `{}` or calling a \
method that returns `{}`",
values.expected,
values.found,
values.expected,
));
if self.sess.teach(&db.get_code().unwrap()) {
db.help("given an associated type `T` and a method `foo`:
```
trait Trait {
type T;
fn foo(&self) -> Self::T;
}
```
the only way of implementing method `foo` is to constrain `T` with an explicit associated type:
```
impl Trait for X {
type T = String;
fn foo(&self) -> Self::T { String::new() }
}
```");
}
db.note("for more information, visit \
https://doc.rust-lang.org/book/ch19-03-advanced-traits.html");
}
(_, ty::Projection(_)) => {
db.note(&format!(
"consider constraining the associated type `{}` to `{}`",
values.found,
values.expected,
));
db.note("for more information, visit \
https://doc.rust-lang.org/book/ch19-03-advanced-traits.html");
}
_ => {}
}
debug!(
"note_and_explain_type_err expected={:?} ({:?}) found={:?} ({:?})",
values.expected,
values.expected.sty,
values.found,
values.found.sty,
);
},
CyclicTy(ty) => {
// Watch out for various cases of cyclic types and try to explain.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ LL | const FROM: &'static str = "foo";
|
= note: expected type `<T as Foo>::Out`
found type `&'static str`
= note: consider constraining the associated type `<T as Foo>::Out` to `&'static str` or calling a method that returns `<T as Foo>::Out`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error: aborting due to previous error

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/associated-types/associated-types-eq-3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ LL | let _: Bar = x.boo();
|
= note: expected type `Bar`
found type `<I as Foo>::A`
= note: consider constraining the associated type `<I as Foo>::A` to `Bar`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
--> $DIR/associated-types-eq-3.rs:38:5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ LL | is_iterator_of::<Option<T>, _>(&adapter);
|
= note: expected type `T`
found type `std::option::Option<T>`
= 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

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ LL | fn want_y<T:Foo<Y=i32>>(t: &T) { }
|
= note: expected type `<T as Foo>::Y`
found type `i32`
= note: consider constraining the associated type `<T as Foo>::Y` to `i32` or calling a method that returns `<T as Foo>::Y`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
--> $DIR/associated-types-multiple-types-one-trait.rs:18:5
Expand All @@ -21,6 +23,8 @@ LL | fn want_x<T:Foo<X=u32>>(t: &T) { }
|
= note: expected type `<T as Foo>::X`
found type `u32`
= note: consider constraining the associated type `<T as Foo>::X` to `u32` or calling a method that returns `<T as Foo>::X`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error: aborting due to 2 previous errors

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/compare-method/reordered-type-param.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ LL | fn b<F:Clone,G>(&self, _x: G) -> G { panic!() }
|
= note: expected type `fn(&E, F) -> F`
found type `fn(&E, G) -> G`
= 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

error: aborting due to previous error

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ LL | let v = Unit2.m(
|
= note: expected type `Unit4`
found type `<_ as Ty<'_>>::V`
= note: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error[E0271]: type mismatch resolving `<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39] as std::ops::FnOnce<((&u8,),)>>::Output == Unit3`
--> $DIR/issue-62203-hrtb-ice.rs:38:19
Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/impl-trait/bound-normalization-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ LL | fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
|
= note: expected type `()`
found type `<T as impl_trait::Trait>::Assoc`
= note: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
= note: the return type of a function must have a statically known size

error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
Expand All @@ -30,6 +32,8 @@ LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
|
= note: expected type `()`
found type `<T as lifetimes::Trait<'static>>::Assoc`
= note: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
= note: the return type of a function must have a statically known size

error: aborting due to 3 previous errors
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/impl-trait/equality2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ LL | let _: i32 = Leak::leak(hide(0_i32));
|
= note: expected type `i32`
found type `<impl Foo as Leak>::T`
= note: consider constraining the associated type `<impl Foo as Leak>::T` to `i32`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error[E0308]: mismatched types
--> $DIR/equality2.rs:38:10
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ LL | fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
|
= note: expected type `fn(&(), &B, &impl Debug)`
found type `fn(&(), &impl Debug, &B)`
= 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

error: aborting due to previous error

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/impl-trait/universal-mismatched-type.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ LL | x
|
= note: expected type `std::string::String`
found type `impl Debug`
= 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

error: aborting due to previous error

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/impl-trait/universal-two-impl-traits.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ LL | a = y;
|
= note: expected type `impl Debug` (type parameter)
found type `impl Debug` (type parameter)
= 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

error: aborting due to previous error

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-13853.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ LL | self.iter()
|
= note: expected type `I`
found type `std::slice::Iter<'_, N>`
= 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

error[E0599]: no method named `iter` found for type `&G` in the current scope
--> $DIR/issue-13853.rs:27:23
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/issues/issue-20225.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {}
|
= note: expected type `extern "rust-call" fn(&Foo, (&'a T,))`
found type `extern "rust-call" fn(&Foo, (T,))`
= 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

error[E0053]: method `call_mut` has an incompatible type for trait
--> $DIR/issue-20225.rs:12:3
Expand All @@ -15,6 +17,8 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
|
= note: expected type `extern "rust-call" fn(&mut Foo, (&'a T,))`
found type `extern "rust-call" fn(&mut Foo, (T,))`
= 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

error[E0053]: method `call_once` has an incompatible type for trait
--> $DIR/issue-20225.rs:20:3
Expand All @@ -24,6 +28,8 @@ LL | extern "rust-call" fn call_once(self, (_,): (T,)) {}
|
= note: expected type `extern "rust-call" fn(Foo, (&'a T,))`
found type `extern "rust-call" fn(Foo, (T,))`
= 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

error: aborting due to 3 previous errors

Expand Down
1 change: 1 addition & 0 deletions src/test/ui/issues/issue-24204.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ LL | fn test<T: Trait<B=i32>>(b: i32) -> T where T::A: MultiDispatch<i32> { T::n
|
= note: expected type `<<T as Trait>::A as MultiDispatch<i32>>::O`
found type `T`
= note: you might be missing a type parameter or trait bound

error: aborting due to previous error

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-2951.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ LL | xx = y;
|
= note: expected type `T`
found type `U`
= 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

error: aborting due to previous error

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-32323.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ LL | pub fn f<'a, T: Tr<'a>>() -> <T as Tr<'a>>::Out {}
|
= note: expected type `<T as Tr<'a>>::Out`
found type `()`
= note: consider constraining the associated type `<T as Tr<'a>>::Out` to `()` or calling a method that returns `<T as Tr<'a>>::Out`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error: aborting due to previous error

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/mismatched_types/issue-35030.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ LL | Some(true)
|
= note: expected type `bool` (type parameter)
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

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ LL | ()
|
= note: expected type `<T as Foo>::Assoc`
found type `()`
= note: consider constraining the associated type `<T as Foo>::Assoc` to `()` or calling a method that returns `<T as Foo>::Assoc`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error[E0308]: mismatched types
--> $DIR/specialization-default-projection.rs:28:5
Expand All @@ -23,6 +25,8 @@ LL | generic::<()>()
|
= note: expected type `()`
found type `<() as Foo>::Assoc`
= note: consider constraining the associated type `<() as Foo>::Assoc` to `()`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error: aborting due to 2 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ LL | Box::new(self)
|
= note: expected type `<T as Example>::Output`
found type `std::boxed::Box<T>`
= note: consider constraining the associated type `<T as Example>::Output` to `std::boxed::Box<T>` or calling a method that returns `<T as Example>::Output`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error[E0308]: mismatched types
--> $DIR/specialization-default-types.rs:25:5
Expand All @@ -19,6 +21,8 @@ LL | Example::generate(t)
|
= note: expected type `std::boxed::Box<T>`
found type `<T as Example>::Output`
= note: consider constraining the associated type `<T as Example>::Output` to `std::boxed::Box<T>`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error: aborting due to 2 previous errors

Expand Down
Loading