@@ -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;
@@ -997,9 +998,9 @@ pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) ->
997
998
/// do not (necessarily) resolve all nested obligations on the impl. Note that type check should
998
999
/// guarantee to us that all nested obligations *could be* resolved if we wanted to.
999
1000
pub fn fulfill_obligation < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
1000
- span : Span ,
1001
- trait_ref : ty:: PolyTraitRef < ' tcx > )
1002
- -> traits:: Vtable < ' tcx , ( ) >
1001
+ span : Span ,
1002
+ trait_ref : ty:: PolyTraitRef < ' tcx > )
1003
+ -> traits:: Vtable < ' tcx , ( ) >
1003
1004
{
1004
1005
let tcx = ccx. tcx ( ) ;
1005
1006
@@ -1058,7 +1059,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1058
1059
let vtable = selection. map_move_nested ( |predicate| {
1059
1060
fulfill_cx. register_predicate_obligation ( & infcx, predicate) ;
1060
1061
} ) ;
1061
- let vtable = drain_fulfillment_cx ( span, & infcx, & mut fulfill_cx, & vtable) ;
1062
+ let vtable = drain_fulfillment_cx_or_panic ( span, & infcx, & mut fulfill_cx, & vtable) ;
1062
1063
1063
1064
info ! ( "Cache miss: {}" , trait_ref. repr( ccx. tcx( ) ) ) ;
1064
1065
ccx. trait_cache ( ) . borrow_mut ( ) . insert ( trait_ref,
@@ -1067,6 +1068,22 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1067
1068
vtable
1068
1069
}
1069
1070
1071
+ pub fn predicates_hold < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
1072
+ predicates : Vec < ty:: Predicate < ' tcx > > )
1073
+ -> bool
1074
+ {
1075
+ debug ! ( "predicates_hold(predicates={})" ,
1076
+ predicates. repr( ccx. tcx( ) ) ) ;
1077
+
1078
+ let infcx = infer:: new_infer_ctxt ( ccx. tcx ( ) ) ;
1079
+ let mut fulfill_cx = traits:: FulfillmentContext :: new ( ) ;
1080
+ for predicate in predicates {
1081
+ let obligation = traits:: Obligation :: new ( traits:: ObligationCause :: dummy ( ) , predicate) ;
1082
+ fulfill_cx. register_predicate_obligation ( & infcx, obligation) ;
1083
+ }
1084
+ drain_fulfillment_cx ( DUMMY_SP , & infcx, & mut fulfill_cx, & ( ) ) . is_ok ( )
1085
+ }
1086
+
1070
1087
pub struct NormalizingClosureTyper < ' a , ' tcx : ' a > {
1071
1088
param_env : ty:: ParameterEnvironment < ' a , ' tcx >
1072
1089
}
@@ -1114,11 +1131,36 @@ impl<'a,'tcx> ty::ClosureTyper<'tcx> for NormalizingClosureTyper<'a,'tcx> {
1114
1131
}
1115
1132
}
1116
1133
1134
+ pub fn drain_fulfillment_cx_or_panic < ' a , ' tcx , T > ( span : Span ,
1135
+ infcx : & infer:: InferCtxt < ' a , ' tcx > ,
1136
+ fulfill_cx : & mut traits:: FulfillmentContext < ' tcx > ,
1137
+ result : & T )
1138
+ -> T
1139
+ where T : TypeFoldable < ' tcx > + Repr < ' tcx >
1140
+ {
1141
+ match drain_fulfillment_cx ( span, infcx, fulfill_cx, result) {
1142
+ Ok ( v) => v,
1143
+ Err ( errors) => {
1144
+ infcx. tcx . sess . span_bug (
1145
+ span,
1146
+ & format ! ( "Encountered errors `{}` fulfilling during trans" ,
1147
+ errors. repr( infcx. tcx) ) ) ;
1148
+ }
1149
+ }
1150
+ }
1151
+
1152
+ /// Finishes processes any obligations that remain in the fulfillment
1153
+ /// context, and then "freshens" and returns `result`. This is
1154
+ /// primarily used during normalization and other cases where
1155
+ /// processing the obligations in `fulfill_cx` may cause type
1156
+ /// inference variables that appear in `result` to be unified, and
1157
+ /// hence we need to process those obligations to get the complete
1158
+ /// picture of the type.
1117
1159
pub fn drain_fulfillment_cx < ' a , ' tcx , T > ( span : Span ,
1118
- infcx : & infer:: InferCtxt < ' a , ' tcx > ,
1119
- fulfill_cx : & mut traits:: FulfillmentContext < ' tcx > ,
1120
- result : & T )
1121
- -> T
1160
+ infcx : & infer:: InferCtxt < ' a , ' tcx > ,
1161
+ fulfill_cx : & mut traits:: FulfillmentContext < ' tcx > ,
1162
+ result : & T )
1163
+ -> StdResult < T , Vec < traits :: FulfillmentError < ' tcx > > >
1122
1164
where T : TypeFoldable < ' tcx > + Repr < ' tcx >
1123
1165
{
1124
1166
debug ! ( "drain_fulfillment_cx(result={})" ,
@@ -1131,16 +1173,13 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
1131
1173
match fulfill_cx. select_all_or_error ( infcx, & typer) {
1132
1174
Ok ( ( ) ) => { }
1133
1175
Err ( errors) => {
1176
+ // We always want to surface any overflow errors, no matter what.
1134
1177
if errors. iter ( ) . all ( |e| e. is_overflow ( ) ) {
1135
- // See Ok(None) case above.
1136
1178
infcx. tcx . sess . span_fatal (
1137
1179
span,
1138
1180
"reached the recursion limit during monomorphization" ) ;
1139
1181
} else {
1140
- infcx. tcx . sess . span_bug (
1141
- span,
1142
- & format ! ( "Encountered errors `{}` fulfilling during trans" ,
1143
- errors. repr( infcx. tcx) ) ) ;
1182
+ return Err ( errors) ;
1144
1183
}
1145
1184
}
1146
1185
}
@@ -1150,7 +1189,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
1150
1189
// sort of overkill because we do not expect there to be any
1151
1190
// unbound type variables, hence no `TyFresh` types should ever be
1152
1191
// inserted.
1153
- result. fold_with ( & mut infcx. freshener ( ) )
1192
+ Ok ( result. fold_with ( & mut infcx. freshener ( ) ) )
1154
1193
}
1155
1194
1156
1195
// Key used to lookup values supplied for type parameters in an expr.
0 commit comments