diff options
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/wf.rs')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/wf.rs | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 562a82cc73d..8a0ce3c1f98 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -165,11 +165,8 @@ pub fn clause_obligations<'tcx>( wf.compute(ty.into()); } ty::ClauseKind::Projection(t) => { - wf.compute_alias(t.projection_ty); - wf.compute(match t.term.unpack() { - ty::TermKind::Ty(ty) => ty.into(), - ty::TermKind::Const(c) => c.into(), - }) + wf.compute_alias_term(t.projection_term); + wf.compute(t.term.into_arg()); } ty::ClauseKind::ConstArgHasType(ct, ty) => { wf.compute(ct.into()); @@ -439,7 +436,37 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// Pushes the obligations required for an alias (except inherent) to be WF /// into `self.out`. - fn compute_alias(&mut self, data: ty::AliasTy<'tcx>) { + fn compute_alias_ty(&mut self, data: ty::AliasTy<'tcx>) { + // A projection is well-formed if + // + // (a) its predicates hold (*) + // (b) its args are wf + // + // (*) The predicates of an associated type include the predicates of + // the trait that it's contained in. For example, given + // + // trait A<T>: Clone { + // type X where T: Copy; + // } + // + // The predicates of `<() as A<i32>>::X` are: + // [ + // `(): Sized` + // `(): Clone` + // `(): A<i32>` + // `i32: Sized` + // `i32: Clone` + // `i32: Copy` + // ] + let obligations = self.nominal_obligations(data.def_id, data.args); + self.out.extend(obligations); + + self.compute_projection_args(data.args); + } + + /// Pushes the obligations required for an alias (except inherent) to be WF + /// into `self.out`. + fn compute_alias_term(&mut self, data: ty::AliasTerm<'tcx>) { // A projection is well-formed if // // (a) its predicates hold (*) @@ -698,7 +725,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> { } ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => { - self.compute_alias(data); + self.compute_alias_ty(data); return; // Subtree handled by compute_projection. } ty::Alias(ty::Inherent, data) => { |
