@@ -46,6 +46,7 @@ use arena::TypedArena;
46
46
use libc:: { c_uint, c_char} ;
47
47
use std:: ffi:: CString ;
48
48
use std:: cell:: { Cell , RefCell } ;
49
+ use std:: result:: Result as StdResult ;
49
50
use std:: vec:: Vec ;
50
51
use syntax:: ast:: Ident ;
51
52
use syntax:: ast;
@@ -1006,9 +1007,9 @@ pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) ->
1006
1007
/// do not (necessarily) resolve all nested obligations on the impl. Note that type check should
1007
1008
/// guarantee to us that all nested obligations *could be* resolved if we wanted to.
1008
1009
pub 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 , ( ) >
1012
1013
{
1013
1014
let tcx = ccx. tcx ( ) ;
1014
1015
@@ -1067,7 +1068,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1067
1068
let vtable = selection. map_move_nested ( |predicate| {
1068
1069
fulfill_cx. register_predicate_obligation ( & infcx, predicate) ;
1069
1070
} ) ;
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) ;
1071
1072
1072
1073
info ! ( "Cache miss: {}" , trait_ref. repr( ccx. tcx( ) ) ) ;
1073
1074
ccx. trait_cache ( ) . borrow_mut ( ) . insert ( trait_ref,
@@ -1076,6 +1077,22 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1076
1077
vtable
1077
1078
}
1078
1079
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
+
1079
1096
pub struct NormalizingClosureTyper < ' a , ' tcx : ' a > {
1080
1097
param_env : ty:: ParameterEnvironment < ' a , ' tcx >
1081
1098
}
@@ -1123,11 +1140,36 @@ impl<'a,'tcx> ty::ClosureTyper<'tcx> for NormalizingClosureTyper<'a,'tcx> {
1123
1140
}
1124
1141
}
1125
1142
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.
1126
1168
pub 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 > > >
1131
1173
where T : TypeFoldable < ' tcx > + Repr < ' tcx >
1132
1174
{
1133
1175
debug ! ( "drain_fulfillment_cx(result={})" ,
@@ -1140,16 +1182,13 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
1140
1182
match fulfill_cx. select_all_or_error ( infcx, & typer) {
1141
1183
Ok ( ( ) ) => { }
1142
1184
Err ( errors) => {
1185
+ // We always want to surface any overflow errors, no matter what.
1143
1186
if errors. iter ( ) . all ( |e| e. is_overflow ( ) ) {
1144
- // See Ok(None) case above.
1145
1187
infcx. tcx . sess . span_fatal (
1146
1188
span,
1147
1189
"reached the recursion limit during monomorphization" ) ;
1148
1190
} 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) ;
1153
1192
}
1154
1193
}
1155
1194
}
@@ -1159,7 +1198,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
1159
1198
// sort of overkill because we do not expect there to be any
1160
1199
// unbound type variables, hence no `TyFresh` types should ever be
1161
1200
// inserted.
1162
- result. fold_with ( & mut infcx. freshener ( ) )
1201
+ Ok ( result. fold_with ( & mut infcx. freshener ( ) ) )
1163
1202
}
1164
1203
1165
1204
// Key used to lookup values supplied for type parameters in an expr.
0 commit comments