@@ -58,7 +58,7 @@ pub fn trait_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
58
58
-> Vec < traits:: PredicateObligation < ' tcx > >
59
59
{
60
60
let mut wf = WfPredicates { infcx, param_env, body_id, span, out : vec ! [ ] } ;
61
- wf. compute_trait_ref ( trait_ref) ;
61
+ wf. compute_trait_ref ( trait_ref, Elaborate :: All ) ;
62
62
wf. normalize ( )
63
63
}
64
64
@@ -74,7 +74,7 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
74
74
// (*) ok to skip binders, because wf code is prepared for it
75
75
match * predicate {
76
76
ty:: Predicate :: Trait ( ref t) => {
77
- wf. compute_trait_ref ( & t. skip_binder ( ) . trait_ref ) ; // (*)
77
+ wf. compute_trait_ref ( & t. skip_binder ( ) . trait_ref , Elaborate :: None ) ; // (*)
78
78
}
79
79
ty:: Predicate :: Equate ( ref t) => {
80
80
wf. compute ( t. skip_binder ( ) . 0 ) ;
@@ -114,6 +114,12 @@ struct WfPredicates<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
114
114
out : Vec < traits:: PredicateObligation < ' tcx > > ,
115
115
}
116
116
117
+ #[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
118
+ enum Elaborate {
119
+ All ,
120
+ None ,
121
+ }
122
+
117
123
impl < ' a , ' gcx , ' tcx > WfPredicates < ' a , ' gcx , ' tcx > {
118
124
fn cause ( & mut self , code : traits:: ObligationCauseCode < ' tcx > ) -> traits:: ObligationCause < ' tcx > {
119
125
traits:: ObligationCause :: new ( self . span , self . body_id , code)
@@ -135,21 +141,24 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
135
141
136
142
/// Pushes the obligations required for `trait_ref` to be WF into
137
143
/// `self.out`.
138
- fn compute_trait_ref ( & mut self , trait_ref : & ty:: TraitRef < ' tcx > ) {
144
+ fn compute_trait_ref ( & mut self , trait_ref : & ty:: TraitRef < ' tcx > , elaborate : Elaborate ) {
139
145
let obligations = self . nominal_obligations ( trait_ref. def_id , trait_ref. substs ) ;
140
146
141
147
let cause = self . cause ( traits:: MiscObligation ) ;
142
148
let param_env = self . param_env ;
143
149
144
- let predicates = obligations. iter ( )
145
- . map ( |obligation| obligation. predicate . clone ( ) )
146
- . collect ( ) ;
147
- let implied_obligations = traits:: elaborate_predicates ( self . infcx . tcx , predicates) ;
148
- let implied_obligations = implied_obligations. map ( |pred| {
149
- traits:: Obligation :: new ( cause. clone ( ) , param_env, pred)
150
- } ) ;
150
+ if let Elaborate :: All = elaborate {
151
+ let predicates = obligations. iter ( )
152
+ . map ( |obligation| obligation. predicate . clone ( ) )
153
+ . collect ( ) ;
154
+ let implied_obligations = traits:: elaborate_predicates ( self . infcx . tcx , predicates) ;
155
+ let implied_obligations = implied_obligations. map ( |pred| {
156
+ traits:: Obligation :: new ( cause. clone ( ) , param_env, pred)
157
+ } ) ;
158
+ self . out . extend ( implied_obligations) ;
159
+ }
151
160
152
- self . out . extend ( implied_obligations . chain ( obligations) ) ;
161
+ self . out . extend ( obligations) ;
153
162
154
163
self . out . extend (
155
164
trait_ref. substs . types ( )
@@ -166,7 +175,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
166
175
// WF and (b) the trait-ref holds. (It may also be
167
176
// normalizable and be WF that way.)
168
177
let trait_ref = data. trait_ref ( self . infcx . tcx ) ;
169
- self . compute_trait_ref ( & trait_ref) ;
178
+ self . compute_trait_ref ( & trait_ref, Elaborate :: All ) ;
170
179
171
180
if !data. has_escaping_regions ( ) {
172
181
let predicate = trait_ref. to_predicate ( ) ;
0 commit comments