@@ -46,6 +46,7 @@ use arena::TypedArena;
4646use libc:: { c_uint, c_char} ;
4747use std:: ffi:: CString ;
4848use std:: cell:: { Cell , RefCell } ;
49+ use std:: result:: Result as StdResult ;
4950use std:: vec:: Vec ;
5051use syntax:: ast:: Ident ;
5152use syntax:: ast;
@@ -1006,9 +1007,9 @@ pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) ->
10061007/// do not (necessarily) resolve all nested obligations on the impl. Note that type check should
10071008/// guarantee to us that all nested obligations *could be* resolved if we wanted to.
10081009pub fn fulfill_obligation < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
1009- span : Span ,
1010- trait_ref : ty:: PolyTraitRef < ' tcx > )
1011- -> traits:: Vtable < ' tcx , ( ) >
1010+ span : Span ,
1011+ trait_ref : ty:: PolyTraitRef < ' tcx > )
1012+ -> traits:: Vtable < ' tcx , ( ) >
10121013{
10131014 let tcx = ccx. tcx ( ) ;
10141015
@@ -1067,7 +1068,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
10671068 let vtable = selection. map_move_nested ( |predicate| {
10681069 fulfill_cx. register_predicate_obligation ( & infcx, predicate) ;
10691070 } ) ;
1070- let vtable = drain_fulfillment_cx ( span, & infcx, & mut fulfill_cx, & vtable) ;
1071+ let vtable = drain_fulfillment_cx_or_panic ( span, & infcx, & mut fulfill_cx, & vtable) ;
10711072
10721073 info ! ( "Cache miss: {}" , trait_ref. repr( ccx. tcx( ) ) ) ;
10731074 ccx. trait_cache ( ) . borrow_mut ( ) . insert ( trait_ref,
@@ -1076,6 +1077,22 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
10761077 vtable
10771078}
10781079
1080+ pub fn predicates_hold < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
1081+ predicates : Vec < ty:: Predicate < ' tcx > > )
1082+ -> bool
1083+ {
1084+ debug ! ( "predicates_hold(predicates={})" ,
1085+ predicates. repr( ccx. tcx( ) ) ) ;
1086+
1087+ let infcx = infer:: new_infer_ctxt ( ccx. tcx ( ) ) ;
1088+ let mut fulfill_cx = traits:: FulfillmentContext :: new ( ) ;
1089+ for predicate in predicates {
1090+ let obligation = traits:: Obligation :: new ( traits:: ObligationCause :: dummy ( ) , predicate) ;
1091+ fulfill_cx. register_predicate_obligation ( & infcx, obligation) ;
1092+ }
1093+ drain_fulfillment_cx ( DUMMY_SP , & infcx, & mut fulfill_cx, & ( ) ) . is_ok ( )
1094+ }
1095+
10791096pub struct NormalizingClosureTyper < ' a , ' tcx : ' a > {
10801097 param_env : ty:: ParameterEnvironment < ' a , ' tcx >
10811098}
@@ -1123,11 +1140,36 @@ impl<'a,'tcx> ty::ClosureTyper<'tcx> for NormalizingClosureTyper<'a,'tcx> {
11231140 }
11241141}
11251142
1143+ pub fn drain_fulfillment_cx_or_panic < ' a , ' tcx , T > ( span : Span ,
1144+ infcx : & infer:: InferCtxt < ' a , ' tcx > ,
1145+ fulfill_cx : & mut traits:: FulfillmentContext < ' tcx > ,
1146+ result : & T )
1147+ -> T
1148+ where T : TypeFoldable < ' tcx > + Repr < ' tcx >
1149+ {
1150+ match drain_fulfillment_cx ( span, infcx, fulfill_cx, result) {
1151+ Ok ( v) => v,
1152+ Err ( errors) => {
1153+ infcx. tcx . sess . span_bug (
1154+ span,
1155+ & format ! ( "Encountered errors `{}` fulfilling during trans" ,
1156+ errors. repr( infcx. tcx) ) ) ;
1157+ }
1158+ }
1159+ }
1160+
1161+ /// Finishes processes any obligations that remain in the fulfillment
1162+ /// context, and then "freshens" and returns `result`. This is
1163+ /// primarily used during normalization and other cases where
1164+ /// processing the obligations in `fulfill_cx` may cause type
1165+ /// inference variables that appear in `result` to be unified, and
1166+ /// hence we need to process those obligations to get the complete
1167+ /// picture of the type.
11261168pub fn drain_fulfillment_cx < ' a , ' tcx , T > ( span : Span ,
1127- infcx : & infer:: InferCtxt < ' a , ' tcx > ,
1128- fulfill_cx : & mut traits:: FulfillmentContext < ' tcx > ,
1129- result : & T )
1130- -> T
1169+ infcx : & infer:: InferCtxt < ' a , ' tcx > ,
1170+ fulfill_cx : & mut traits:: FulfillmentContext < ' tcx > ,
1171+ result : & T )
1172+ -> StdResult < T , Vec < traits :: FulfillmentError < ' tcx > > >
11311173 where T : TypeFoldable < ' tcx > + Repr < ' tcx >
11321174{
11331175 debug ! ( "drain_fulfillment_cx(result={})" ,
@@ -1140,16 +1182,13 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
11401182 match fulfill_cx. select_all_or_error ( infcx, & typer) {
11411183 Ok ( ( ) ) => { }
11421184 Err ( errors) => {
1185+ // We always want to surface any overflow errors, no matter what.
11431186 if errors. iter ( ) . all ( |e| e. is_overflow ( ) ) {
1144- // See Ok(None) case above.
11451187 infcx. tcx . sess . span_fatal (
11461188 span,
11471189 "reached the recursion limit during monomorphization" ) ;
11481190 } else {
1149- infcx. tcx . sess . span_bug (
1150- span,
1151- & format ! ( "Encountered errors `{}` fulfilling during trans" ,
1152- errors. repr( infcx. tcx) ) ) ;
1191+ return Err ( errors) ;
11531192 }
11541193 }
11551194 }
@@ -1159,7 +1198,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
11591198 // sort of overkill because we do not expect there to be any
11601199 // unbound type variables, hence no `TyFresh` types should ever be
11611200 // inserted.
1162- result. fold_with ( & mut infcx. freshener ( ) )
1201+ Ok ( result. fold_with ( & mut infcx. freshener ( ) ) )
11631202}
11641203
11651204// Key used to lookup values supplied for type parameters in an expr.
0 commit comments