mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Rollup merge of #106702 - estebank:trait-bounds, r=compiler-errors
Conserve cause of `ImplDerivedObligation` in E0599 CC #86377.
This commit is contained in:
commit
8a13157c16
@ -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),
|
||||
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,
|
||||
);
|
||||
|
@ -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,
|
||||
@ -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.
|
||||
@ -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`.
|
||||
@ -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,
|
||||
);
|
||||
@ -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, ..),
|
||||
@ -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();
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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`
|
||||
|
@ -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)]
|
||||
|
@ -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)]
|
||||
@ -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)]
|
||||
@ -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)]
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -16,10 +16,18 @@ LL | struct Foo<X, Y> (X, Y);
|
||||
LL | let y = x.test();
|
||||
| ^^^^ method cannot be called on `Foo<Enum, CloneEnum>` due to unsatisfied trait bounds
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`Enum: Clone`
|
||||
`Enum: Default`
|
||||
`CloneEnum: Default`
|
||||
note: the following trait bounds were not satisfied:
|
||||
`CloneEnum: Default`
|
||||
`Enum: Clone`
|
||||
`Enum: Default`
|
||||
--> $DIR/derive-trait-for-method-call.rs:20:9
|
||||
|
|
||||
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
|
||||
| ^^^^^ ^^^^^^^ ^^^^^^^ ---------
|
||||
| | | |
|
||||
| | | unsatisfied trait bound introduced here
|
||||
| | unsatisfied trait bound introduced here
|
||||
| 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 +53,18 @@ LL | struct Foo<X, Y> (X, Y);
|
||||
LL | let y = x.test();
|
||||
| ^^^^ method cannot be called on `Foo<Struct, CloneStruct>` due to unsatisfied trait bounds
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`Struct: Clone`
|
||||
`Struct: Default`
|
||||
`CloneStruct: Default`
|
||||
note: the following trait bounds were not satisfied:
|
||||
`CloneStruct: Default`
|
||||
`Struct: Clone`
|
||||
`Struct: Default`
|
||||
--> $DIR/derive-trait-for-method-call.rs:20:9
|
||||
|
|
||||
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
|
||||
| ^^^^^ ^^^^^^^ ^^^^^^^ ---------
|
||||
| | | |
|
||||
| | | unsatisfied trait bound introduced here
|
||||
| | unsatisfied trait bound introduced here
|
||||
| unsatisfied trait bound introduced here
|
||||
help: consider annotating `CloneStruct` with `#[derive(Default)]`
|
||||
|
|
||||
LL | #[derive(Default)]
|
||||
@ -73,9 +89,16 @@ LL | let y = x.test();
|
||||
|
|
||||
= note: doesn't satisfy `Vec<Enum>: Clone`
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`Vec<Enum>: Clone`
|
||||
`Instant: Default`
|
||||
note: the following trait bounds were not satisfied:
|
||||
`Instant: Default`
|
||||
`Vec<Enum>: Clone`
|
||||
--> $DIR/derive-trait-for-method-call.rs:20:9
|
||||
|
|
||||
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
|
||||
| ^^^^^ ^^^^^^^ ---------
|
||||
| | |
|
||||
| | unsatisfied trait bound introduced here
|
||||
| unsatisfied trait bound introduced here
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -32,9 +32,6 @@ note: trait bound `CloneNoCopy: Copy` was not satisfied
|
||||
|
|
||||
LL | #[derive(Clone, Copy)]
|
||||
| ^^^^^ unsatisfied trait bound introduced in this `derive` macro
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`CloneNoCopy: Copy`
|
||||
which is required by `U5<CloneNoCopy>: Clone`
|
||||
help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]`
|
||||
|
|
||||
LL | #[derive(Clone, Copy)]
|
||||
|
@ -32,9 +32,6 @@ note: trait bound `CloneNoCopy: Copy` was not satisfied
|
||||
|
|
||||
LL | #[derive(Clone, Copy)]
|
||||
| ^^^^^ unsatisfied trait bound introduced in this `derive` macro
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`CloneNoCopy: Copy`
|
||||
which is required by `U5<CloneNoCopy>: Clone`
|
||||
help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]`
|
||||
|
|
||||
LL | #[derive(Clone, Copy)]
|
||||
|
Loading…
Reference in New Issue
Block a user