From fb5d2153473b8a61e8697d05da10fc37d849fb80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 11 Jan 2023 03:07:14 +0000 Subject: [PATCH] Conserve cause of `ImplDerivedObligation` in E0599 CC #86377. --- compiler/rustc_hir_typeck/src/method/probe.rs | 18 ++++- .../rustc_hir_typeck/src/method/suggest.rs | 41 ++++++------ .../generic_const_exprs/issue-69654.stderr | 10 ++- .../generic_const_exprs/issue-80742.stderr | 13 +++- tests/ui/derives/issue-91492.stderr | 9 ++- tests/ui/derives/issue-91550.stderr | 35 ++++++++-- .../method-unsatified-assoc-type-predicate.rs | 2 +- tests/ui/impl-trait/issues/issue-62742.stderr | 9 ++- ...ethod-not-found-generic-arg-elision.stderr | 17 ++++- .../derive-trait-for-method-call.stderr | 67 ++++++++++++++++--- 10 files changed, 171 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 5d8383170f0..63067deb7b0 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1556,7 +1556,23 @@ fn consider_probe( // Convert the bounds into obligations. let impl_obligations = traits::predicates_for_generics( - |_, _| cause.clone(), + |_idx, span| { + let misc = traits::ObligationCause::misc(span, self.body_id); + let parent_trait_pred = ty::Binder::dummy(ty::TraitPredicate { + trait_ref: ty::TraitRef::from_method(self.tcx, impl_def_id, substs), + constness: ty::BoundConstness::NotConst, + polarity: ty::ImplPolarity::Positive, + }); + misc.derived_cause(parent_trait_pred, |derived| { + traits::ImplDerivedObligation(Box::new( + traits::ImplDerivedObligationCause { + derived, + impl_def_id, + span, + }, + )) + }) + }, self.param_env, impl_bounds, ); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 62e80659486..8c39e4413c5 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -101,6 +101,7 @@ fn is_slice_ty(&self, ty: Ty<'tcx>, span: Span) -> bool { self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..))) } + #[instrument(level = "debug", skip(self))] pub fn report_method_error( &self, span: Span, @@ -587,21 +588,18 @@ pub fn report_no_match_method_error( // Find all the requirements that come from a local `impl` block. let mut skip_list: FxHashSet<_> = Default::default(); let mut spanned_predicates: FxHashMap = Default::default(); - for (data, p, parent_p, impl_def_id, cause) in unsatisfied_predicates + for (p, parent_p, impl_def_id, cause) in unsatisfied_predicates .iter() .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c))) .filter_map(|(p, parent, c)| match c.code() { - ObligationCauseCode::ImplDerivedObligation(data) => { - Some((&data.derived, p, parent, data.impl_def_id, data)) + ObligationCauseCode::ImplDerivedObligation(data) + if matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) => + { + Some((p, parent, data.impl_def_id, data)) } _ => None, }) { - let parent_trait_ref = data.parent_trait_pred; - let path = parent_trait_ref.print_modifiers_and_trait_path(); - let tr_self_ty = parent_trait_ref.skip_binder().self_ty(); - let unsatisfied_msg = "unsatisfied trait bound introduced here"; - let derive_msg = "unsatisfied trait bound introduced in this `derive` macro"; match self.tcx.hir().get_if_local(impl_def_id) { // Unmet obligation comes from a `derive` macro, point at it once to // avoid multiple span labels pointing at the same place. @@ -618,9 +616,12 @@ pub fn report_no_match_method_error( { let span = self_ty.span.ctxt().outer_expn_data().call_site; let mut spans: MultiSpan = span.into(); - spans.push_span_label(span, derive_msg); + spans.push_span_label( + span, + "unsatisfied trait bound introduced in this `derive` macro", + ); let entry = spanned_predicates.entry(spans); - entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); + entry.or_insert_with(|| Vec::new()).push(p); } // Unmet obligation coming from an `impl`. @@ -647,8 +648,7 @@ pub fn report_no_match_method_error( }; err.span_suggestion_verbose( sp, - "consider relaxing the type parameter's implicit \ - `Sized` bound", + "consider relaxing the type parameter's implicit `Sized` bound", sugg, Applicability::MachineApplicable, ); @@ -661,7 +661,10 @@ pub fn report_no_match_method_error( skip_list.insert(p); let mut spans = if cause.span != *item_span { let mut spans: MultiSpan = cause.span.into(); - spans.push_span_label(cause.span, unsatisfied_msg); + spans.push_span_label( + cause.span, + "unsatisfied trait bound introduced here", + ); spans } else { let mut spans = Vec::with_capacity(2); @@ -677,7 +680,7 @@ pub fn report_no_match_method_error( spans.push_span_label(self_ty.span, ""); let entry = spanned_predicates.entry(spans); - entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); + entry.or_insert_with(|| Vec::new()).push(p); } Some(Node::Item(hir::Item { kind: hir::ItemKind::Trait(rustc_ast::ast::IsAuto::Yes, ..), @@ -694,11 +697,11 @@ pub fn report_no_match_method_error( } } let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect(); - spanned_predicates.sort_by_key(|(span, (_, _, _))| span.primary_span()); - for (span, (_path, _self_ty, preds)) in spanned_predicates { - let mut preds: Vec<_> = preds - .into_iter() - .filter_map(|pred| format_pred(*pred)) + spanned_predicates.sort_by_key(|(span, _)| span.primary_span()); + for (span, predicates) in spanned_predicates { + let mut preds: Vec<_> = predicates + .iter() + .filter_map(|pred| format_pred(**pred)) .map(|(p, _)| format!("`{}`", p)) .collect(); preds.sort(); diff --git a/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr index c3e2f8e1646..eb4ff8305da 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr @@ -15,8 +15,14 @@ LL | struct Foo {} LL | Foo::foo(); | ^^^ function or associated item cannot be called on `Foo<_>` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `[u8; _]: Bar<[(); _]>` +note: trait bound `[u8; _]: Bar<[(); _]>` was not satisfied + --> $DIR/issue-69654.rs:11:14 + | +LL | impl Foo + | ------ +LL | where +LL | [u8; N]: Bar<[(); N]>, + | ^^^^^^^^^^^^ unsatisfied trait bound introduced here error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr index a08c9912527..6aa8ee13b79 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -23,8 +23,17 @@ LL | let dst = Inline::::new(0); | = note: doesn't satisfy `dyn Debug: Sized` | - = note: the following trait bounds were not satisfied: - `dyn Debug: Sized` +note: trait bound `dyn Debug: Sized` was not satisfied + --> $DIR/issue-80742.rs:20:6 + | +LL | impl Inline + | ^ --------- + | | + | unsatisfied trait bound introduced here +help: consider relaxing the type parameter's implicit `Sized` bound + | +LL | impl Inline + | ++++++++ error[E0080]: evaluation of `Inline::::{constant#0}` failed --> $SRC_DIR/core/src/mem/mod.rs:LL:COL diff --git a/tests/ui/derives/issue-91492.stderr b/tests/ui/derives/issue-91492.stderr index fbd48336d91..cee30ac50a6 100644 --- a/tests/ui/derives/issue-91492.stderr +++ b/tests/ui/derives/issue-91492.stderr @@ -42,8 +42,13 @@ LL | struct Object(T, A); LL | foo.use_clone(); | ^^^^^^^^^ method cannot be called on `Object` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `NoDerives: Clone` +note: trait bound `NoDerives: Clone` was not satisfied + --> $DIR/issue-91492.rs:18:9 + | +LL | impl Object { + | ^^^^^ ------------ + | | + | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Clone)]` | LL | #[derive(Clone)] diff --git a/tests/ui/derives/issue-91550.stderr b/tests/ui/derives/issue-91550.stderr index 12be269565d..e8d67ccb359 100644 --- a/tests/ui/derives/issue-91550.stderr +++ b/tests/ui/derives/issue-91550.stderr @@ -30,8 +30,13 @@ LL | struct Object(T); LL | foo.use_eq(); | ^^^^^^ method cannot be called on `Object` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `NoDerives: Eq` +note: trait bound `NoDerives: Eq` was not satisfied + --> $DIR/issue-91550.rs:15:9 + | +LL | impl Object { + | ^^ --------- + | | + | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]` | LL | #[derive(Eq, PartialEq)] @@ -49,8 +54,13 @@ LL | struct Object(T); LL | foo.use_ord(); | ^^^^^^^ method cannot be called on `Object` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `NoDerives: Ord` +note: trait bound `NoDerives: Ord` was not satisfied + --> $DIR/issue-91550.rs:18:9 + | +LL | impl Object { + | ^^^ --------- + | | + | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | LL | #[derive(Eq, Ord, PartialEq, PartialOrd)] @@ -71,9 +81,20 @@ LL | struct Object(T); 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: Ord` - `NoDerives: PartialOrd` +note: trait bound `NoDerives: Ord` was not satisfied + --> $DIR/issue-91550.rs:21:9 + | +LL | impl Object { + | ^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `NoDerives: PartialOrd` was not satisfied + --> $DIR/issue-91550.rs:21:15 + | +LL | impl Object { + | ^^^^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | LL | #[derive(Eq, Ord, PartialEq, PartialOrd)] diff --git a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs b/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs index 36974b3df5e..83655341d6a 100644 --- a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs +++ b/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs @@ -11,7 +11,7 @@ fn f(&self) {} impl = i32>> M for T {} //~^ NOTE trait bound `::Y = i32` was not satisfied -//~| NOTE unsatisfied trait bound introduced here +//~| NOTE //~| NOTE //~| NOTE diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr index bc342dc4689..d872291c870 100644 --- a/tests/ui/impl-trait/issues/issue-62742.stderr +++ b/tests/ui/impl-trait/issues/issue-62742.stderr @@ -23,8 +23,13 @@ LL | pub struct RawImpl(PhantomData); LL | pub struct SafeImpl>(PhantomData<(A, T)>); | ----------------------------------------- function or associated item `foo` not found for this struct | - = note: the following trait bounds were not satisfied: - `RawImpl<()>: Raw<()>` +note: trait bound `RawImpl<()>: Raw<()>` was not satisfied + --> $DIR/issue-62742.rs:28:20 + | +LL | impl> SafeImpl { + | ^^^^^^ -------------- + | | + | unsatisfied trait bound introduced here note: the trait `Raw` must be implemented --> $DIR/issue-62742.rs:12:1 | diff --git a/tests/ui/methods/method-not-found-generic-arg-elision.stderr b/tests/ui/methods/method-not-found-generic-arg-elision.stderr index 8846efba871..6ec369644a0 100644 --- a/tests/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/tests/ui/methods/method-not-found-generic-arg-elision.stderr @@ -88,9 +88,20 @@ LL | struct Struct { LL | s.method(); | ^^^^^^ method cannot be called on `Struct` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `f64: Eq` - `f64: Ord` +note: trait bound `f64: Eq` was not satisfied + --> $DIR/method-not-found-generic-arg-elision.rs:74:36 + | +LL | impl Struct { + | ^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `f64: Ord` was not satisfied + --> $DIR/method-not-found-generic-arg-elision.rs:74:54 + | +LL | impl Struct { + | ^^^ --------- + | | + | unsatisfied trait bound introduced here error: aborting due to 9 previous errors diff --git a/tests/ui/suggestions/derive-trait-for-method-call.stderr b/tests/ui/suggestions/derive-trait-for-method-call.stderr index 14e8a2675dd..8d5957bd719 100644 --- a/tests/ui/suggestions/derive-trait-for-method-call.stderr +++ b/tests/ui/suggestions/derive-trait-for-method-call.stderr @@ -16,10 +16,27 @@ LL | struct Foo (X, Y); LL | let y = x.test(); | ^^^^ method cannot be called on `Foo` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `Enum: Clone` - `Enum: Default` - `CloneEnum: Default` +note: trait bound `Enum: Clone` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:9 + | +LL | impl Foo { + | ^^^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `Enum: Default` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:17 + | +LL | impl Foo { + | ^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `CloneEnum: Default` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:40 + | +LL | impl Foo { + | ^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here note: the trait `Default` must be implemented --> $SRC_DIR/core/src/default.rs:LL:COL help: consider annotating `Enum` with `#[derive(Clone)]` @@ -45,10 +62,27 @@ LL | struct Foo (X, Y); LL | let y = x.test(); | ^^^^ method cannot be called on `Foo` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `Struct: Clone` - `Struct: Default` - `CloneStruct: Default` +note: trait bound `Struct: Clone` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:9 + | +LL | impl Foo { + | ^^^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `Struct: Default` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:17 + | +LL | impl Foo { + | ^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `CloneStruct: Default` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:40 + | +LL | impl Foo { + | ^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here help: consider annotating `CloneStruct` with `#[derive(Default)]` | LL | #[derive(Default)] @@ -73,9 +107,20 @@ LL | let y = x.test(); | = note: doesn't satisfy `Vec: Clone` | - = note: the following trait bounds were not satisfied: - `Vec: Clone` - `Instant: Default` +note: trait bound `Vec: Clone` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:9 + | +LL | impl Foo { + | ^^^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `Instant: Default` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:40 + | +LL | impl Foo { + | ^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here error: aborting due to 3 previous errors