@@ -885,12 +885,12 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
885
885
} ;
886
886
887
887
// All type checking constraints were added, try to fallback unsolved variables.
888
- fcx. select_obligations_where_possible ( false ) ;
888
+ fcx. select_obligations_where_possible ( false , |_| { } ) ;
889
889
let mut fallback_has_occurred = false ;
890
890
for ty in & fcx. unsolved_variables ( ) {
891
891
fallback_has_occurred |= fcx. fallback_if_possible ( ty) ;
892
892
}
893
- fcx. select_obligations_where_possible ( fallback_has_occurred) ;
893
+ fcx. select_obligations_where_possible ( fallback_has_occurred, |_| { } ) ;
894
894
895
895
// Even though coercion casts provide type hints, we check casts after fallback for
896
896
// backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
@@ -2356,7 +2356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2356
2356
// possible. This can help substantially when there are
2357
2357
// indirect dependencies that don't seem worth tracking
2358
2358
// precisely.
2359
- self . select_obligations_where_possible ( false ) ;
2359
+ self . select_obligations_where_possible ( false , |_| { } ) ;
2360
2360
ty = self . resolve_vars_if_possible ( & ty) ;
2361
2361
2362
2362
debug ! ( "resolve_type_vars_with_obligations: ty={:?}" , ty) ;
@@ -2807,7 +2807,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2807
2807
fn resolve_generator_interiors ( & self , def_id : DefId ) {
2808
2808
let mut generators = self . deferred_generator_interiors . borrow_mut ( ) ;
2809
2809
for ( body_id, interior, kind) in generators. drain ( ..) {
2810
- self . select_obligations_where_possible ( false ) ;
2810
+ self . select_obligations_where_possible ( false , |_| { } ) ;
2811
2811
generator_interior:: resolve_interior ( self , def_id, body_id, interior, kind) ;
2812
2812
}
2813
2813
}
@@ -2844,8 +2844,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2844
2844
}
2845
2845
2846
2846
/// Select as many obligations as we can at present.
2847
- fn select_obligations_where_possible ( & self , fallback_has_occurred : bool ) {
2848
- if let Err ( errors) = self . fulfillment_cx . borrow_mut ( ) . select_where_possible ( self ) {
2847
+ fn select_obligations_where_possible (
2848
+ & self ,
2849
+ fallback_has_occurred : bool ,
2850
+ f : impl Fn ( & mut Vec < traits:: FulfillmentError < ' tcx > > ) ,
2851
+ ) {
2852
+ if let Err ( mut errors) = self . fulfillment_cx . borrow_mut ( ) . select_where_possible ( self ) {
2853
+ f ( & mut errors) ;
2849
2854
self . report_fulfillment_errors ( & errors, self . inh . body_id , fallback_has_occurred) ;
2850
2855
}
2851
2856
}
@@ -3267,20 +3272,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3267
3272
// an "opportunistic" vtable resolution of any trait bounds on
3268
3273
// the call. This helps coercions.
3269
3274
if check_closures {
3270
- // We don't use `select_obligations_where_possible` to try to figure out if the
3271
- // obligation is comming from a single fn call argument, and if it is, we point
3272
- // at the expression corresponding to that argument, instead of the call.
3273
- if let Err (
3274
- mut errors,
3275
- ) = self . fulfillment_cx . borrow_mut ( ) . select_where_possible ( self ) {
3275
+ self . select_obligations_where_possible ( false , |errors| {
3276
3276
self . point_at_arg_instead_of_call_if_possible (
3277
- & mut errors,
3277
+ errors,
3278
3278
& final_arg_types[ ..] ,
3279
3279
sp,
3280
3280
& args,
3281
3281
) ;
3282
- self . report_fulfillment_errors ( & errors, self . inh . body_id , false ) ;
3283
- }
3282
+ } )
3284
3283
}
3285
3284
3286
3285
// For C-variadic functions, we don't have a declared type for all of
@@ -3394,8 +3393,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3394
3393
}
3395
3394
}
3396
3395
}
3397
- if referenced_in. len ( ) == 1 {
3398
- error. obligation . cause . span = args[ referenced_in[ 0 ] ] . span ;
3396
+ let mut referenced_in = final_arg_types. iter ( )
3397
+ . flat_map ( |( i, ty) | {
3398
+ let ty = self . resolve_vars_if_possible ( ty) ;
3399
+ ty. walk ( )
3400
+ . filter ( |& ty| ty == predicate. skip_binder ( ) . self_ty ( ) )
3401
+ . map ( move |_| * i)
3402
+ } ) ;
3403
+ if let ( Some ( ref_in) , None ) = ( referenced_in. next ( ) , referenced_in. next ( ) ) {
3404
+ // We make sure that only *one* argument matches the obligation failure
3405
+ // and thet the obligation's span to its expression's.
3406
+ error. obligation . cause . span = args[ ref_in] . span ;
3399
3407
error. points_at_arg_span = true ;
3400
3408
}
3401
3409
}
0 commit comments