about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2023-01-12 21:32:06 +0000
committerEsteban Küber <esteban@kuber.com.ar>2023-01-13 18:20:23 +0000
commit3d6b09e53e0b1d5920fe3c6106f676b7b95f4a70 (patch)
tree3f53fe89cbc4a44fa82c70f4d695b7c7d482bcd9
parentf6e6d2a035d9e86e7053847aa60a99940f41064c (diff)
downloadrust-3d6b09e53e0b1d5920fe3c6106f676b7b95f4a70.tar.gz
rust-3d6b09e53e0b1d5920fe3c6106f676b7b95f4a70.zip
Keep obligation chain when elaborating obligations
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs15
-rw-r--r--compiler/rustc_infer/src/traits/util.rs18
-rw-r--r--tests/ui/associated-types/issue-43784-associated-type.stderr5
-rw-r--r--tests/ui/derives/issue-91550.stderr29
-rw-r--r--tests/ui/generic-associated-types/issue-74824.stderr1
-rw-r--r--tests/ui/traits/issue-43784-supertrait.stderr5
6 files changed, 59 insertions, 14 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 8166eb82990..338fabca389 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -692,7 +692,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             "auto trait is invoked with no method error, but no error reported?",
                         );
                     }
-                    Some(_) => unreachable!(),
+                    Some(Node::Item(hir::Item {
+                        ident, kind: hir::ItemKind::Trait(..), ..
+                    })) => {
+                        skip_list.insert(p);
+                        let entry = spanned_predicates.entry(ident.span);
+                        let entry = entry.or_insert_with(|| {
+                            (FxHashSet::default(), FxHashSet::default(), Vec::new())
+                        });
+                        entry.0.insert(cause.span);
+                        entry.1.insert((ident.span, ""));
+                        entry.1.insert((cause.span, "unsatisfied trait bound introduced here"));
+                        entry.2.push(p);
+                    }
+                    Some(node) => unreachable!("encountered `{node:?}`"),
                     None => (),
                 }
             }
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 8f0bd3a9abe..1817bbf9228 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -1,7 +1,7 @@
 use smallvec::smallvec;
 
 use crate::infer::outlives::components::{push_outlives_components, Component};
-use crate::traits::{Obligation, ObligationCause, PredicateObligation};
+use crate::traits::{self, Obligation, ObligationCause, PredicateObligation};
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_middle::ty::{self, ToPredicate, TyCtxt};
 use rustc_span::symbol::Ident;
