diff options
| author | Matthew Jasper <mjjasper1@gmail.com> | 2020-06-28 10:51:32 +0100 |
|---|---|---|
| committer | Matthew Jasper <mjjasper1@gmail.com> | 2020-10-06 11:19:29 +0100 |
| commit | 87f2f42dc2c81dd842451e6c68d12abdc5fe3ecf (patch) | |
| tree | 0d18d300ea4b5711ea4499ce0857276d1d36aacd | |
| parent | f958e6c24615c4b1f1e77b0ee3d4f32383fb3617 (diff) | |
Make projection wf check the predicates for the projection
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/wf.rs | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 909cd2aa155..165e45aa94a 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -327,17 +327,31 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// Pushes the obligations required for `trait_ref::Item` to be WF /// into `self.out`. fn compute_projection(&mut self, data: ty::ProjectionTy<'tcx>) { - // A projection is well-formed if (a) the trait ref itself is - // WF and (b) the trait-ref holds. (It may also be - // normalizable and be WF that way.) - let trait_ref = data.trait_ref(self.infcx.tcx); - self.compute_trait_ref(&trait_ref, Elaborate::None); - - if !data.has_escaping_bound_vars() { - let predicate = trait_ref.without_const().to_predicate(self.infcx.tcx); - let cause = self.cause(traits::ProjectionWf(data)); - self.out.push(traits::Obligation::new(cause, self.param_env, predicate)); - } + // A projection is well-formed if + // (a) its predicates hold + // (b) its substs are wf + let obligations = self.nominal_obligations(data.item_def_id, data.substs); + self.out.extend(obligations); + + let tcx = self.tcx(); + let cause = self.cause(traits::MiscObligation); + let param_env = self.param_env; + + 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>) { |
