@@ -58,7 +58,7 @@ pub fn trait_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
5858 -> Vec < traits:: PredicateObligation < ' tcx > >
5959{
6060 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 ) ;
6262 wf. normalize ( )
6363}
6464
@@ -74,7 +74,7 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
7474 // (*) ok to skip binders, because wf code is prepared for it
7575 match * predicate {
7676 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 ) ; // (*)
7878 }
7979 ty:: Predicate :: Equate ( ref t) => {
8080 wf. compute ( t. skip_binder ( ) . 0 ) ;
@@ -114,6 +114,12 @@ struct WfPredicates<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
114114 out : Vec < traits:: PredicateObligation < ' tcx > > ,
115115}
116116
117+ #[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
118+ enum Elaborate {
119+ All ,
120+ None ,
121+ }
122+
117123impl < ' a , ' gcx , ' tcx > WfPredicates < ' a , ' gcx , ' tcx > {
118124 fn cause ( & mut self , code : traits:: ObligationCauseCode < ' tcx > ) -> traits:: ObligationCause < ' tcx > {
119125 traits:: ObligationCause :: new ( self . span , self . body_id , code)
@@ -135,21 +141,24 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
135141
136142 /// Pushes the obligations required for `trait_ref` to be WF into
137143 /// `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 ) {
139145 let obligations = self . nominal_obligations ( trait_ref. def_id , trait_ref. substs ) ;
140146
141147 let cause = self . cause ( traits:: MiscObligation ) ;
142148 let param_env = self . param_env ;
143149
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+ }
151160
152- self . out . extend ( implied_obligations . chain ( obligations) ) ;
161+ self . out . extend ( obligations) ;
153162
154163 self . out . extend (
155164 trait_ref. substs . types ( )
@@ -166,7 +175,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
166175 // WF and (b) the trait-ref holds. (It may also be
167176 // normalizable and be WF that way.)
168177 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 ) ;
170179
171180 if !data. has_escaping_regions ( ) {
172181 let predicate = trait_ref. to_predicate ( ) ;
0 commit comments