@@ -80,6 +80,7 @@ mod expr;
80
80
mod generator_interior;
81
81
pub mod intrinsic;
82
82
pub mod method;
83
+ mod never_compat;
83
84
mod op;
84
85
mod pat;
85
86
mod regionck;
@@ -1065,76 +1066,7 @@ fn typeck_tables_of_with_fallback<'tcx>(
1065
1066
// All type checking constraints were added, try to fallback unsolved variables.
1066
1067
fcx. select_obligations_where_possible ( false , |_| { } ) ;
1067
1068
let mut fallback_has_occurred = false ;
1068
- let unresolved_paths: FxHashMap < hir:: HirId , InferredPath < ' tcx > > = fcx
1069
- . inferred_paths
1070
- . borrow ( )
1071
- . iter ( )
1072
- . map ( |( id, path) | ( * id, path. clone ( ) ) )
1073
- . filter_map ( |( hir_id, mut path) | {
1074
- debug ! (
1075
- "typeck_tables_of_with_fallback: inspecting path ({:?}, {:?})" ,
1076
- hir_id, path
1077
- ) ;
1078
-
1079
- let ty_resolved = fcx. infcx . resolve_vars_if_possible ( & path. ty ) ;
1080
-
1081
- let fn_substs = match ty_resolved {
1082
- Some ( ty:: TyS { kind : ty:: FnDef ( _, substs) , .. } ) => substs,
1083
- _ => {
1084
- debug ! (
1085
- "typeck_tables_of_with_fallback: non-fn ty {:?}, skipping" ,
1086
- ty_resolved
1087
- ) ;
1088
- return None ;
1089
- }
1090
- } ;
1091
-
1092
- if fcx. infcx . unresolved_type_vars ( fn_substs) . is_some ( ) {
1093
- struct TyVarFinder < ' a , ' tcx > {
1094
- infcx : & ' a InferCtxt < ' a , ' tcx > ,
1095
- vars : Vec < Ty < ' tcx > > ,
1096
- }
1097
- impl < ' a , ' tcx > TypeFolder < ' tcx > for TyVarFinder < ' a , ' tcx > {
1098
- fn tcx ( & self ) -> TyCtxt < ' tcx > {
1099
- self . infcx . tcx
1100
- }
1101
-
1102
- fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
1103
- if let ty:: Infer ( ty:: InferTy :: TyVar ( _) ) = t. kind {
1104
- self . vars . push ( t) ;
1105
- }
1106
- t. super_fold_with ( self )
1107
- }
1108
- }
1109
-
1110
- for subst in fn_substs. types ( ) {
1111
- let mut finder = TyVarFinder { infcx : & fcx. infcx , vars : vec ! [ ] } ;
1112
- path. ty . fold_with ( & mut finder) ;
1113
- path. unresolved_vars . push ( finder. vars ) ;
1114
- }
1115
-
1116
- debug ! (
1117
- "typeck_tables_of_with_fallback: unresolved vars in ty {:?} : {:?}" ,
1118
- ty_resolved, path. unresolved_vars
1119
- ) ;
1120
-
1121
- Some ( ( hir_id, path) )
1122
- } else {
1123
- debug ! (
1124
- "typeck_tables_of_with_fallback: all vars resolved in ty: {:?}" ,
1125
- ty_resolved
1126
- ) ;
1127
- None
1128
- }
1129
- } )
1130
- . collect ( ) ;
1131
-
1132
- let unconstrained_diverging: Vec < _ > = fcx
1133
- . unsolved_variables ( )
1134
- . iter ( )
1135
- . cloned ( )
1136
- . filter ( |ty| fcx. infcx . type_var_diverges ( ty) )
1137
- . collect ( ) ;
1069
+ let never_compat = never_compat:: NeverCompatHandler :: pre_fallback ( & fcx) ;
1138
1070
1139
1071
// We do fallback in two passes, to try to generate
1140
1072
// better error messages.
@@ -1177,131 +1109,7 @@ fn typeck_tables_of_with_fallback<'tcx>(
1177
1109
// See if we can make any more progress.
1178
1110
fcx. select_obligations_where_possible ( fallback_has_occurred, |_| { } ) ;
1179
1111
1180
- for ( call_id, path) in unresolved_paths {
1181
- debug ! (
1182
- "Resolved ty: {:?} at span {:?} : expr={:?} parent={:?} path={:?}" ,
1183
- path. span,
1184
- path. ty,
1185
- tcx. hir( ) . get( call_id) ,
1186
- tcx. hir( ) . get( tcx. hir( ) . get_parent_node( call_id) ) ,
1187
- path
1188
- ) ;
1189
-
1190
- let ty = fcx. infcx . resolve_vars_if_possible ( & path. ty ) ;
1191
- debug ! ( "Fully resolved ty: {:?}" , ty) ;
1192
-
1193
- let ty = ty. unwrap_or_else ( || bug ! ( "Missing ty in path: {:?}" , path) ) ;
1194
-
1195
- if let ty:: FnDef ( _, substs) = ty. kind {
1196
- debug ! ( "Got substs: {:?}" , substs) ;
1197
- let mut args_inhabited = true ;
1198
- let mut uninhabited_subst = None ;
1199
-
1200
- for arg in & * path. args . unwrap ( ) {
1201
- let resolved_arg = fcx. infcx . resolve_vars_if_possible ( arg) ;
1202
-
1203
- if resolved_arg. conservative_is_privately_uninhabited ( tcx) {
1204
- debug ! ( "Arg is uninhabited: {:?}" , resolved_arg) ;
1205
- args_inhabited = false ;
1206
- break ;
1207
- } else {
1208
- debug ! ( "Arg is inhabited: {:?}" , resolved_arg) ;
1209
- }
1210
- }
1211
-
1212
- for ( subst_ty, vars) in substs. types ( ) . zip ( path. unresolved_vars . into_iter ( ) ) {
1213
- let resolved_subst = fcx. infcx . resolve_vars_if_possible ( & subst_ty) ;
1214
- if resolved_subst. conservative_is_privately_uninhabited ( tcx) {
1215
- debug ! ( "Subst is uninhabited: {:?}" , resolved_subst) ;
1216
- if !vars. is_empty ( ) {
1217
- debug ! ( "Found fallback vars: {:?}" , vars) ;
1218
- uninhabited_subst = Some ( ( resolved_subst, vars) ) ;
1219
- break ;
1220
- } else {
1221
- debug ! ( "No fallback vars" )
1222
- }
1223
- } else {
1224
- debug ! ( "Subst is inhabited: {:?}" , resolved_subst) ;
1225
- }
1226
- }
1227
-
1228
- if let ( true , Some ( ( subst, vars) ) ) = ( args_inhabited, uninhabited_subst) {
1229
- debug ! ( "All arguments are inhabited, at least one subst is not inhabited!" ) ;
1230
-
1231
- let mut best_diverging_var = None ;
1232
- let mut best_var = None ;
1233
-
1234
- for var in vars {
1235
- for diverging_var in & unconstrained_diverging {
1236
- match ( & var. kind , & diverging_var. kind ) {
1237
- (
1238
- ty:: Infer ( ty:: InferTy :: TyVar ( vid1) ) ,
1239
- ty:: Infer ( ty:: InferTy :: TyVar ( vid2) ) ,
1240
- ) => {
1241
- if fcx
1242
- . infcx
1243
- . type_variables
1244
- . borrow_mut ( )
1245
- . sub_unified ( * vid1, * vid2)
1246
- {
1247
- debug ! (
1248
- "Type variable {:?} is equal to diverging var {:?}" ,
1249
- var, diverging_var
1250
- ) ;
1251
-
1252
- debug ! (
1253
- "Var origin: {:?}" ,
1254
- fcx. infcx. type_variables. borrow( ) . var_origin( * vid1)
1255
- ) ;
1256
- best_var = Some ( vid1) ;
1257
- best_diverging_var = Some ( vid2) ;
1258
- }
1259
- }
1260
- _ => bug ! (
1261
- "Unexpected types: var={:?} diverging_var={:?}" ,
1262
- var,
1263
- diverging_var
1264
- ) ,
1265
- }
1266
- }
1267
- }
1268
-
1269
- let var_origin =
1270
- * fcx. infcx . type_variables . borrow ( ) . var_origin ( * best_var. unwrap ( ) ) ;
1271
- let diverging_var_span = fcx
1272
- . infcx
1273
- . type_variables
1274
- . borrow ( )
1275
- . var_origin ( * best_diverging_var. unwrap ( ) )
1276
- . span ;
1277
-
1278
- let mut err = fcx. tcx ( ) . sess . struct_span_warn (
1279
- path. span ,
1280
- "Fallback to `!` may introduce undefined behavior" ,
1281
- ) ;
1282
-
1283
- match var_origin. kind {
1284
- TypeVariableOriginKind :: TypeParameterDefinition ( name, did) => {
1285
- err. span_note (
1286
- var_origin. span ,
1287
- & format ! ( "the type parameter {} here was inferred to `!`" , name) ,
1288
- ) ;
1289
- if let Some ( did) = did {
1290
- err. span_note (
1291
- fcx. tcx . def_span ( did) ,
1292
- "(type parameter defined here)" ,
1293
- ) ;
1294
- }
1295
- }
1296
- _ => {
1297
- err. span_note ( var_origin. span , "the type here was inferred to `!`" ) ;
1298
- }
1299
- }
1300
-
1301
- err. span_note ( diverging_var_span, "... due to this expression" ) . emit ( ) ;
1302
- }
1303
- }
1304
- }
1112
+ never_compat. post_fallback ( & fcx) ;
1305
1113
1306
1114
// Even though coercion casts provide type hints, we check casts after fallback for
1307
1115
// backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
0 commit comments