1
Fork 0

Keep obligation chain when elaborating obligations

This commit is contained in:
Esteban Küber 2023-01-12 21:32:06 +00:00
parent f6e6d2a035
commit 3d6b09e53e
6 changed files with 59 additions and 14 deletions

View file

@ -692,7 +692,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"auto trait is invoked with no method error, but no error reported?", "auto trait is invoked with no method error, but no error reported?",
); );
} }
Some(_) => unreachable!(), Some(Node::Item(hir::Item {
ident, kind: hir::ItemKind::Trait(..), ..
})) => {
skip_list.insert(p);
let entry = spanned_predicates.entry(ident.span);
let entry = entry.or_insert_with(|| {
(FxHashSet::default(), FxHashSet::default(), Vec::new())
});
entry.0.insert(cause.span);
entry.1.insert((ident.span, ""));
entry.1.insert((cause.span, "unsatisfied trait bound introduced here"));
entry.2.push(p);
}
Some(node) => unreachable!("encountered `{node:?}`"),
None => (), None => (),
} }
} }

View file

@ -1,7 +1,7 @@
use smallvec::smallvec; use smallvec::smallvec;
use crate::infer::outlives::components::{push_outlives_components, Component}; use crate::infer::outlives::components::{push_outlives_components, Component};
use crate::traits::{Obligation, ObligationCause, PredicateObligation}; use crate::traits::{self, Obligation, ObligationCause, PredicateObligation};
use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_middle::ty::{self, ToPredicate, TyCtxt}; use rustc_middle::ty::{self, ToPredicate, TyCtxt};
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
@ -145,16 +145,28 @@ impl<'tcx> Elaborator<'tcx> {
// Get predicates declared on the trait. // Get predicates declared on the trait.
let predicates = tcx.super_predicates_of(data.def_id()); let predicates = tcx.super_predicates_of(data.def_id());
let obligations = predicates.predicates.iter().map(|&(mut pred, _)| { let obligations = predicates.predicates.iter().map(|&(mut pred, span)| {
// when parent predicate is non-const, elaborate it to non-const predicates. // when parent predicate is non-const, elaborate it to non-const predicates.
if data.constness == ty::BoundConstness::NotConst { if data.constness == ty::BoundConstness::NotConst {
pred = pred.without_const(tcx); pred = pred.without_const(tcx);
} }
let cause = obligation.cause.clone().derived_cause(
bound_predicate.rebind(data),
|derived| {
traits::ImplDerivedObligation(Box::new(
traits::ImplDerivedObligationCause {
derived,
impl_def_id: data.def_id(),
span,
},
))
},
);
predicate_obligation( predicate_obligation(
pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)), pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
obligation.param_env, obligation.param_env,
obligation.cause.clone(), cause,
) )
}); });
debug!(?data, ?obligations, "super_predicates"); debug!(?data, ?obligations, "super_predicates");

View file

