@@ -13,7 +13,7 @@ use middle::const_val::ConstVal;
13
13
use infer:: InferCtxt ;
14
14
use ty:: subst:: Substs ;
15
15
use traits;
16
- use ty:: { self , ToPredicate , Ty , TyCtxt , TypeFoldable } ;
16
+ use ty:: { self , ToPredicate , ToPolyTraitRef , Ty , TyCtxt , TypeFoldable } ;
17
17
use std:: iter:: once;
18
18
use syntax:: ast;
19
19
use syntax_pos:: Span ;
@@ -59,7 +59,7 @@ pub fn trait_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
59
59
-> Vec < traits:: PredicateObligation < ' tcx > >
60
60
{
61
61
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 ) ;
63
63
wf. normalize ( )
64
64
}
65
65
@@ -73,19 +73,18 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
73
73
let mut wf = WfPredicates { infcx, param_env, body_id, span, out : vec ! [ ] } ;
74
74
75
75
// (*) 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 ) ;
79
79
}
80
80
ty:: Predicate :: RegionOutlives ( ..) => {
81
81
}
82
- ty:: Predicate :: TypeOutlives ( ref t) => {
82
+ ty:: Predicate :: TypeOutlives ( t) => {
83
83
wf. compute ( t. skip_binder ( ) . 0 ) ;
84
84
}
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 ) ; // (*)
89
88
}
90
89
ty:: Predicate :: WellFormed ( t) => {
91
90
wf. compute ( t) ;
@@ -94,12 +93,12 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
94
93
}
95
94
ty:: Predicate :: ClosureKind ( ..) => {
96
95
}
97
- ty:: Predicate :: Subtype ( ref data) => {
96
+ ty:: Predicate :: Subtype ( data) => {
98
97
wf. compute ( data. skip_binder ( ) . a ) ; // (*)
99
98
wf. compute ( data. skip_binder ( ) . b ) ; // (*)
100
99
}
101
100
ty:: Predicate :: ConstEvaluatable ( def_id, substs) => {
102
- let obligations = wf. nominal_obligations ( def_id, substs) ;
101
+ let obligations = wf. nominal_obligations ( * def_id, substs) ;
103
102
wf. out . extend ( obligations) ;
104
103
105
104
for ty in substs. types ( ) {
@@ -169,8 +168,8 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
169
168
170
169
/// Pushes the obligations required for `trait_ref` to be WF into
171
170
/// `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 ) ;
174
173
175
174
let cause = self . cause ( traits:: MiscObligation ) ;
176
175
let param_env = self . param_env ;
@@ -189,7 +188,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
189
188
self . out . extend ( obligations) ;
190
189
191
190
self . out . extend (
192
- trait_ref . substs . types ( )
191
+ poly_trait_ref . skip_binder ( ) . substs . types ( )
193
192
. filter ( |ty| !ty. has_escaping_regions ( ) )
194
193
. map ( |ty| traits:: Obligation :: new ( cause. clone ( ) ,
195
194
param_env,
@@ -198,16 +197,18 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
198
197
199
198
/// Pushes the obligations required for `trait_ref::Item` to be WF
200
199
/// 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 > > ) {
202
201
// A projection is well-formed if (a) the trait ref itself is
203
202
// WF and (b) the trait-ref holds. (It may also be
204
203
// 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) ) ;
211
212
self . out . push ( traits:: Obligation :: new ( cause, self . param_env , predicate) ) ;
212
213
}
213
214
}
@@ -289,7 +290,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
289
290
290
291
ty:: TyProjection ( data) => {
291
292
subtys. skip_current_subtree ( ) ; // subtree handled by compute_projection
292
- self . compute_projection ( data) ;
293
+ self . compute_projection ( ty :: Binder :: bind ( data) ) ;
293
294
}
294
295
295
296
ty:: TyAdt ( def, substs) => {
@@ -431,6 +432,23 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
431
432
return true ;
432
433
}
433
434
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
+
434
452
fn nominal_obligations ( & mut self ,
435
453
def_id : DefId ,
436
454
substs : & Substs < ' tcx > )
0 commit comments