Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conserve cause of ImplDerivedObligation in E0599 #106702

Merged
merged 2 commits into from
Jan 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1556,7 +1556,23 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {

// 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),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should've caught this when reviewing this, but this is not correct. We cannot construct a trait ref out of an impl def id and impl substs, and it's not meaningful to even use tcx.impl_trait_ref(impl_def_id).subst(self.tcx, substs) here because this is an inherent impl by construction.

I fixed this in #110133

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,
);
Expand Down
73 changes: 40 additions & 33 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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,
Expand Down Expand Up @@ -586,22 +587,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Find all the requirements that come from a local `impl` block.
let mut skip_list: FxHashSet<_> = Default::default();
let mut spanned_predicates: FxHashMap<MultiSpan, _> = Default::default();
for (data, p, parent_p, impl_def_id, cause) in unsatisfied_predicates
let mut spanned_predicates = FxHashMap::default();
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.
Expand All @@ -617,10 +615,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) =>
{
let span = self_ty.span.ctxt().outer_expn_data().call_site;
let mut spans: MultiSpan = span.into();
spans.push_span_label(span, derive_msg);
let entry = spanned_predicates.entry(spans);
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
let entry = spanned_predicates.entry(span);
let entry = entry.or_insert_with(|| {
(FxHashSet::default(), FxHashSet::default(), Vec::new())
});
entry.0.insert(span);
entry.1.insert((
span,
"unsatisfied trait bound introduced in this `derive` macro",
));
entry.2.push(p);
skip_list.insert(p);
}

