Skip to content

Commit fb5d215

Browse files
committed
Conserve cause of ImplDerivedObligation in E0599
CC #86377.
1 parent b22c152 commit fb5d215

File tree

10 files changed

+171
-50
lines changed

10 files changed

+171
-50
lines changed

compiler/rustc_hir_typeck/src/method/probe.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,23 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15561556

15571557
// Convert the bounds into obligations.
15581558
let impl_obligations = traits::predicates_for_generics(
1559-
|_, _| cause.clone(),
1559+
|_idx, span| {
1560+
let misc = traits::ObligationCause::misc(span, self.body_id);
1561+
let parent_trait_pred = ty::Binder::dummy(ty::TraitPredicate {
1562+
trait_ref: ty::TraitRef::from_method(self.tcx, impl_def_id, substs),
1563+
constness: ty::BoundConstness::NotConst,
1564+
polarity: ty::ImplPolarity::Positive,
1565+
});
1566+
misc.derived_cause(parent_trait_pred, |derived| {
1567+
traits::ImplDerivedObligation(Box::new(
1568+
traits::ImplDerivedObligationCause {
1569+
derived,
1570+
impl_def_id,
1571+
span,
1572+
},
1573+
))
1574+
})
1575+
},
15601576
self.param_env,
15611577
impl_bounds,
15621578
);

compiler/rustc_hir_typeck/src/method/suggest.rs

+22-19
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
101101
self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
102102
}
103103

