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;
|
||||
};
|
||||
for obligation in obligations {
|
||||
debug!(?obligation);
|
||||
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::ClauseKind::RegionOutlives(..) | ty::ClauseKind::TypeOutlives(..),
|
||||
ty::ClauseKind::RegionOutlives(..)
|
||||
| ty::ClauseKind::TypeOutlives(..)
|
||||
| ty::ClauseKind::Projection(..),
|
||||
) => ocx.register_obligation(obligation),
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(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