@@ -13,7 +13,7 @@ use middle::const_val::ConstVal;
1313use infer:: InferCtxt ;
1414use ty:: subst:: Substs ;
1515use traits;
16- use ty:: { self , ToPredicate , Ty , TyCtxt , TypeFoldable } ;
16+ use ty:: { self , ToPredicate , ToPolyTraitRef , Ty , TyCtxt , TypeFoldable } ;
1717use std:: iter:: once;
1818use syntax:: ast;
1919use syntax_pos:: Span ;
@@ -59,7 +59,7 @@ pub fn trait_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
5959 -> Vec < traits:: PredicateObligation < ' tcx > >
6060{
6161 let mut wf = WfPredicates { infcx, param_env, body_id, span, out : vec ! [ ] } ;
62- wf. compute_trait_ref ( trait_ref, Elaborate :: All ) ;
62+ wf. compute_trait_ref ( & trait_ref. to_poly_trait_ref ( ) , Elaborate :: All ) ;
6363 wf. normalize ( )
6464}
6565
@@ -73,19 +73,18 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
7373 let mut wf = WfPredicates { infcx, param_env, body_id, span, out : vec ! [ ] } ;
7474
7575 // (*) ok to skip binders, because wf code is prepared for it
76- match * predicate {
77- ty:: Predicate :: Trait ( ref t) => {
78- wf. compute_trait_ref ( & t. skip_binder ( ) . trait_ref , Elaborate :: None ) ; // (*)
76+ match predicate {
77+ ty:: Predicate :: Trait ( t) => {
78+ wf. compute_trait_ref ( & t. to_poly_trait_ref ( ) , Elaborate :: None ) ;
7979 }
8080 ty:: Predicate :: RegionOutlives ( ..) => {
8181 }
82- ty:: Predicate :: TypeOutlives ( ref t) => {
82+ ty:: Predicate :: TypeOutlives ( t) => {
8383 wf. compute ( t. skip_binder ( ) . 0 ) ;
8484 }
85- ty:: Predicate :: Projection ( ref t) => {
86- let t = t. skip_binder ( ) ; // (*)
87- wf. compute_projection ( t. projection_ty ) ;
88- wf. compute ( t. ty ) ;
85+ ty:: Predicate :: Projection ( t) => {
86+ wf. compute_projection ( t. map_bound ( |t| t. projection_ty ) ) ;
87+ wf. compute ( t. skip_binder ( ) . ty ) ; // (*)
8988 }
9089 ty:: Predicate :: WellFormed ( t) => {
9190 wf. compute ( t) ;
@@ -94,12 +93,12 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
9493 }
9594 ty:: Predicate :: ClosureKind ( ..) => {
9695 }
97- ty:: Predicate :: Subtype ( ref data) => {
96+ ty:: Predicate :: Subtype ( data) => {
9897 wf. compute ( data. skip_binder ( ) . a ) ; // (*)
9998 wf. compute ( data. skip_binder ( ) . b ) ; // (*)
10099 }
101100 ty:: Predicate :: ConstEvaluatable ( def_id, substs) => {
102- let obligations = wf. nominal_obligations ( def_id, substs) ;
101+ let obligations = wf. nominal_obligations ( * def_id, substs) ;
103102 wf. out . extend ( obligations) ;
104103
105104 for ty in substs. types ( ) {
@@ -169,8 +168,8 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
169168
170169 /// Pushes the obligations required for `trait_ref` to be WF into
171170 /// `self.out`.
172- fn compute_trait_ref ( & mut self , trait_ref : & ty:: TraitRef < ' tcx > , elaborate : Elaborate ) {
173- let obligations = self . nominal_obligations ( trait_ref . def_id , trait_ref . substs ) ;
171+ fn compute_trait_ref ( & mut self , poly_trait_ref : & ty:: PolyTraitRef < ' tcx > , elaborate : Elaborate ) {
172+ let obligations = self . nominal_trait_ref_obligations ( poly_trait_ref ) ;
174173
175174 let cause = self . cause ( traits:: MiscObligation ) ;
176175 let param_env = self . param_env ;
@@ -189,7 +188,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
189188 self . out . extend ( obligations) ;
190189
191190 self . out . extend (
192- trait_ref . substs . types ( )
191+ poly_trait_ref . skip_binder ( ) . substs . types ( )
193192 . filter ( |ty| !ty. has_escaping_regions ( ) )
194193 . map ( |ty| traits:: Obligation :: new ( cause. clone ( ) ,
195194 param_env,
@@ -198,16 +197,18 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
198197
199198 /// Pushes the obligations required for `trait_ref::Item` to be WF
200199 /// into `self.out`.
201- fn compute_projection ( & mut self , data : ty:: ProjectionTy < ' tcx > ) {
200+ fn compute_projection ( & mut self , poly_proj : ty:: Binder < ty :: ProjectionTy < ' tcx > > ) {
202201 // A projection is well-formed if (a) the trait ref itself is
203202 // WF and (b) the trait-ref holds. (It may also be
204203 // normalizable and be WF that way.)
205- let trait_ref = data. trait_ref ( self . infcx . tcx ) ;
206- self . compute_trait_ref ( & trait_ref, Elaborate :: None ) ;
207-
208- if !data. has_escaping_regions ( ) {
209- let predicate = trait_ref. to_predicate ( ) ;
210- let cause = self . cause ( traits:: ProjectionWf ( data) ) ;
204+ let poly_trait_ref = poly_proj. map_bound ( |proj| proj. trait_ref ( self . infcx . tcx ) ) ;
205+ self . compute_trait_ref ( & poly_trait_ref, Elaborate :: None ) ;
206+
207+ // FIXME(leodasvacas): Should be straightforward to remove
208+ // this condition and use the `poly_proj` directly.
209+ if let Some ( proj) = poly_proj. no_late_bound_regions ( ) {
210+ let predicate = poly_trait_ref. to_predicate ( ) ;
211+ let cause = self . cause ( traits:: ProjectionWf ( proj) ) ;
211212 self . out . push ( traits:: Obligation :: new ( cause, self . param_env , predicate) ) ;
212213 }
213214 }
@@ -289,7 +290,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
289290
290291 ty:: TyProjection ( data) => {
291292 subtys. skip_current_subtree ( ) ; // subtree handled by compute_projection
292- self . compute_projection ( data) ;
293+ self . compute_projection ( ty :: Binder :: bind ( data) ) ;
293294 }
294295
295296 ty:: TyAdt ( def, substs) => {
@@ -431,6 +432,23 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
431432 return true ;
432433 }
433434
435+ fn nominal_trait_ref_obligations ( & mut self ,
436+ poly_trait_ref : & ty:: PolyTraitRef < ' tcx > )
437+ -> Vec < traits:: PredicateObligation < ' tcx > > {
438+ let cause = self . cause ( traits:: ItemObligation ( poly_trait_ref. def_id ( ) ) ) ;
439+ poly_trait_ref
440+ . unfold ( |trait_ref| {
441+ self . infcx
442+ . tcx
443+ . predicates_of ( trait_ref. def_id )
444+ . instantiate ( self . infcx . tcx , trait_ref. substs )
445+ . predicates
446+ } )
447+ . map ( |poly_pred| poly_pred. flatten ( self . infcx . tcx ) )
448+ . map ( |pred| traits:: Obligation :: new ( cause. clone ( ) , self . param_env , pred) )
449+ . collect ( )
450+ }
451+
434452 fn nominal_obligations ( & mut self ,
435453 def_id : DefId ,
436454 substs : & Substs < ' tcx > )
0 commit comments