Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit ad1c23c

Browse files
committed
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.
1 parent 52fa23a commit ad1c23c

22 files changed

+181
-0
lines changed

src/librustc_trait_selection/traits/wf.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
88
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
99
use rustc_span::symbol::{kw, Ident};
1010
use rustc_span::Span;
11+
use std::rc::Rc;
1112

1213
/// Returns the set of obligations needed to make `ty` well-formed.
1314
/// If `ty` contains unresolved inference variables, this may include
@@ -315,6 +316,15 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
315316
let implied_obligations = traits::util::elaborate_obligations(tcx, obligations.clone());
316317
let implied_obligations = implied_obligations.map(|obligation| {
317318
let mut cause = cause.clone();
319+
let parent_trait_ref = obligation
320+
.predicate
321+
.to_opt_poly_trait_ref()
322+
.unwrap_or_else(|| ty::Binder::dummy(*trait_ref));
323+
let derived_cause = traits::DerivedObligationCause {
324+
parent_trait_ref,
325+
parent_code: Rc::new(obligation.cause.code.clone()),
326+
};
327+
cause.code = traits::ObligationCauseCode::ImplDerivedObligation(derived_cause);
318328
extend_cause_with_original_assoc_item_obligation(
319329
tcx,
320330
trait_ref,

src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
error[E0277]: `<L1 as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug`
22
--> $DIR/bad-bounds-on-assoc-in-trait.rs:31:6
33
|
4+
LL | trait Case1 {
5+
| -----
6+
...
7+
LL | Debug
8+
| ----- required by this bound in `Case1`
9+
...
410
LL | impl Case1 for S1 {
511
| ^^^^^ `<L1 as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
612
|
713
= help: the trait `for<'a> std::fmt::Debug` is not implemented for `<L1 as Lam<&'a u8>>::App`
14+
= 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`
815

916
error[E0277]: `<<T as Case1>::C as std::iter::Iterator>::Item` is not an iterator
1017
--> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20

src/test/ui/associated-types/defaults-unsound-62211-1.stderr

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,18 @@ LL | + Display = Self;
4242
error[E0277]: `T` doesn't implement `std::fmt::Display`
4343
--> $DIR/defaults-unsound-62211-1.rs:41:9
4444
|
45+
LL | trait UncheckedCopy: Sized {
46+
| -------------
47+
...
48+
LL | + Display = Self;
49+
| ------- required by this bound in `UncheckedCopy`
50+
...
4551
LL | impl<T> UncheckedCopy for T {}
4652
| ^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter
4753
|
4854
= help: the trait `std::fmt::Display` is not implemented for `T`
4955
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
56+
= note: required because of the requirements on the impl of `std::fmt::Display` for `<T as UncheckedCopy>::Output`
5057
help: consider restricting type parameter `T`
5158
|
5259
LL | impl<T: std::fmt::Display> UncheckedCopy for T {}
@@ -55,9 +62,16 @@ LL | impl<T: std::fmt::Display> UncheckedCopy for T {}
5562
error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
5663
--> $DIR/defaults-unsound-62211-1.rs:41:9
5764
|
65+
LL | trait UncheckedCopy: Sized {
66+
| -------------
67+
...
68+
LL | + Deref<Target = str>
69+
| ------------------- required by this bound in `UncheckedCopy`
70+
...
5871
LL | impl<T> UncheckedCopy for T {}
5972
| ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T`
6073
|
74+
= note: required because of the requirements on the impl of `std::ops::Deref` for `<T as UncheckedCopy>::Output`
6175
help: consider restricting type parameter `T`
6276
|
6377
LL | impl<T: std::ops::Deref> UncheckedCopy for T {}
@@ -66,10 +80,17 @@ LL | impl<T: std::ops::Deref> UncheckedCopy for T {}
6680
error[E0277]: cannot add-assign `&'static str` to `T`
6781
--> $DIR/defaults-unsound-62211-1.rs:41:9
6882
|
83+
LL | trait UncheckedCopy: Sized {
84+
| -------------
85+
...
86+
LL | + AddAssign<&'static str>
87+
| ----------------------- required by this bound in `UncheckedCopy`
88+
...
6989
LL | impl<T> UncheckedCopy for T {}
7090
| ^^^^^^^^^^^^^ no implementation for `T += &'static str`
7191
|
7292
= help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `T`
93+
= note: required because of the requirements on the impl of `std::ops::AddAssign<&'static str>` for `<T as UncheckedCopy>::Output`
7394
help: consider restricting type parameter `T`
7495
|
7596
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 {}
7899
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
79100
--> $DIR/defaults-unsound-62211-1.rs:41:9
80101
|
102+
LL | trait UncheckedCopy: Sized {
103+
| -------------
104+
...
105+
LL | type Output: Copy
106+
| ---- required by this bound in `UncheckedCopy`
107+
...
81108
LL | impl<T> UncheckedCopy for T {}
82109
| ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
83110
|
111+
= note: required because of the requirements on the impl of `std::marker::Copy` for `<T as UncheckedCopy>::Output`
84112
help: consider restricting type parameter `T`
85113
|
86114
LL | impl<T: std::marker::Copy> UncheckedCopy for T {}

src/test/ui/associated-types/defaults-unsound-62211-2.stderr

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,18 @@ LL | + Display = Self;
4242
error[E0277]: `T` doesn't implement `std::fmt::Display`
4343
--> $DIR/defaults-unsound-62211-2.rs:41:9
4444
|
45+
LL | trait UncheckedCopy: Sized {
46+
| -------------
47+
...
48+
LL | + Display = Self;
49+
| ------- required by this bound in `UncheckedCopy`
50+
...
4551
LL | impl<T> UncheckedCopy for T {}
4652
| ^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter
4753
|
4854
= help: the trait `std::fmt::Display` is not implemented for `T`
4955
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
56+
= note: required because of the requirements on the impl of `std::fmt::Display` for `<T as UncheckedCopy>::Output`
5057
help: consider restricting type parameter `T`
5158
|
5259
LL | impl<T: std::fmt::Display> UncheckedCopy for T {}
@@ -55,9 +62,16 @@ LL | impl<T: std::fmt::Display> UncheckedCopy for T {}
5562
error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
5663
--> $DIR/defaults-unsound-62211-2.rs:41:9
5764
|
65+
LL | trait UncheckedCopy: Sized {
66+
| -------------
67+
...
68+
LL | + Deref<Target = str>
69+
| ------------------- required by this bound in `UncheckedCopy`
70+
...
5871
LL | impl<T> UncheckedCopy for T {}
5972
| ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T`
6073
|
74+
= note: required because of the requirements on the impl of `std::ops::Deref` for `<T as UncheckedCopy>::Output`
6175
help: consider restricting type parameter `T`
6276
|
6377
LL | impl<T: std::ops::Deref> UncheckedCopy for T {}
@@ -66,10 +80,17 @@ LL | impl<T: std::ops::Deref> UncheckedCopy for T {}
6680
error[E0277]: cannot add-assign `&'static str` to `T`
6781
--> $DIR/defaults-unsound-62211-2.rs:41:9
6882
|
83+
LL | trait UncheckedCopy: Sized {
84+
| -------------
85+
...
86+
LL | + AddAssign<&'static str>
87+
| ----------------------- required by this bound in `UncheckedCopy`
88+
...
6989
LL | impl<T> UncheckedCopy for T {}
7090
| ^^^^^^^^^^^^^ no implementation for `T += &'static str`
7191
|
7292
= help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `T`
93+
= note: required because of the requirements on the impl of `std::ops::AddAssign<&'static str>` for `<T as UncheckedCopy>::Output`
7394
help: consider restricting type parameter `T`
7495
|
7596
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 {}
7899
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
79100
--> $DIR/defaults-unsound-62211-2.rs:41:9
80101
|
102+
LL | trait UncheckedCopy: Sized {
103+
| -------------
104+
...
105+
LL | type Output: Copy
106+
| ---- required by this bound in `UncheckedCopy`
107+
...
81108
LL | impl<T> UncheckedCopy for T {}
82109
| ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
83110
|
111+
= note: required because of the requirements on the impl of `std::marker::Copy` for `<T as UncheckedCopy>::Output`
84112
help: consider restricting type parameter `T`
85113
|
86114
LL | impl<T: std::marker::Copy> UncheckedCopy for T {}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,28 @@ LL | type Out: Default + ToString + ?Sized = dyn ToString;
99
error[E0277]: the trait bound `(dyn std::string::ToString + 'static): std::default::Default` is not satisfied
1010
--> $DIR/issue-43924.rs:10:6
1111
|
12+
LL | trait Foo<T: Default + ToString> {
13+
| ---
14+
LL | type Out: Default + ToString + ?Sized = dyn ToString;
15+
| ------- required by this bound in `Foo`
16+
...
1217
LL | impl Foo<u32> for () {}
1318
| ^^^^^^^^ the trait `std::default::Default` is not implemented for `(dyn std::string::ToString + 'static)`
19+
|
20+
= note: required because of the requirements on the impl of `std::default::Default` for `<() as Foo<u32>>::Out`
1421

1522
error[E0277]: the trait bound `(dyn std::string::ToString + 'static): std::default::Default` is not satisfied
1623
--> $DIR/issue-43924.rs:11:6
1724
|
25+
LL | trait Foo<T: Default + ToString> {
26+
| ---
27+
LL | type Out: Default + ToString + ?Sized = dyn ToString;
28+
| ------- required by this bound in `Foo`
29+
...
1830
LL | impl Foo<u64> for () {}
1931
| ^^^^^^^^ the trait `std::default::Default` is not implemented for `(dyn std::string::ToString + 'static)`
32+
|
33+
= note: required because of the requirements on the impl of `std::default::Default` for `<() as Foo<u64>>::Out`
2034

2135
error: aborting due to 3 previous errors
2236

src/test/ui/associated-types/issue-65774-1.stderr

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ LL | type MpuConfig: MyDisplay = T;
99
error[E0277]: the trait bound `T: MyDisplay` is not satisfied
1010
--> $DIR/issue-65774-1.rs:16:6
1111
|
12+
LL | trait MPU {
13+
| ---
14+
LL | type MpuConfig: MyDisplay = T;
15+
| --------- required by this bound in `MPU`
16+
...
1217
LL | impl MPU for S { }
1318
| ^^^ the trait `MyDisplay` is not implemented for `T`
19+
|
20+
= note: required because of the requirements on the impl of `MyDisplay` for `<S as MPU>::MpuConfig`
1421

1522
error: aborting due to 2 previous errors
1623

src/test/ui/associated-types/issue-65774-2.stderr

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ LL | type MpuConfig: MyDisplay = T;
99
error[E0277]: the trait bound `T: MyDisplay` is not satisfied
1010
--> $DIR/issue-65774-2.rs:16:6
1111
|
12+
LL | trait MPU {
13+
| ---
14+
LL | type MpuConfig: MyDisplay = T;
15+
| --------- required by this bound in `MPU`
16+
...
1217
LL | impl MPU for S { }
1318
| ^^^ the trait `MyDisplay` is not implemented for `T`
19+
|
20+
= note: required because of the requirements on the impl of `MyDisplay` for `<S as MPU>::MpuConfig`
1421

1522
error: aborting due to 2 previous errors
1623

src/test/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
error[E0277]: `T` cannot be sent between threads safely
22
--> $DIR/builtin-superkinds-double-superkind.rs:6:24
33
|
4+
LL | trait Foo : Send+Sync { }
5+
| ---- required by this bound in `Foo`
6+
LL |
47
LL | impl <T: Sync+'static> Foo for (T,) { }
58
| ^^^ `T` cannot be sent between threads safely
69
|
710
= help: within `(T,)`, the trait `std::marker::Send` is not implemented for `T`
811
= note: required because it appears within the type `(T,)`
12+
= note: required because of the requirements on the impl of `std::marker::Send` for `(T,)`
913
help: consider further restricting this bound
1014
|
1115
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,) { }
1418
error[E0277]: `T` cannot be shared between threads safely
1519
--> $DIR/builtin-superkinds-double-superkind.rs:9:16
1620
|
21+
LL | trait Foo : Send+Sync { }
22+
| ---- required by this bound in `Foo`
23+
...
1724
LL | impl <T: Send> Foo for (T,T) { }
1825
| ^^^ `T` cannot be shared between threads safely
1926
|
2027
= help: within `(T, T)`, the trait `std::marker::Sync` is not implemented for `T`
2128
= note: required because it appears within the type `(T, T)`
29+
= note: required because of the requirements on the impl of `std::marker::Sync` for `(T, T)`
2230
help: consider further restricting this bound
2331
|
2432
LL | impl <T: Send + std::marker::Sync> Foo for (T,T) { }

src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@ error[E0277]: `T` cannot be sent between threads safely
33
|
44
LL | impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` cannot be sent between threads safely
6+
|
7+
::: $DIR/auxiliary/trait_superkinds_in_metadata.rs:7:58
8+
|
9+
LL | pub trait RequiresRequiresShareAndSend : RequiresShare + Send { }
10+
| ---- required by this bound in `trait_superkinds_in_metadata::RequiresRequiresShareAndSend`
611
|
712
= help: within `X<T>`, the trait `std::marker::Send` is not implemented for `T`
813
= note: required because it appears within the type `X<T>`
14+
= note: required because of the requirements on the impl of `std::marker::Send` for `X<T>`
915
help: consider further restricting this bound
1016
|
1117
LL | impl <T:Sync+'static + std::marker::Send> RequiresRequiresShareAndSend for X<T> { }

src/test/ui/builtin-superkinds/builtin-superkinds-simple.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
error[E0277]: `std::rc::Rc<i8>` cannot be sent between threads safely
22
--> $DIR/builtin-superkinds-simple.rs:6:6
33
|
4+
LL | trait Foo : Send { }
5+
| ---- required by this bound in `Foo`
6+
LL |
47
LL | impl Foo for std::rc::Rc<i8> { }
58
| ^^^ `std::rc::Rc<i8>` cannot be sent between threads safely
69
|
710
= help: the trait `std::marker::Send` is not implemented for `std::rc::Rc<i8>`
11+
= note: required because of the requirements on the impl of `std::marker::Send` for `std::rc::Rc<i8>`
812

913
error: aborting due to previous error
1014

src/test/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
error[E0277]: `T` cannot be sent between threads safely
22
--> $DIR/builtin-superkinds-typaram-not-send.rs:5:24
33
|
4+
LL | trait Foo : Send { }
5+
| ---- required by this bound in `Foo`
6+
LL |
47
LL | impl <T: Sync+'static> Foo for T { }
58
| ^^^ `T` cannot be sent between threads safely
69
|
710
= help: the trait `std::marker::Send` is not implemented for `T`
11+
= note: required because of the requirements on the impl of `std::marker::Send` for `T`
812
help: consider further restricting this bound
913
|
1014
LL | impl <T: Sync+'static + std::marker::Send> Foo for T { }

src/test/ui/dst/dst-sized-trait-param.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
error[E0277]: the size for values of type `[isize]` cannot be known at compilation time
22
--> $DIR/dst-sized-trait-param.rs:7:6
33
|
4+
LL | trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized
5+
| - required by this bound in `Foo`
6+
LL |
47
LL | impl Foo<[isize]> for usize { }
58
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
69
|
710
= help: the trait `std::marker::Sized` is not implemented for `[isize]`
811
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
12+
= note: required because of the requirements on the impl of `std::marker::Sized` for `[isize]`
913

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

1927
error: aborting due to 2 previous errors
2028

src/test/ui/generic-associated-types/construct_with_other_type.stderr

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
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>`
22
--> $DIR/construct_with_other_type.rs:19:9
33
|
4+
LL | trait Baz {
5+
| ---
6+
...
7+
LL | type Baa<'a>: Deref<Target = <Self::Quux<'a> as Foo>::Bar<'a, 'static>> where Self: 'a;
8+
| -------------------------------------------------- required by this bound in `Baz`
9+
...
410
LL | impl<T> Baz for T where T: Foo {
511
| ^^^ expected type parameter `T`, found associated type
612
|
713
= note: expected associated type `<T as Foo>::Bar<'_, 'static>`
814
found associated type `<<T as Baz>::Quux<'_> as Foo>::Bar<'_, 'static>`
915
= note: you might be missing a type parameter or trait bound
16+
= note: required because of the requirements on the impl of `Baz` for `T`
1017

1118
error: aborting due to previous error
1219

src/test/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
error[E0277]: the size for values of type `[()]` cannot be known at compilation time
22
--> $DIR/issue-61631-default-type-param-can-reference-self-in-trait.rs:19:6
33
|
4+
LL | trait Tsized<P: Sized = [Self]> {}
5+
| - required by this bound in `Tsized`
6+
LL |
47
LL | impl Tsized for () {}
58
| ^^^^^^ doesn't have a size known at compile-time
69
|
710
= help: the trait `std::marker::Sized` is not implemented for `[()]`
811
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
12+
= note: required because of the requirements on the impl of `std::marker::Sized` for `[()]`
913

1014
error: aborting due to previous error
1115

0 commit comments

Comments
 (0)