@@ -954,28 +954,47 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
954
954
955
955
// Currently, we use a fulfillment context to completely resolve
956
956
// all nested obligations. This is because they can inform the
957
- // inference of the impl's type parameters. However, in principle,
958
- // we only need to do this until the impl's type parameters are
959
- // fully bound. It could be a slight optimization to stop
960
- // iterating early.
957
+ // inference of the impl's type parameters.
961
958
let mut fulfill_cx = traits:: FulfillmentContext :: new ( ) ;
962
959
let vtable = selection. map_move_nested ( |predicate| {
963
960
fulfill_cx. register_predicate_obligation ( & infcx, predicate) ;
964
961
} ) ;
965
- match fulfill_cx. select_all_or_error ( & infcx, & param_env, tcx) {
962
+ let vtable = drain_fulfillment_cx ( span, & infcx, & param_env, & mut fulfill_cx, & vtable) ;
963
+
964
+ info ! ( "Cache miss: {}" , trait_ref. repr( ccx. tcx( ) ) ) ;
965
+ ccx. trait_cache ( ) . borrow_mut ( ) . insert ( trait_ref,
966
+ vtable. clone ( ) ) ;
967
+
968
+ vtable
969
+ }
970
+
971
+ pub fn drain_fulfillment_cx < ' a , ' tcx , T > ( span : Span ,
972
+ infcx : & infer:: InferCtxt < ' a , ' tcx > ,
973
+ param_env : & ty:: ParameterEnvironment < ' tcx > ,
974
+ fulfill_cx : & mut traits:: FulfillmentContext < ' tcx > ,
975
+ result : & T )
976
+ -> T
977
+ where T : TypeFoldable < ' tcx > + Repr < ' tcx >
978
+ {
979
+ debug ! ( "drain_fulfillment_cx(result={})" ,
980
+ result. repr( infcx. tcx) ) ;
981
+
982
+ // In principle, we only need to do this so long as `result`
983
+ // contains unbound type parameters. It could be a slight
984
+ // optimization to stop iterating early.
985
+ match fulfill_cx. select_all_or_error ( infcx, param_env, infcx. tcx ) {
966
986
Ok ( ( ) ) => { }
967
987
Err ( errors) => {
968
988
if errors. iter ( ) . all ( |e| e. is_overflow ( ) ) {
969
989
// See Ok(None) case above.
970
- ccx . sess ( ) . span_fatal (
990
+ infcx . tcx . sess . span_fatal (
971
991
span,
972
992
"reached the recursion limit during monomorphization" ) ;
973
993
} else {
974
- tcx. sess . span_bug (
994
+ infcx . tcx . sess . span_bug (
975
995
span,
976
- format ! ( "Encountered errors `{}` fulfilling `{}` during trans" ,
977
- errors. repr( tcx) ,
978
- trait_ref. repr( tcx) ) [ ] ) ;
996
+ format ! ( "Encountered errors `{}` fulfilling during trans" ,
997
+ errors. repr( infcx. tcx) ) [ ] ) ;
979
998
}
980
999
}
981
1000
}
@@ -985,13 +1004,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
985
1004
// sort of overkill because we do not expect there to be any
986
1005
// unbound type variables, hence no `TyFresh` types should ever be
987
1006
// inserted.
988
- let vtable = vtable. fold_with ( & mut infcx. freshener ( ) ) ;
989
-
990
- info ! ( "Cache miss: {}" , trait_ref. repr( ccx. tcx( ) ) ) ;
991
- ccx. trait_cache ( ) . borrow_mut ( ) . insert ( trait_ref,
992
- vtable. clone ( ) ) ;
993
-
994
- vtable
1007
+ result. fold_with ( & mut infcx. freshener ( ) )
995
1008
}
996
1009
997
1010
// Key used to lookup values supplied for type parameters in an expr.
0 commit comments