Auto merge of #115039 - jackh726:impl_compare_add_alias_obligations, r=aliemjay
Add projection obligations when comparing impl too Fixes #115033 In the test, when we ask for WF obligations of `DatasetIter<'a, ArrayBase<D>>`, we get back two important obligations: `[<D as Data>::Elem -> ?1, ?1: 'a]`. If we don't add the projection obligation, `?1` remains unconstrained. An alternative solution would be to use unnormalized obligations, where we only have one relevant obligation: `<D as Data>::Elem: 'a`. This would leave no inference vars unconstrained.
This commit is contained in:
commit
fe5f591257
@ -342,9 +342,16 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
for obligation in obligations {
|
for obligation in obligations {
|
||||||
|
debug!(?obligation);
|
||||||
match obligation.predicate.kind().skip_binder() {
|
match obligation.predicate.kind().skip_binder() {
|
||||||
|
// We need to register Projection oblgiations too, because we may end up with
|
||||||
|
// an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
|
||||||
|
// If we only register the region outlives obligation, this leads to an unconstrained var.
|
||||||
|
// See `implied_bounds_entailment_alias_var` test.
|
||||||
ty::PredicateKind::Clause(
|
ty::PredicateKind::Clause(
|
||||||
ty::ClauseKind::RegionOutlives(..) | ty::ClauseKind::TypeOutlives(..),
|
ty::ClauseKind::RegionOutlives(..)
|
||||||
|
| ty::ClauseKind::TypeOutlives(..)
|
||||||
|
| ty::ClauseKind::Projection(..),
|
||||||
) => ocx.register_obligation(obligation),
|
) => ocx.register_obligation(obligation),
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
|
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
|
||||||
if wf_args_seen.insert(arg) {
|
if wf_args_seen.insert(arg) {
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
trait Data {
|
||||||
|
type Elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, S: Data<Elem = F>> Data for ArrayBase<S> {
|
||||||
|
type Elem = F;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DatasetIter<'a, R: Data> {
|
||||||
|
data: &'a R::Elem,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ArrayBase<S> {
|
||||||
|
data: S,
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
type Item;
|
||||||
|
fn next() -> Option<Self::Item>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, D: Data> Trait for DatasetIter<'a, ArrayBase<D>> {
|
||||||
|
type Item = ();
|
||||||
|
|
||||||
|
fn next() -> Option<Self::Item> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue
Block a user