about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs28
-rw-r--r--tests/ui/derives/issue-91550.stderr29
-rw-r--r--tests/ui/missing-trait-bounds/issue-35677.fixed2
-rw-r--r--tests/ui/missing-trait-bounds/issue-35677.stderr6
4 files changed, 53 insertions, 12 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index dd827777df9..15f6e117177 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -1587,11 +1587,29 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                         let o = self.resolve_vars_if_possible(o);
                         if !self.predicate_may_hold(&o) {
                             result = ProbeResult::NoMatch;
-                            possibly_unsatisfied_predicates.push((
-                                o.predicate,
-                                None,
-                                Some(o.cause),
-                            ));
+                            let parent_o = o.clone();
+                            let implied_obligations =
+                                traits::elaborate_obligations(self.tcx, vec![o]);
+                            for o in implied_obligations {
+                                let parent = if o == parent_o {
+                                    None
+                                } else {
+                                    if o.predicate.to_opt_poly_trait_pred().map(|p| p.def_id())
+                                        == self.tcx.lang_items().sized_trait()
+                                    {
+                                        // We don't care to talk about implicit `Sized` bounds.
+                                        continue;
+                                    }
+                                    Some(parent_o.predicate)
+                                };
+                                if !self.predicate_may_hold(&o) {
+                                    possibly_unsatisfied_predicates.push((
+                                        o.predicate,
+                                        parent,
+                                        Some(o.cause),
+                                    ));
+                                }
+                            }
                         }
                     }
                 }
diff --git a/tests/ui/derives/issue-91550.stderr b/tests/ui/derives/issue-91550.stderr
index bf0bb3fbdf8..381d860a9c3 100644
--- a/tests/ui/derives/issue-91550.stderr
+++ b/tests/ui/derives/issue-91550.stderr
@@ -6,12 +6,15 @@ LL | struct Value(u32);
    | |
    | doesn't satisfy `Value: Eq`
    | doesn't satisfy `Value: Hash`
+   | doesn't satisfy `Value: PartialEq`
 ...
 LL |     hs.insert(Value(0));
    |        ^^^^^^
    |
    = note: the following trait bounds were not satisfied:
            `Value: Eq`
+           `Value: PartialEq`
+           which is required by `Value: Eq`
            `Value: Hash`
 help: consider annotating `Value` with `#[derive(Eq, Hash, PartialEq)]`
    |
@@ -22,7 +25,10 @@ error[E0599]: the method `use_eq` exists for struct `Object<NoDerives>`, but its
   --> $DIR/issue-91550.rs:26:9
    |
 LL | pub struct NoDerives;
-   | -------------------- doesn't satisfy `NoDerives: Eq`
+   | --------------------
+   | |
+   | doesn't satisfy `NoDerives: Eq`
+   | doesn't satisfy `NoDerives: PartialEq`
 LL |
 LL | struct Object<T>(T);
    | ---------------- method `use_eq` not found for this struct
@@ -30,7 +36,9 @@ LL | struct Object<T>(T);
 LL |     foo.use_eq();
    |         ^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
    |
-note: trait bound `NoDerives: Eq` was not satisfied
+note: the following trait bounds were not satisfied:
+      `NoDerives: Eq`
+      `NoDerives: PartialEq`
   --> $DIR/issue-91550.rs:15:9
    |
 LL | impl<T: Eq> Object<T> {
@@ -46,7 +54,12 @@ error[E0599]: the method `use_ord` exists for struct `Object<NoDerives>`, but it
   --> $DIR/issue-91550.rs:27:9
    |
 LL | pub struct NoDerives;
-   | -------------------- doesn't satisfy `NoDerives: Ord`
+   | --------------------
+   | |
+   | doesn't satisfy `NoDerives: Eq`
+   | doesn't satisfy `NoDerives: Ord`
+   | doesn't satisfy `NoDerives: PartialEq`
+   | doesn't satisfy `NoDerives: PartialOrd`
 LL |
 LL | struct Object<T>(T);
    | ---------------- method `use_ord` not found for this struct
@@ -54,7 +67,11 @@ LL | struct Object<T>(T);
 LL |     foo.use_ord();
    |         ^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
    |
-note: trait bound `NoDerives: Ord` was not satisfied
+note: the following trait bounds were not satisfied:
+      `NoDerives: Eq`
+      `NoDerives: Ord`
+      `NoDerives: PartialEq`
+      `NoDerives: PartialOrd`
   --> $DIR/issue-91550.rs:18:9
    |
 LL | impl<T: Ord> Object<T> {
@@ -72,7 +89,9 @@ error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoD
 LL | pub struct NoDerives;
    | --------------------
    | |
+   | doesn't satisfy `NoDerives: Eq`
    | doesn't satisfy `NoDerives: Ord`
+   | doesn't satisfy `NoDerives: PartialEq`
    | doesn't satisfy `NoDerives: PartialOrd`
 LL |
 LL | struct Object<T>(T);
@@ -82,7 +101,9 @@ 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
    |
diff --git a/tests/ui/missing-trait-bounds/issue-35677.fixed b/tests/ui/missing-trait-bounds/issue-35677.fixed
index 08174d8d8d5..c76b6bc9c18 100644
--- a/tests/ui/missing-trait-bounds/issue-35677.fixed
+++ b/tests/ui/missing-trait-bounds/issue-35677.fixed
@@ -3,7 +3,7 @@
 use std::collections::HashSet;
 use std::hash::Hash;
 
-fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash {
+fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash, T: PartialEq {
     this.is_subset(other)
     //~^ ERROR the method
 }
diff --git a/tests/ui/missing-trait-bounds/issue-35677.stderr b/tests/ui/missing-trait-bounds/issue-35677.stderr
index a2201b946a6..067b10b873a 100644
--- a/tests/ui/missing-trait-bounds/issue-35677.stderr
+++ b/tests/ui/missing-trait-bounds/issue-35677.stderr
@@ -6,11 +6,13 @@ LL |     this.is_subset(other)
    |
    = note: the following trait bounds were not satisfied:
            `T: Eq`
+           `T: PartialEq`
+           which is required by `T: Eq`
            `T: Hash`
 help: consider restricting the type parameters to satisfy the trait bounds
    |
-LL | fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash {
-   |                                                                ++++++++++++++++++++
+LL | fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash, T: PartialEq {
+   |                                                                ++++++++++++++++++++++++++++++++++
 
 error: aborting due to previous error