// Unmet obligation coming from an `impl`.
Expand All @@ -647,8 +652,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
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,
);
Expand All @@ -659,25 +663,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let _ = format_pred(*pred);
}
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
let entry = spanned_predicates.entry(self_ty.span);
let entry = entry.or_insert_with(|| {
(FxHashSet::default(), FxHashSet::default(), Vec::new())
});
entry.2.push(p);
if cause.span != *item_span {
entry.0.insert(cause.span);
entry.1.insert((cause.span, "unsatisfied trait bound introduced here"));
} else {
let mut spans = Vec::with_capacity(2);
if let Some(trait_ref) = of_trait {
spans.push(trait_ref.path.span);
entry.0.insert(trait_ref.path.span);
}
spans.push(self_ty.span);
spans.into()
entry.0.insert(self_ty.span);
};
if let Some(trait_ref) = of_trait {
spans.push_span_label(trait_ref.path.span, "");
entry.1.insert((trait_ref.path.span, ""));
}
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.1.insert((self_ty.span, ""));
}
Some(Node::Item(hir::Item {
kind: hir::ItemKind::Trait(rustc_ast::ast::IsAuto::Yes, ..),
Expand All @@ -694,11 +697,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
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);
for (_, (primary_spans, span_labels, predicates)) in spanned_predicates {
let mut preds: Vec<_> = predicates
.iter()
.filter_map(|pred| format_pred(**pred))
.map(|(p, _)| format!("`{}`", p))
.collect();
preds.sort();
Expand All @@ -708,6 +711,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
format!("the following trait bounds were not satisfied:\n{}", preds.join("\n"),)
};
let mut span: MultiSpan = primary_spans.into_iter().collect::<Vec<_>>().into();
for (sp, label) in span_labels {
span.push_span_label(sp, label);
}
err.span_note(span, &msg);
unsatisfied_bounds = true;
}
Expand Down
10 changes: 8 additions & 2 deletions tests/ui/const-generics/generic_const_exprs/issue-69654.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@ LL | struct Foo<const N: usize> {}
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<const N: usize> Foo<N>
| ------
LL | where
LL | [u8; N]: Bar<[(); N]>,
| ^^^^^^^^^^^^ unsatisfied trait bound introduced here

error: aborting due to 2 previous errors

Expand Down
13 changes: 11 additions & 2 deletions tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,17 @@ LL | let dst = Inline::<dyn Debug>::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<T> Inline<T>
| ^ ---------
| |
| unsatisfied trait bound introduced here
help: consider relaxing the type parameter's implicit `Sized` bound
|
LL | impl<T: ?Sized> Inline<T>
| ++++++++

error[E0080]: evaluation of `Inline::<dyn std::fmt::Debug>::{constant#0}` failed
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
Expand Down
3 changes: 0 additions & 3 deletions tests/ui/derives/derive-assoc-type-not-impl.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ note: trait bound `NotClone: Clone` was not satisfied
|
LL | #[derive(Clone)]
| ^^^^^ unsatisfied trait bound introduced in this `derive` macro
= note: the following trait bounds were not satisfied:
`NotClone: Clone`
which is required by `Bar<NotClone>: Clone`
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `clone`, perhaps you need to implement it:
candidate #1: `Clone`
Expand Down
9 changes: 7 additions & 2 deletions tests/ui/derives/issue-91492.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,13 @@ LL | struct Object<T, A>(T, A);
LL | foo.use_clone();
| ^^^^^^^^^ method cannot be called on `Object<NoDerives, SomeDerives>` 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<T: Clone, A: Default> Object<T, A> {
| ^^^^^ ------------
| |
| unsatisfied trait bound introduced here
help: consider annotating `NoDerives` with `#[derive(Clone)]`
|
LL | #[derive(Clone)]
Expand Down
31 changes: 24 additions & 7 deletions tests/ui/derives/issue-91550.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ 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`
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
help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]`
|
LL | #[derive(Eq, PartialEq)]
Expand All @@ -49,8 +54,13 @@ 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: Ord`
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
help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
|
LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]
Expand All @@ -71,9 +81,16 @@ LL | struct Object<T>(T);
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: Ord`
`NoDerives: PartialOrd`
note: the following trait bounds were not satisfied:
`NoDerives: Ord`
`NoDerives: PartialOrd`
--> $DIR/issue-91550.rs:21:9
|
LL | impl<T: Ord + PartialOrd> Object<T> {
| ^^^ ^^^^^^^^^^ ---------
| | |
| | unsatisfied trait bound introduced here
| unsatisfied trait bound introduced here
help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
|
LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ trait M {

impl<T: X<Y<i32> = i32>> M for T {}
//~^ NOTE trait bound `<S as X>::Y<i32> = i32` was not satisfied
//~| NOTE unsatisfied trait bound introduced here
//~| NOTE
//~| NOTE
//~| NOTE

Expand Down
9 changes: 7 additions & 2 deletions tests/ui/impl-trait/issues/issue-62742.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@ LL | pub struct RawImpl<T>(PhantomData<T>);
LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(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<T: ?Sized, A: Raw<T>> SafeImpl<T, A> {
| ^^^^^^ --------------
| |
| unsatisfied trait bound introduced here
note: the trait `Raw` must be implemented
--> $DIR/issue-62742.rs:12:1
|
Expand Down
13 changes: 10 additions & 3 deletions tests/ui/methods/method-not-found-generic-arg-elision.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,16 @@ LL | struct Struct<T> {
LL | s.method();
| ^^^^^^ method cannot be called on `Struct<f64>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`f64: Eq`
`f64: Ord`
note: the following trait bounds were not satisfied:
`f64: Eq`
`f64: Ord`
--> $DIR/method-not-found-generic-arg-elision.rs:74:36
|
LL | impl<T: Clone + Copy + PartialEq + Eq + PartialOrd + Ord> Struct<T> {
| ^^ ^^^ ---------
| | |
| | unsatisfied trait bound introduced here
| unsatisfied trait bound introduced here

error: aborting due to 9 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,16 @@ LL | struct Foo<T> {
LL | self.foo();
| ^^^ method cannot be called on `&Foo<T>` due to unsatisfied trait bounds
|
note: trait bound `T: Default` was not satisfied
note: the following trait bounds were not satisfied:
`T: Bar`
`T: Default`
--> $DIR/missing-trait-bounds-for-method-call.rs:10:9
|
LL | impl<T: Default + Bar> Bar for Foo<T> {}
| ^^^^^^^ --- ------
| |
| ^^^^^^^ ^^^ --- ------
| | |
| | unsatisfied trait bound introduced here
| unsatisfied trait bound introduced here
note: trait bound `T: Bar` was not satisfied
--> $DIR/missing-trait-bounds-for-method-call.rs:10:19
|
LL | impl<T: Default + Bar> Bar for Foo<T> {}
| ^^^ --- ------
| |
| unsatisfied trait bound introduced here
help: consider restricting the type parameters to satisfy the trait bounds
|
LL | struct Foo<T> where T: Bar, T: Default {
Expand Down
Loading