104+
#[instrument(level = "debug", skip(self))]
104105
pub fn report_method_error(
105106
&self,
106107
span: Span,
@@ -587,21 +588,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
587588
// Find all the requirements that come from a local `impl` block.
588589
let mut skip_list: FxHashSet<_> = Default::default();
589590
let mut spanned_predicates: FxHashMap<MultiSpan, _> = Default::default();
590-
for (data, p, parent_p, impl_def_id, cause) in unsatisfied_predicates
591+
for (p, parent_p, impl_def_id, cause) in unsatisfied_predicates
591592
.iter()
592593
.filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c)))
593594
.filter_map(|(p, parent, c)| match c.code() {
594-
ObligationCauseCode::ImplDerivedObligation(data) => {
595-
Some((&data.derived, p, parent, data.impl_def_id, data))
595+
ObligationCauseCode::ImplDerivedObligation(data)
596+
if matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) =>
597+
{
598+
Some((p, parent, data.impl_def_id, data))
596599
}
597600
_ => None,
598601
})
599602
{
600-
let parent_trait_ref = data.parent_trait_pred;
601-
let path = parent_trait_ref.print_modifiers_and_trait_path();
602-
let tr_self_ty = parent_trait_ref.skip_binder().self_ty();
603-
let unsatisfied_msg = "unsatisfied trait bound introduced here";
604-
let derive_msg = "unsatisfied trait bound introduced in this `derive` macro";
605603
match self.tcx.hir().get_if_local(impl_def_id) {
606604
// Unmet obligation comes from a `derive` macro, point at it once to
607605
// avoid multiple span labels pointing at the same place.
@@ -618,9 +616,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
618616
{
619617
let span = self_ty.span.ctxt().outer_expn_data().call_site;
620618
let mut spans: MultiSpan = span.into();
621-
spans.push_span_label(span, derive_msg);
619+
spans.push_span_label(
620+
span,
621+
"unsatisfied trait bound introduced in this `derive` macro",
622+
);
622623
let entry = spanned_predicates.entry(spans);
623-
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
624+
entry.or_insert_with(|| Vec::new()).push(p);
624625
}
625626

626627
// Unmet obligation coming from an `impl`.
@@ -647,8 +648,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
647648
};
648649
err.span_suggestion_verbose(
649650
sp,
650-
"consider relaxing the type parameter's implicit \
651-
`Sized` bound",
651+
"consider relaxing the type parameter's implicit `Sized` bound",
652652
sugg,
653653
Applicability::MachineApplicable,
654654
);
@@ -661,7 +661,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
661661
skip_list.insert(p);
662662
let mut spans = if cause.span != *item_span {
663663
let mut spans: MultiSpan = cause.span.into();
664-
spans.push_span_label(cause.span, unsatisfied_msg);
664+
spans.push_span_label(
665+
cause.span,
666+
"unsatisfied trait bound introduced here",
667+
);
665668
spans
666669
} else {
667670
let mut spans = Vec::with_capacity(2);
@@ -677,7 +680,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
677680
spans.push_span_label(self_ty.span, "");
678681

679682
let entry = spanned_predicates.entry(spans);
680-
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
683+
entry.or_insert_with(|| Vec::new()).push(p);
681684
}
682685
Some(Node::Item(hir::Item {
683686
kind: hir::ItemKind::Trait(rustc_ast::ast::IsAuto::Yes, ..),
@@ -694,11 +697,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
694697
}
695698
}
696699
let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect();
697-
spanned_predicates.sort_by_key(|(span, (_, _, _))| span.primary_span());
698-
for (span, (_path, _self_ty, preds)) in spanned_predicates {
699-
let mut preds: Vec<_> = preds
700-
.into_iter()
701-
.filter_map(|pred| format_pred(*pred))
700+
spanned_predicates.sort_by_key(|(span, _)| span.primary_span());
701+
for (span, predicates) in spanned_predicates {
702+
let mut preds: Vec<_> = predicates
703+
.iter()
704+
.filter_map(|pred| format_pred(**pred))
702705
.map(|(p, _)| format!("`{}`", p))
703706
.collect();
704707
preds.sort();

tests/ui/const-generics/generic_const_exprs/issue-69654.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,14 @@ LL | struct Foo<const N: usize> {}
1515
LL | Foo::foo();
1616
| ^^^ function or associated item cannot be called on `Foo<_>` due to unsatisfied trait bounds
1717
|
18-
= note: the following trait bounds were not satisfied:
19-
`[u8; _]: Bar<[(); _]>`
18+
note: trait bound `[u8; _]: Bar<[(); _]>` was not satisfied
19+
--> $DIR/issue-69654.rs:11:14
20+
|
21+
LL | impl<const N: usize> Foo<N>
22+
| ------
23+
LL | where
24+
LL | [u8; N]: Bar<[(); N]>,
25+
| ^^^^^^^^^^^^ unsatisfied trait bound introduced here
2026

2127
error: aborting due to 2 previous errors
2228

tests/ui/const-generics/generic_const_exprs/issue-80742.stderr

+11-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,17 @@ LL | let dst = Inline::<dyn Debug>::new(0);
2323
|
2424
= note: doesn't satisfy `dyn Debug: Sized`
2525
|
26-
= note: the following trait bounds were not satisfied:
27-
`dyn Debug: Sized`
26+
note: trait bound `dyn Debug: Sized` was not satisfied
27+
--> $DIR/issue-80742.rs:20:6
28+
|
29+
LL | impl<T> Inline<T>
30+
| ^ ---------
31+
| |
32+
| unsatisfied trait bound introduced here
33+
help: consider relaxing the type parameter's implicit `Sized` bound
34+
|
35+
LL | impl<T: ?Sized> Inline<T>
36+
| ++++++++
2837

2938
error[E0080]: evaluation of `Inline::<dyn std::fmt::Debug>::{constant#0}` failed
3039
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL

tests/ui/derives/issue-91492.stderr

+7-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,13 @@ LL | struct Object<T, A>(T, A);
4242
LL | foo.use_clone();
4343
| ^^^^^^^^^ method cannot be called on `Object<NoDerives, SomeDerives>` due to unsatisfied trait bounds
4444
|
45-
= note: the following trait bounds were not satisfied:
46-
`NoDerives: Clone`
45+
note: trait bound `NoDerives: Clone` was not satisfied
46+
--> $DIR/issue-91492.rs:18:9
47+
|
48+
LL | impl<T: Clone, A: Default> Object<T, A> {
49+
| ^^^^^ ------------
50+
| |
51+
| unsatisfied trait bound introduced here
4752
help: consider annotating `NoDerives` with `#[derive(Clone)]`
4853
|
4954
LL | #[derive(Clone)]

tests/ui/derives/issue-91550.stderr

+28-7
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,13 @@ LL | struct Object<T>(T);
3030
LL | foo.use_eq();
3131
| ^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
3232
|
33-
= note: the following trait bounds were not satisfied:
34-
`NoDerives: Eq`
33+
note: trait bound `NoDerives: Eq` was not satisfied
34+
--> $DIR/issue-91550.rs:15:9
35+
|
36+
LL | impl<T: Eq> Object<T> {
37+
| ^^ ---------
38+
| |
39+
| unsatisfied trait bound introduced here
3540
help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]`
3641
|
3742
LL | #[derive(Eq, PartialEq)]
@@ -49,8 +54,13 @@ LL | struct Object<T>(T);
4954
LL | foo.use_ord();
5055
| ^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
5156
|
52-
= note: the following trait bounds were not satisfied:
53-
`NoDerives: Ord`
57+
note: trait bound `NoDerives: Ord` was not satisfied
58+
--> $DIR/issue-91550.rs:18:9
59+
|
60+
LL | impl<T: Ord> Object<T> {
61+
| ^^^ ---------
62+
| |
63+
| unsatisfied trait bound introduced here
5464
help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
5565
|
5666
LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]
@@ -71,9 +81,20 @@ LL | struct Object<T>(T);
7181
LL | foo.use_ord_and_partial_ord();
7282
| ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
7383
|
74-
= note: the following trait bounds were not satisfied:
75-
`NoDerives: Ord`
76-
`NoDerives: PartialOrd`
84+
note: trait bound `NoDerives: Ord` was not satisfied
85+
--> $DIR/issue-91550.rs:21:9
86+
|
87+
LL | impl<T: Ord + PartialOrd> Object<T> {
88+
| ^^^ ---------
89+
| |
90+
| unsatisfied trait bound introduced here
91+
note: trait bound `NoDerives: PartialOrd` was not satisfied
92+
--> $DIR/issue-91550.rs:21:15
93+
|
94+
LL | impl<T: Ord + PartialOrd> Object<T> {
95+
| ^^^^^^^^^^ ---------
96+
| |
97+
| unsatisfied trait bound introduced here
7798
help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
7899
|
79100
LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]

tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ trait M {
1111

1212
impl<T: X<Y<i32> = i32>> M for T {}
1313
//~^ NOTE trait bound `<S as X>::Y<i32> = i32` was not satisfied
14-
//~| NOTE unsatisfied trait bound introduced here
14+
//~| NOTE
1515
//~| NOTE
1616
//~| NOTE
1717

tests/ui/impl-trait/issues/issue-62742.stderr

+7-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,13 @@ LL | pub struct RawImpl<T>(PhantomData<T>);
2323
LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
2424
| ----------------------------------------- function or associated item `foo` not found for this struct
2525
|
26-
= note: the following trait bounds were not satisfied:
27-
`RawImpl<()>: Raw<()>`
26+
note: trait bound `RawImpl<()>: Raw<()>` was not satisfied
27+
--> $DIR/issue-62742.rs:28:20
28+
|
29+
LL | impl<T: ?Sized, A: Raw<T>> SafeImpl<T, A> {
30+
| ^^^^^^ --------------
31+
| |
32+
| unsatisfied trait bound introduced here
2833
note: the trait `Raw` must be implemented
2934
--> $DIR/issue-62742.rs:12:1
3035
|

tests/ui/methods/method-not-found-generic-arg-elision.stderr

+14-3
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,20 @@ LL | struct Struct<T> {
8888
LL | s.method();
8989
| ^^^^^^ method cannot be called on `Struct<f64>` due to unsatisfied trait bounds
9090
|
91-
= note: the following trait bounds were not satisfied:
92-
`f64: Eq`
93-
`f64: Ord`
91+
note: trait bound `f64: Eq` was not satisfied
92+
--> $DIR/method-not-found-generic-arg-elision.rs:74:36
93+
|
94+
LL | impl<T: Clone + Copy + PartialEq + Eq + PartialOrd + Ord> Struct<T> {
95+
| ^^ ---------
96+
| |
97+
| unsatisfied trait bound introduced here
98+
note: trait bound `f64: Ord` was not satisfied
99+
--> $DIR/method-not-found-generic-arg-elision.rs:74:54
100+
|
101+
LL | impl<T: Clone + Copy + PartialEq + Eq + PartialOrd + Ord> Struct<T> {
102+
| ^^^ ---------
103+
| |
104+
| unsatisfied trait bound introduced here
94105

95106
error: aborting due to 9 previous errors
96107

tests/ui/suggestions/derive-trait-for-method-call.stderr

+56-11
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,27 @@ LL | struct Foo<X, Y> (X, Y);
1616
LL | let y = x.test();
1717
| ^^^^ method cannot be called on `Foo<Enum, CloneEnum>` due to unsatisfied trait bounds
1818
|
19-
= note: the following trait bounds were not satisfied:
20-
`Enum: Clone`
21-
`Enum: Default`
22-
`CloneEnum: Default`
19+
note: trait bound `Enum: Clone` was not satisfied
20+
--> $DIR/derive-trait-for-method-call.rs:20:9
21+
|
22+
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
23+
| ^^^^^ ---------
24+
| |
25+
| unsatisfied trait bound introduced here
26+
note: trait bound `Enum: Default` was not satisfied
27+
--> $DIR/derive-trait-for-method-call.rs:20:17
28+
|
29+
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
30+
| ^^^^^^^ ---------
31+
| |
32+
| unsatisfied trait bound introduced here
33+
note: trait bound `CloneEnum: Default` was not satisfied
34+
--> $DIR/derive-trait-for-method-call.rs:20:40
35+
|
36+
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
37+
| ^^^^^^^ ---------
38+
| |
39+
| unsatisfied trait bound introduced here
2340
note: the trait `Default` must be implemented
2441
--> $SRC_DIR/core/src/default.rs:LL:COL
2542
help: consider annotating `Enum` with `#[derive(Clone)]`
@@ -45,10 +62,27 @@ LL | struct Foo<X, Y> (X, Y);
4562
LL | let y = x.test();
4663
| ^^^^ method cannot be called on `Foo<Struct, CloneStruct>` due to unsatisfied trait bounds
4764
|
48-
= note: the following trait bounds were not satisfied:
49-
`Struct: Clone`
50-
`Struct: Default`
51-
`CloneStruct: Default`
65+
note: trait bound `Struct: Clone` was not satisfied
66+
--> $DIR/derive-trait-for-method-call.rs:20:9
67+
|
68+
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
69+
| ^^^^^ ---------
70+
| |
71+
| unsatisfied trait bound introduced here
72+
note: trait bound `Struct: Default` was not satisfied
73+
--> $DIR/derive-trait-for-method-call.rs:20:17
74+
|
75+
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
76+
| ^^^^^^^ ---------
77+
| |
78+
| unsatisfied trait bound introduced here
79+
note: trait bound `CloneStruct: Default` was not satisfied
80+
--> $DIR/derive-trait-for-method-call.rs:20:40
81+
|
82+
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
83+
| ^^^^^^^ ---------
84+
| |
85+
| unsatisfied trait bound introduced here
5286
help: consider annotating `CloneStruct` with `#[derive(Default)]`
5387
|
5488
LL | #[derive(Default)]
@@ -73,9 +107,20 @@ LL | let y = x.test();
73107
|
74108
= note: doesn't satisfy `Vec<Enum>: Clone`
75109
|
76-
= note: the following trait bounds were not satisfied:
77-
`Vec<Enum>: Clone`
78-
`Instant: Default`
110+
note: trait bound `Vec<Enum>: Clone` was not satisfied
111+
--> $DIR/derive-trait-for-method-call.rs:20:9
112+
|
113+
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
114+
| ^^^^^ ---------
115+
| |
116+
| unsatisfied trait bound introduced here
117+
note: trait bound `Instant: Default` was not satisfied
118+
--> $DIR/derive-trait-for-method-call.rs:20:40
119+
|
120+
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
121+
| ^^^^^^^ ---------
122+
| |
123+
| unsatisfied trait bound introduced here
79124

80125
error: aborting due to 3 previous errors
81126

0 commit comments

Comments
 (0)