@@ -145,16 +145,28 @@ impl<'tcx> Elaborator<'tcx> {
                 // Get predicates declared on the trait.
                 let predicates = tcx.super_predicates_of(data.def_id());
 
-                let obligations = predicates.predicates.iter().map(|&(mut pred, _)| {
+                let obligations = predicates.predicates.iter().map(|&(mut pred, span)| {
                     // when parent predicate is non-const, elaborate it to non-const predicates.
                     if data.constness == ty::BoundConstness::NotConst {
                         pred = pred.without_const(tcx);
                     }
 
+                    let cause = obligation.cause.clone().derived_cause(
+                        bound_predicate.rebind(data),
+                        |derived| {
+                            traits::ImplDerivedObligation(Box::new(
+                                traits::ImplDerivedObligationCause {
+                                    derived,
+                                    impl_def_id: data.def_id(),
+                                    span,
+                                },
+                            ))
+                        },
+                    );
                     predicate_obligation(
                         pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
                         obligation.param_env,
-                        obligation.cause.clone(),
+                        cause,
                     )
                 });
                 debug!(?data, ?obligations, "super_predicates");
diff --git a/tests/ui/associated-types/issue-43784-associated-type.stderr b/tests/ui/associated-types/issue-43784-associated-type.stderr
index f1677b822b4..50fa7d1ac4d 100644
--- a/tests/ui/associated-types/issue-43784-associated-type.stderr
+++ b/tests/ui/associated-types/issue-43784-associated-type.stderr
@@ -4,6 +4,11 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
 LL |     type Assoc = T;
    |                  ^ the trait `Copy` is not implemented for `T`
    |
+note: required for `<T as Complete>::Assoc` to implement `Partial<T>`
+  --> $DIR/issue-43784-associated-type.rs:1:11
+   |
+LL | pub trait Partial<X: ?Sized>: Copy {
+   |           ^^^^^^^
 note: required by a bound in `Complete::Assoc`
   --> $DIR/issue-43784-associated-type.rs:5:17
    |
diff --git a/tests/ui/derives/issue-91550.stderr b/tests/ui/derives/issue-91550.stderr
index 381d860a9c3..af03f0e5e5f 100644
--- a/tests/ui/derives/issue-91550.stderr
+++ b/tests/ui/derives/issue-91550.stderr
@@ -36,15 +36,16 @@ LL | struct Object<T>(T);
 LL |     foo.use_eq();
    |         ^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
    |
-note: the following trait bounds were not satisfied:
-      `NoDerives: Eq`
-      `NoDerives: PartialEq`
+note: trait bound `NoDerives: Eq` was not satisfied
   --> $DIR/issue-91550.rs:15:9
    |
 LL | impl<T: Eq> Object<T> {
    |         ^^  ---------
    |         |
    |         unsatisfied trait bound introduced here
+   = note: the following trait bounds were not satisfied:
+           `NoDerives: PartialEq`
+           which is required by `NoDerives: Eq`
 help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]`
    |
 LL | #[derive(Eq, PartialEq)]
@@ -67,17 +68,20 @@ LL | struct Object<T>(T);
 LL |     foo.use_ord();
    |         ^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
    |
-note: the following trait bounds were not satisfied:
-      `NoDerives: Eq`
-      `NoDerives: Ord`
-      `NoDerives: PartialEq`
-      `NoDerives: PartialOrd`
+note: trait bound `NoDerives: Ord` was not satisfied
   --> $DIR/issue-91550.rs:18:9
    |
 LL | impl<T: Ord> Object<T> {
    |         ^^^  ---------
    |         |
    |         unsatisfied trait bound introduced here
+   = note: the following trait bounds were not satisfied:
+           `NoDerives: PartialOrd`
+           which is required by `NoDerives: Ord`
+           `NoDerives: PartialEq`
+           which is required by `NoDerives: Ord`
+           `NoDerives: Eq`
+           which is required by `NoDerives: Ord`
 help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
    |
 LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]
@@ -101,9 +105,7 @@ LL |     foo.use_ord_and_partial_ord();
    |         ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
    |
 note: the following trait bounds were not satisfied:
-      `NoDerives: Eq`
       `NoDerives: Ord`
-      `NoDerives: PartialEq`
       `NoDerives: PartialOrd`
   --> $DIR/issue-91550.rs:21:9
    |
@@ -112,6 +114,13 @@ LL | impl<T: Ord + PartialOrd> Object<T> {
    |         |     |
    |         |     unsatisfied trait bound introduced here
    |         unsatisfied trait bound introduced here
+   = note: the following trait bounds were not satisfied:
+           `NoDerives: PartialEq`
+           which is required by `NoDerives: Ord`
+           `NoDerives: Eq`
+           which is required by `NoDerives: Ord`
+           `NoDerives: PartialEq`
+           which is required by `NoDerives: PartialOrd`
 help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
    |
 LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]
diff --git a/tests/ui/generic-associated-types/issue-74824.stderr b/tests/ui/generic-associated-types/issue-74824.stderr
index 623adb1c2ad..e5638d90ee8 100644
--- a/tests/ui/generic-associated-types/issue-74824.stderr
+++ b/tests/ui/generic-associated-types/issue-74824.stderr
@@ -17,6 +17,7 @@ LL |     type Copy<T>: Copy = Box<T>;
    |                          ^^^^^^ the trait `Clone` is not implemented for `T`
    |
    = note: required for `Box<T>` to implement `Clone`
+   = note: required for `<Self as UnsafeCopy>::Copy<T>` to implement `Copy`
 note: required by a bound in `UnsafeCopy::Copy`
   --> $DIR/issue-74824.rs:6:19
    |
diff --git a/tests/ui/traits/issue-43784-supertrait.stderr b/tests/ui/traits/issue-43784-supertrait.stderr
index 4fe12731475..6b5b721384c 100644
--- a/tests/ui/traits/issue-43784-supertrait.stderr
+++ b/tests/ui/traits/issue-43784-supertrait.stderr
@@ -4,6 +4,11 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
 LL | impl<T> Complete for T {}
    |                      ^ the trait `Copy` is not implemented for `T`
    |
+note: required for `T` to implement `Partial`
+  --> $DIR/issue-43784-supertrait.rs:1:11
+   |
+LL | pub trait Partial: Copy {
+   |           ^^^^^^^
 note: required by a bound in `Complete`
   --> $DIR/issue-43784-supertrait.rs:4:21
    |