@@ -17,6 +17,8 @@ use dep_graph::{DepKind, DepTrackingMapConfig};
1717use std:: marker:: PhantomData ;
1818use syntax_pos:: DUMMY_SP ;
1919use hir:: def_id:: DefId ;
20+ use infer:: InferCtxt ;
21+ use syntax_pos:: Span ;
2022use traits:: { FulfillmentContext , Obligation , ObligationCause , SelectionContext , Vtable } ;
2123use ty:: { self , Ty , TyCtxt } ;
2224use ty:: subst:: { Subst , Substs } ;
@@ -151,3 +153,45 @@ impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
151153 DepKind :: TraitSelect
152154 }
153155}
156+
157+ impl < ' a , ' gcx , ' tcx > InferCtxt < ' a , ' gcx , ' tcx > {
158+ /// Finishes processes any obligations that remain in the
159+ /// fulfillment context, and then returns the result with all type
160+ /// variables removed and regions erased. Because this is intended
161+ /// for use after type-check has completed, if any errors occur,
162+ /// it will panic. It is used during normalization and other cases
163+ /// where processing the obligations in `fulfill_cx` may cause
164+ /// type inference variables that appear in `result` to be
165+ /// unified, and hence we need to process those obligations to get
166+ /// the complete picture of the type.
167+ fn drain_fulfillment_cx_or_panic < T > ( & self ,
168+ span : Span ,
169+ fulfill_cx : & mut FulfillmentContext < ' tcx > ,
170+ result : & T )
171+ -> T :: Lifted
172+ where T : TypeFoldable < ' tcx > + ty:: Lift < ' gcx >
173+ {
174+ debug ! ( "drain_fulfillment_cx_or_panic()" ) ;
175+
176+ // In principle, we only need to do this so long as `result`
177+ // contains unbound type parameters. It could be a slight
178+ // optimization to stop iterating early.
179+ match fulfill_cx. select_all_or_error ( self ) {
180+ Ok ( ( ) ) => { }
181+ Err ( errors) => {
182+ span_bug ! ( span, "Encountered errors `{:?}` resolving bounds after type-checking" ,
183+ errors) ;
184+ }
185+ }
186+
187+ let result = self . resolve_type_vars_if_possible ( result) ;
188+ let result = self . tcx . erase_regions ( & result) ;
189+
190+ match self . tcx . lift_to_global ( & result) {
191+ Some ( result) => result,
192+ None => {
193+ span_bug ! ( span, "Uninferred types/regions in `{:?}`" , result) ;
194+ }
195+ }
196+ }
197+ }
0 commit comments