Maintain chain of derived obligations

When evaluating the derived obligations from super traits, maintain a
reference to the original obligation in order to give more actionable
context in the output.
This commit is contained in:
Esteban Küber 2020-03-06 16:24:08 -08:00
parent 52fa23add6
commit ad1c23c993
22 changed files with 181 additions and 0 deletions

View File

@ -8,6 +8,7 @@ use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
use rustc_span::symbol::{kw, Ident};
use rustc_span::Span;
use std::rc::Rc;
/// Returns the set of obligations needed to make `ty` well-formed.
/// If `ty` contains unresolved inference variables, this may include
@ -315,6 +316,15 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
let implied_obligations = traits::util::elaborate_obligations(tcx, obligations.clone());
let implied_obligations = implied_obligations.map(|obligation| {
let mut cause = cause.clone();
let parent_trait_ref = obligation
.predicate
.to_opt_poly_trait_ref()
.unwrap_or_else(|| ty::Binder::dummy(*trait_ref));
let derived_cause = traits::DerivedObligationCause {
parent_trait_ref,
parent_code: Rc::new(obligation.cause.code.clone()),
};
cause.code = traits::ObligationCauseCode::ImplDerivedObligation(derived_cause);
extend_cause_with_original_assoc_item_obligation(
tcx,
trait_ref,

View File

@ -1,10 +1,17 @@
error[E0277]: `<L1 as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug`
--> $DIR/bad-bounds-on-assoc-in-trait.rs:31:6
|
LL | trait Case1 {
| -----
...
LL | Debug
| ----- required by this bound in `Case1`
...
LL | impl Case1 for S1 {
| ^^^^^ `<L1 as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
|
= help: the trait `for<'a> std::fmt::Debug` is not implemented for `<L1 as Lam<&'a u8>>::App`
= note: required because of the requirements on the impl of `for<'a> std::fmt::Debug` for `<<<<S1 as Case1>::C as std::iter::Iterator>::Item as std::iter::Iterator>::Item as Lam<&'a u8>>::App`
error[E0277]: `<<T as Case1>::C as std::iter::Iterator>::Item` is not an iterator
--> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20

View File

@ -42,11 +42,18 @@ LL | + Display = Self;
error[E0277]: `T` doesn't implement `std::fmt::Display`
--> $DIR/defaults-unsound-62211-1.rs:41:9
|
LL | trait UncheckedCopy: Sized {
| -------------
...
LL | + Display = Self;
| ------- required by this bound in `UncheckedCopy`
...
LL | impl<T> UncheckedCopy for T {}
| ^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `T`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: required because of the requirements on the impl of `std::fmt::Display` for `<T as UncheckedCopy>::Output`
help: consider restricting type parameter `T`
|
LL | impl<T: std::fmt::Display> UncheckedCopy for T {}
@ -55,9 +62,16 @@ LL | impl<T: std::fmt::Display> UncheckedCopy for T {}
error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
--> $DIR/defaults-unsound-62211-1.rs:41:9
|
LL | trait UncheckedCopy: Sized {
| -------------
...
LL | + Deref<Target = str>
| ------------------- required by this bound in `UncheckedCopy`
...
LL | impl<T> UncheckedCopy for T {}
| ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T`
|
= note: required because of the requirements on the impl of `std::ops::Deref` for `<T as UncheckedCopy>::Output`
help: consider restricting type parameter `T`
|
LL | impl<T: std::ops::Deref> UncheckedCopy for T {}
@ -66,10 +80,17 @@ LL | impl<T: std::ops::Deref> UncheckedCopy for T {}
error[E0277]: cannot add-assign `&'static str` to `T`
--> $DIR/defaults-unsound-62211-1.rs:41:9
|
LL | trait UncheckedCopy: Sized {
| -------------
...
LL | + AddAssign<&'static str>
| ----------------------- required by this bound in `UncheckedCopy`
...
LL | impl<T> UncheckedCopy for T {}
| ^^^^^^^^^^^^^ no implementation for `T += &'static str`
|
= help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `T`
= note: required because of the requirements on the impl of `std::ops::AddAssign<&'static str>` for `<T as UncheckedCopy>::Output`
help: consider restricting type parameter `T`
|
LL | impl<T: std::ops::AddAssign<&'static str>> UncheckedCopy for T {}
@ -78,9 +99,16 @@ LL | impl<T: std::ops::AddAssign<&'static str>> UncheckedCopy for T {}
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
--> $DIR/defaults-unsound-62211-1.rs:41:9
|
LL | trait UncheckedCopy: Sized {
| -------------
...
LL | type Output: Copy
| ---- required by this bound in `UncheckedCopy`
...
LL | impl<T> UncheckedCopy for T {}
| ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
|
= note: required because of the requirements on the impl of `std::marker::Copy` for `<T as UncheckedCopy>::Output`
help: consider restricting type parameter `T`
|
LL | impl<T: std::marker::Copy> UncheckedCopy for T {}

View File

@ -42,11 +42,18 @@ LL | + Display = Self;
error[E0277]: `T` doesn't implement `std::fmt::Display`
--> $DIR/defaults-unsound-62211-2.rs:41:9
|
LL | trait UncheckedCopy: Sized {
| -------------
...
LL | + Display = Self;
| ------- required by this bound in `UncheckedCopy`
...
LL | impl<T> UncheckedCopy for T {}
| ^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `T`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: required because of the requirements on the impl of `std::fmt::Display` for `<T as UncheckedCopy>::Output`
help: consider restricting type parameter `T`
|
LL | impl<T: std::fmt::Display> UncheckedCopy for T {}
@ -55,9 +62,16 @@ LL | impl<T: std::fmt::Display> UncheckedCopy for T {}
error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
--> $DIR/defaults-unsound-62211-2.rs:41:9
|
LL | trait UncheckedCopy: Sized {
| -------------
...
LL | + Deref<Target = str>
| ------------------- required by this bound in `UncheckedCopy`
...
LL | impl<T> UncheckedCopy for T {}
| ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T`
|
= note: required because of the requirements on the impl of `std::ops::Deref` for `<T as UncheckedCopy>::Output`
help: consider restricting type parameter `T`
|
LL | impl<T: std::ops::Deref> UncheckedCopy for T {}
@ -66,10 +80,17 @@ LL | impl<T: std::ops::Deref> UncheckedCopy for T {}
error[E0277]: cannot add-assign `&'static str` to `T`
--> $DIR/defaults-unsound-62211-2.rs:41:9
|
LL | trait UncheckedCopy: Sized {
| -------------
...
LL | + AddAssign<&'static str>
| ----------------------- required by this bound in `UncheckedCopy`
...
LL | impl<T> UncheckedCopy for T {}
| ^^^^^^^^^^^^^ no implementation for `T += &'static str`
|
= help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `T`
= note: required because of the requirements on the impl of `std::ops::AddAssign<&'static str>` for `<T as UncheckedCopy>::Output`
help: consider restricting type parameter `T`
|
LL | impl<T: std::ops::AddAssign<&'static str>> UncheckedCopy for T {}
@ -78,9 +99,16 @@ LL | impl<T: std::ops::AddAssign<&'static str>> UncheckedCopy for T {}
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
--> $DIR/defaults-unsound-62211-2.rs:41:9
|
LL | trait UncheckedCopy: Sized {
| -------------
...
LL | type Output: Copy
| ---- required by this bound in `UncheckedCopy`
...
LL | impl<T> UncheckedCopy for T {}
| ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
|
= note: required because of the requirements on the impl of `std::marker::Copy` for `<T as UncheckedCopy>::Output`
help: consider restricting type parameter `T`
|
LL | impl<T: std::marker::Copy> UncheckedCopy for T {}

View File

@ -9,14 +9,28 @@ LL | type Out: Default + ToString + ?Sized = dyn ToString;
error[E0277]: the trait bound `(dyn std::string::ToString + 'static): std::default::Default` is not satisfied
--> $DIR/issue-43924.rs:10:6
|
LL | trait Foo<T: Default + ToString> {
| ---
LL | type Out: Default + ToString + ?Sized = dyn ToString;
| ------- required by this bound in `Foo`
...
LL | impl Foo<u32> for () {}
| ^^^^^^^^ the trait `std::default::Default` is not implemented for `(dyn std::string::ToString + 'static)`
|
= note: required because of the requirements on the impl of `std::default::Default` for `<() as Foo<u32>>::Out`
error[E0277]: the trait bound `(dyn std::string::ToString + 'static): std::default::Default` is not satisfied
--> $DIR/issue-43924.rs:11:6
|
LL | trait Foo<T: Default + ToString> {
| ---
LL | type Out: Default + ToString + ?Sized = dyn ToString;
| ------- required by this bound in `Foo`
...
LL | impl Foo<u64> for () {}
| ^^^^^^^^ the trait `std::default::Default` is not implemented for `(dyn std::string::ToString + 'static)`
|
= note: required because of the requirements on the impl of `std::default::Default` for `<() as Foo<u64>>::Out`
error: aborting due to 3 previous errors

View File

@ -9,8 +9,15 @@ LL | type MpuConfig: MyDisplay = T;
error[E0277]: the trait bound `T: MyDisplay` is not satisfied
--> $DIR/issue-65774-1.rs:16:6
|
LL | trait MPU {
| ---
LL | type MpuConfig: MyDisplay = T;
| --------- required by this bound in `MPU`
...
LL | impl MPU for S { }
| ^^^ the trait `MyDisplay` is not implemented for `T`
|
= note: required because of the requirements on the impl of `MyDisplay` for `<S as MPU>::MpuConfig`
error: aborting due to 2 previous errors

View File

@ -9,8 +9,15 @@ LL | type MpuConfig: MyDisplay = T;
error[E0277]: the trait bound `T: MyDisplay` is not satisfied
--> $DIR/issue-65774-2.rs:16:6
|
LL | trait MPU {
| ---
LL | type MpuConfig: MyDisplay = T;
| --------- required by this bound in `MPU`
...
LL | impl MPU for S { }
| ^^^ the trait `MyDisplay` is not implemented for `T`
|
= note: required because of the requirements on the impl of `MyDisplay` for `<S as MPU>::MpuConfig`
error: aborting due to 2 previous errors

View File

@ -1,11 +1,15 @@
error[E0277]: `T` cannot be sent between threads safely
--> $DIR/builtin-superkinds-double-superkind.rs:6:24
|
LL | trait Foo : Send+Sync { }
| ---- required by this bound in `Foo`
LL |
LL | impl <T: Sync+'static> Foo for (T,) { }
| ^^^ `T` cannot be sent between threads safely
|
= help: within `(T,)`, the trait `std::marker::Send` is not implemented for `T`
= note: required because it appears within the type `(T,)`
= note: required because of the requirements on the impl of `std::marker::Send` for `(T,)`
help: consider further restricting this bound
|
LL | impl <T: Sync+'static + std::marker::Send> Foo for (T,) { }
@ -14,11 +18,15 @@ LL | impl <T: Sync+'static + std::marker::Send> Foo for (T,) { }
error[E0277]: `T` cannot be shared between threads safely
--> $DIR/builtin-superkinds-double-superkind.rs:9:16
|
LL | trait Foo : Send+Sync { }
| ---- required by this bound in `Foo`
...
LL | impl <T: Send> Foo for (T,T) { }
| ^^^ `T` cannot be shared between threads safely
|
= help: within `(T, T)`, the trait `std::marker::Sync` is not implemented for `T`
= note: required because it appears within the type `(T, T)`
= note: required because of the requirements on the impl of `std::marker::Sync` for `(T, T)`
help: consider further restricting this bound
|
LL | impl <T: Send + std::marker::Sync> Foo for (T,T) { }

View File

@ -3,9 +3,15 @@ error[E0277]: `T` cannot be sent between threads safely
|
LL | impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` cannot be sent between threads safely
|
::: $DIR/auxiliary/trait_superkinds_in_metadata.rs:7:58
|
LL | pub trait RequiresRequiresShareAndSend : RequiresShare + Send { }
| ---- required by this bound in `trait_superkinds_in_metadata::RequiresRequiresShareAndSend`
|
= help: within `X<T>`, the trait `std::marker::Send` is not implemented for `T`
= note: required because it appears within the type `X<T>`
= note: required because of the requirements on the impl of `std::marker::Send` for `X<T>`
help: consider further restricting this bound
|
LL | impl <T:Sync+'static + std::marker::Send> RequiresRequiresShareAndSend for X<T> { }

View File

@ -1,10 +1,14 @@
error[E0277]: `std::rc::Rc<i8>` cannot be sent between threads safely
--> $DIR/builtin-superkinds-simple.rs:6:6
|
LL | trait Foo : Send { }
| ---- required by this bound in `Foo`
LL |
LL | impl Foo for std::rc::Rc<i8> { }
| ^^^ `std::rc::Rc<i8>` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `std::rc::Rc<i8>`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::rc::Rc<i8>`
error: aborting due to previous error

View File

@ -1,10 +1,14 @@
error[E0277]: `T` cannot be sent between threads safely
--> $DIR/builtin-superkinds-typaram-not-send.rs:5:24
|
LL | trait Foo : Send { }
| ---- required by this bound in `Foo`
LL |
LL | impl <T: Sync+'static> Foo for T { }
| ^^^ `T` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `T`
= note: required because of the requirements on the impl of `std::marker::Send` for `T`
help: consider further restricting this bound
|
LL | impl <T: Sync+'static + std::marker::Send> Foo for T { }

View File

@ -1,20 +1,28 @@
error[E0277]: the size for values of type `[isize]` cannot be known at compilation time
--> $DIR/dst-sized-trait-param.rs:7:6
|
LL | trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized
| - required by this bound in `Foo`
LL |
LL | impl Foo<[isize]> for usize { }
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `[isize]`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because of the requirements on the impl of `std::marker::Sized` for `[isize]`
error[E0277]: the size for values of type `[usize]` cannot be known at compilation time
--> $DIR/dst-sized-trait-param.rs:10:6
|
LL | trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized
| ----- required by this bound in `Foo`
...
LL | impl Foo<isize> for [usize] { }
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `[usize]`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because of the requirements on the impl of `std::marker::Sized` for `[usize]`
error: aborting due to 2 previous errors

View File

@ -1,12 +1,19 @@
error[E0271]: type mismatch resolving `for<'a> <<T as Baz>::Baa<'a> as std::ops::Deref>::Target == <<T as Baz>::Quux<'a> as Foo>::Bar<'a, 'static>`
--> $DIR/construct_with_other_type.rs:19:9
|
LL | trait Baz {
| ---
...
LL | type Baa<'a>: Deref<Target = <Self::Quux<'a> as Foo>::Bar<'a, 'static>> where Self: 'a;
| -------------------------------------------------- required by this bound in `Baz`
...
LL | impl<T> Baz for T where T: Foo {
| ^^^ expected type parameter `T`, found associated type
|
= note: expected associated type `<T as Foo>::Bar<'_, 'static>`
found associated type `<<T as Baz>::Quux<'_> as Foo>::Bar<'_, 'static>`
= note: you might be missing a type parameter or trait bound
= note: required because of the requirements on the impl of `Baz` for `T`
error: aborting due to previous error

View File

@ -1,11 +1,15 @@
error[E0277]: the size for values of type `[()]` cannot be known at compilation time
--> $DIR/issue-61631-default-type-param-can-reference-self-in-trait.rs:19:6
|
LL | trait Tsized<P: Sized = [Self]> {}
| - required by this bound in `Tsized`
LL |
LL | impl Tsized for () {}
| ^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `[()]`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because of the requirements on the impl of `std::marker::Sized` for `[()]`
error: aborting due to previous error

View File

@ -1,8 +1,13 @@
error[E0277]: the trait bound `isize: Clone2` is not satisfied
--> $DIR/impl-bounds-checking.rs:10:6
|
LL | trait Getter<T: Clone2> {
| ------ required by this bound in `Getter`
...
LL | impl Getter<isize> for isize {
| ^^^^^^^^^^^^^ the trait `Clone2` is not implemented for `isize`
|
= note: required because of the requirements on the impl of `Clone2` for `isize`
error: aborting due to previous error

View File

@ -49,11 +49,15 @@ LL | impl<'self> Serializable<str> for &'self str {
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/issue-10412.rs:6:13
|
LL | trait Serializable<'self, T> {
| - required by this bound in `Serializable`
...
LL | impl<'self> Serializable<str> for &'self str {
| ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `str`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because of the requirements on the impl of `std::marker::Sized` for `str`
error: aborting due to 9 previous errors

View File

@ -4,6 +4,7 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
LL | impl<T> Complete for T {}
| ^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
|
= note: required because of the requirements on the impl of `std::marker::Copy` for `T`
help: consider restricting type parameter `T`
|
LL | impl<T: std::marker::Copy> Complete for T {}

View File

@ -21,7 +21,13 @@ error[E0277]: the trait bound `Test1: std::clone::Clone` is not satisfied
|
LL | #[derive(Copy(Bad))]
| ^^^^ the trait `std::clone::Clone` is not implemented for `Test1`
|
::: $SRC_DIR/libcore/marker.rs:LL:COL
|
LL | pub trait Copy: Clone {
| ----- required by this bound in `std::marker::Copy`
|
= note: required because of the requirements on the impl of `std::clone::Clone` for `Test1`
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `Test2: std::clone::Clone` is not satisfied
@ -29,7 +35,13 @@ error[E0277]: the trait bound `Test2: std::clone::Clone` is not satisfied
|
LL | #[derive(Copy="bad")]
| ^^^^ the trait `std::clone::Clone` is not implemented for `Test2`
|
::: $SRC_DIR/libcore/marker.rs:LL:COL
|
LL | pub trait Copy: Clone {
| ----- required by this bound in `std::marker::Copy`
|
= note: required because of the requirements on the impl of `std::clone::Clone` for `Test2`
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 5 previous errors

View File

@ -1,9 +1,13 @@
error[E0277]: the trait bound `U: std::cmp::Eq` is not satisfied
--> $DIR/specialization-wfcheck.rs:7:17
|
LL | trait Foo<'a, T: Eq + 'a> { }
| -- required by this bound in `Foo`
LL |
LL | default impl<U> Foo<'static, U> for () {}
| ^^^^^^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `U`
|
= note: required because of the requirements on the impl of `std::cmp::Eq` for `U`
help: consider restricting type parameter `U`
|
LL | default impl<U: std::cmp::Eq> Foo<'static, U> for () {}

View File

@ -1,8 +1,13 @@
error[E0271]: type mismatch resolving `<std::vec::IntoIter<i32> as std::iter::Iterator>::Item == u32`
--> $DIR/traits-assoc-type-in-supertrait-bad.rs:11:6
|
LL | pub trait Foo: Iterator<Item=<Self as Foo>::Key> {
| ----------------------- required by this bound in `Foo`
...
LL | impl Foo for IntoIter<i32> {
| ^^^ expected `i32`, found `u32`
|
= note: required because of the requirements on the impl of `Foo` for `std::vec::IntoIter<i32>`
error: aborting due to previous error

View File

@ -1,6 +1,9 @@
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized-trait-impl-trait-arg.rs:8:17
|
LL | trait T2<Z> {
| - required by this bound in `T2`
...
LL | impl<X: ?Sized> T2<X> for S4<X> {
| - ^^^^^ doesn't have a size known at compile-time
| |
@ -8,6 +11,7 @@ LL | impl<X: ?Sized> T2<X> for S4<X> {
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because of the requirements on the impl of `std::marker::Sized` for `X`
error: aborting due to previous error

View File

@ -1,6 +1,9 @@
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized7.rs:12:21
|
LL | trait T1<Z: T> {
| - required by this bound in `T1`
...
LL | impl<X: ?Sized + T> T1<X> for S3<X> {
| - ^^^^^ doesn't have a size known at compile-time
| |
@ -8,6 +11,7 @@ LL | impl<X: ?Sized + T> T1<X> for S3<X> {
|
= help: the trait `std::marker::Sized` is not implemented for `X`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because of the requirements on the impl of `std::marker::Sized` for `X`
error: aborting due to previous error