@ -4,6 +4,11 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
LL | type Assoc = T; LL | type Assoc = T;
| ^ the trait `Copy` is not implemented for `T` | ^ the trait `Copy` is not implemented for `T`
| |
note: required for `<T as Complete>::Assoc` to implement `Partial<T>`
--> $DIR/issue-43784-associated-type.rs:1:11
|
LL | pub trait Partial<X: ?Sized>: Copy {
| ^^^^^^^
note: required by a bound in `Complete::Assoc` note: required by a bound in `Complete::Assoc`
--> $DIR/issue-43784-associated-type.rs:5:17 --> $DIR/issue-43784-associated-type.rs:5:17
| |

View file

@ -36,15 +36,16 @@ LL | struct Object<T>(T);
LL | foo.use_eq(); LL | foo.use_eq();
| ^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds | ^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
| |
note: the following trait bounds were not satisfied: note: trait bound `NoDerives: Eq` was not satisfied
`NoDerives: Eq`
`NoDerives: PartialEq`
--> $DIR/issue-91550.rs:15:9 --> $DIR/issue-91550.rs:15:9
| |
LL | impl<T: Eq> Object<T> { LL | impl<T: Eq> Object<T> {
| ^^ --------- | ^^ ---------
| | | |
| unsatisfied trait bound introduced here | unsatisfied trait bound introduced here
= note: the following trait bounds were not satisfied:
`NoDerives: PartialEq`
which is required by `NoDerives: Eq`
help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]` help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]`
| |
LL | #[derive(Eq, PartialEq)] LL | #[derive(Eq, PartialEq)]
@ -67,17 +68,20 @@ LL | struct Object<T>(T);
LL | foo.use_ord(); LL | foo.use_ord();
| ^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds | ^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
| |
note: the following trait bounds were not satisfied: note: trait bound `NoDerives: Ord` was not satisfied
`NoDerives: Eq`
`NoDerives: Ord`
`NoDerives: PartialEq`
`NoDerives: PartialOrd`
--> $DIR/issue-91550.rs:18:9 --> $DIR/issue-91550.rs:18:9
| |
LL | impl<T: Ord> Object<T> { LL | impl<T: Ord> Object<T> {
| ^^^ --------- | ^^^ ---------
| | | |
| unsatisfied trait bound introduced here | unsatisfied trait bound introduced here
= note: the following trait bounds were not satisfied:
`NoDerives: PartialOrd`
which is required by `NoDerives: Ord`
`NoDerives: PartialEq`
which is required by `NoDerives: Ord`
`NoDerives: Eq`
which is required by `NoDerives: Ord`
help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
| |
LL | #[derive(Eq, Ord, PartialEq, PartialOrd)] LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]
@ -101,9 +105,7 @@ LL | foo.use_ord_and_partial_ord();
| ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds | ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
| |
note: the following trait bounds were not satisfied: note: the following trait bounds were not satisfied:
`NoDerives: Eq`
`NoDerives: Ord` `NoDerives: Ord`
`NoDerives: PartialEq`
`NoDerives: PartialOrd` `NoDerives: PartialOrd`
--> $DIR/issue-91550.rs:21:9 --> $DIR/issue-91550.rs:21:9
| |
@ -112,6 +114,13 @@ LL | impl<T: Ord + PartialOrd> Object<T> {
| | | | | |
| | unsatisfied trait bound introduced here | | unsatisfied trait bound introduced here
| unsatisfied trait bound introduced here | unsatisfied trait bound introduced here
= note: the following trait bounds were not satisfied:
`NoDerives: PartialEq`
which is required by `NoDerives: Ord`
`NoDerives: Eq`
which is required by `NoDerives: Ord`
`NoDerives: PartialEq`
which is required by `NoDerives: PartialOrd`
help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
| |
LL | #[derive(Eq, Ord, PartialEq, PartialOrd)] LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]

View file

@ -17,6 +17,7 @@ LL | type Copy<T>: Copy = Box<T>;
| ^^^^^^ the trait `Clone` is not implemented for `T` | ^^^^^^ the trait `Clone` is not implemented for `T`
| |
= note: required for `Box<T>` to implement `Clone` = note: required for `Box<T>` to implement `Clone`
= note: required for `<Self as UnsafeCopy>::Copy<T>` to implement `Copy`
note: required by a bound in `UnsafeCopy::Copy` note: required by a bound in `UnsafeCopy::Copy`
--> $DIR/issue-74824.rs:6:19 --> $DIR/issue-74824.rs:6:19
| |

View file

@ -4,6 +4,11 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
LL | impl<T> Complete for T {} LL | impl<T> Complete for T {}
| ^ the trait `Copy` is not implemented for `T` | ^ the trait `Copy` is not implemented for `T`
| |
note: required for `T` to implement `Partial`
--> $DIR/issue-43784-supertrait.rs:1:11
|
LL | pub trait Partial: Copy {
| ^^^^^^^
note: required by a bound in `Complete` note: required by a bound in `Complete`
--> $DIR/issue-43784-supertrait.rs:4:21 --> $DIR/issue-43784-supertrait.rs:4:21
| |