1
Fork 0

Make projection wf check the predicates for the projection

This commit is contained in:
Matthew Jasper 2020-06-28 10:51:32 +01:00
parent f958e6c246
commit 87f2f42dc2

View file

@ -327,17 +327,31 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
/// Pushes the obligations required for `trait_ref::Item` to be WF /// Pushes the obligations required for `trait_ref::Item` to be WF
/// into `self.out`. /// into `self.out`.
fn compute_projection(&mut self, data: ty::ProjectionTy<'tcx>) { fn compute_projection(&mut self, data: ty::ProjectionTy<'tcx>) {
// A projection is well-formed if (a) the trait ref itself is // A projection is well-formed if
// WF and (b) the trait-ref holds. (It may also be // (a) its predicates hold
// normalizable and be WF that way.) // (b) its substs are wf
let trait_ref = data.trait_ref(self.infcx.tcx); let obligations = self.nominal_obligations(data.item_def_id, data.substs);
self.compute_trait_ref(&trait_ref, Elaborate::None); self.out.extend(obligations);
if !data.has_escaping_bound_vars() { let tcx = self.tcx();
let predicate = trait_ref.without_const().to_predicate(self.infcx.tcx); let cause = self.cause(traits::MiscObligation);
let cause = self.cause(traits::ProjectionWf(data)); let param_env = self.param_env;
self.out.push(traits::Obligation::new(cause, self.param_env, predicate));
} self.out.extend(
data.substs
.iter()
.filter(|arg| {
matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
})
.filter(|arg| !arg.has_escaping_bound_vars())
.map(|arg| {
traits::Obligation::new(
cause.clone(),
param_env,
ty::PredicateKind::WellFormed(arg).to_predicate(tcx),
)
}),
);
} }
fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) { fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {