@@ -1231,6 +1231,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1231
1231
self . ccx . tcx . sess . err_count ( ) - self . err_count_on_creation
1232
1232
}
1233
1233
1234
+ /// Resolves type variables in `ty` if possible. Unlike the infcx
1235
+ /// version, this version will also select obligations if it seems
1236
+ /// useful, in an effort to get more type information.
1237
+ fn resolve_type_vars_if_possible ( & self , mut ty : Ty < ' tcx > ) -> Ty < ' tcx > {
1238
+ // No ty::infer()? Nothing needs doing.
1239
+ if !ty:: type_has_ty_infer ( ty) {
1240
+ return ty;
1241
+ }
1242
+
1243
+ // If `ty` is a type variable, see whether we already know what it is.
1244
+ ty = self . infcx ( ) . resolve_type_vars_if_possible ( & ty) ;
1245
+ if !ty:: type_has_ty_infer ( ty) {
1246
+ return ty;
1247
+ }
1248
+
1249
+ // If not, try resolving any new fcx obligations that have cropped up.
1250
+ vtable:: select_new_fcx_obligations ( self ) ;
1251
+ ty = self . infcx ( ) . resolve_type_vars_if_possible ( & ty) ;
1252
+ if !ty:: type_has_ty_infer ( ty) {
1253
+ return ty;
1254
+ }
1255
+
1256
+ // If not, try resolving *all* pending obligations as much as
1257
+ // possible. This can help substantially when there are
1258
+ // indirect dependencies that don't seem worth tracking
1259
+ // precisely.
1260
+ vtable:: select_fcx_obligations_where_possible ( self ) ;
1261
+ self . infcx ( ) . resolve_type_vars_if_possible ( & ty)
1262
+ }
1263
+
1234
1264
/// Resolves all type variables in `t` and then, if any were left
1235
1265
/// unresolved, substitutes an error type. This is used after the
1236
1266
/// main checking when doing a second pass before writeback. The
@@ -2321,9 +2351,9 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2321
2351
let check_blocks = * check_blocks;
2322
2352
debug ! ( "check_blocks={}" , check_blocks) ;
2323
2353
2324
- // More awful hacks: before we check the blocks , try to do
2325
- // an "opportunistic" vtable resolution of any trait
2326
- // bounds on the call.
2354
+ // More awful hacks: before we check argument types , try to do
2355
+ // an "opportunistic" vtable resolution of any trait bounds on
2356
+ // the call. This helps coercions .
2327
2357
if check_blocks {
2328
2358
vtable:: select_new_fcx_obligations ( fcx) ;
2329
2359
}
@@ -2863,7 +2893,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2863
2893
// Shift is a special case: rhs must be uint, no matter what lhs is
2864
2894
check_expr ( fcx, & * * rhs) ;
2865
2895
let rhs_ty = fcx. expr_ty ( & * * rhs) ;
2866
- let rhs_ty = fcx. infcx ( ) . resolve_type_vars_if_possible ( & rhs_ty) ;
2896
+ let rhs_ty = structurally_resolved_type ( fcx, rhs . span , rhs_ty) ;
2867
2897
if ty:: type_is_integral ( rhs_ty) {
2868
2898
fcx. write_ty ( expr. id , lhs_t) ;
2869
2899
} else {
@@ -5115,21 +5145,12 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
5115
5145
5116
5146
// Resolves `typ` by a single level if `typ` is a type variable. If no
5117
5147
// resolution is possible, then an error is reported.
5118
- pub fn structurally_resolved_type < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > , sp : Span ,
5119
- mut ty : Ty < ' tcx > ) -> Ty < ' tcx > {
5120
- // If `ty` is a type variable, see whether we already know what it is.
5121
- ty = fcx. infcx ( ) . shallow_resolve ( ty) ;
5122
-
5123
- // If not, try resolve pending fcx obligations. Those can shed light.
5124
- //
5125
- // FIXME(#18391) -- This current strategy can lead to bad performance in
5126
- // extreme cases. We probably ought to smarter in general about
5127
- // only resolving when we need help and only resolving obligations
5128
- // will actually help.
5129
- if ty:: type_is_ty_var ( ty) {
5130
- vtable:: select_fcx_obligations_where_possible ( fcx) ;
5131
- ty = fcx. infcx ( ) . shallow_resolve ( ty) ;
5132
- }
5148
+ pub fn structurally_resolved_type < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > ,
5149
+ sp : Span ,
5150
+ ty : Ty < ' tcx > )
5151
+ -> Ty < ' tcx >
5152
+ {
5153
+ let mut ty = fcx. resolve_type_vars_if_possible ( ty) ;
5133
5154
5134
5155
// If not, error.
5135
5156
if ty:: type_is_ty_var ( ty) {
0 commit comments