Avoid cycles from projection bounds

Only check the own predicates of associated types when confirming
projection candidates.
Also consider implied bounds when comparing trait and impl methods.
This commit is contained in:
Matthew Jasper 2020-07-25 13:41:53 +01:00
parent 596d6c4b3b
commit 0dfa6ff3be
11 changed files with 122 additions and 85 deletions

View file

@ -157,22 +157,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
);
}),
);
// Require that the projection is well-formed.
let self_ty = self.infcx.replace_bound_vars_with_placeholders(&bound_self_ty);
let self_ty = normalize_with_depth_to(
self,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
&self_ty,
&mut obligations,
);
obligations.push(Obligation::with_depth(
obligation.cause.clone(),
obligation.recursion_depth + 1,
obligation.param_env,
ty::PredicateKind::WellFormed(self_ty.into()).to_predicate(tcx),
));
if let ty::Projection(..) = bound_self_ty.skip_binder().kind {
for predicate in tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates {
let normalized = normalize_with_depth_to(
self,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
&predicate,
&mut obligations,
);
obligations.push(Obligation::with_depth(
obligation.cause.clone(),
obligation.recursion_depth + 1,
obligation.param_env,
normalized,
));
}
}
obligations
})
}