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`, 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); | ---------------- method `use_eq` not found for this struct @@ -30,7 +36,9 @@ LL | struct Object(T); LL | foo.use_eq(); | ^^^^^^ method cannot be called on `Object` 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 Object { @@ -46,7 +54,12 @@ error[E0599]: the method `use_ord` exists for struct `Object`, 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); | ---------------- method `use_ord` not found for this struct @@ -54,7 +67,11 @@ LL | struct Object(T); LL | foo.use_ord(); | ^^^^^^^ method cannot be called on `Object` 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 Object { @@ -72,7 +89,9 @@ error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object(T); @@ -82,7 +101,9 @@ LL | foo.use_ord_and_partial_ord(); | ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object` 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(this: &HashSet, other: &HashSet) -> bool where T: Eq, T: Hash { +fn is_subset(this: &HashSet, other: &HashSet) -> 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(this: &HashSet, other: &HashSet) -> bool where T: Eq, T: Hash { - | ++++++++++++++++++++ +LL | fn is_subset(this: &HashSet, other: &HashSet) -> bool where T: Eq, T: Hash, T: PartialEq { + | ++++++++++++++++++++++++++++++++++ error: aborting due to previous error