@@ -885,12 +885,12 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
885885 } ;
886886
887887 // 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 , |_| { } ) ;
889889 let mut fallback_has_occurred = false ;
890890 for ty in & fcx. unsolved_variables ( ) {
891891 fallback_has_occurred |= fcx. fallback_if_possible ( ty) ;
892892 }
893- fcx. select_obligations_where_possible ( fallback_has_occurred) ;
893+ fcx. select_obligations_where_possible ( fallback_has_occurred, |_| { } ) ;
894894
895895 // Even though coercion casts provide type hints, we check casts after fallback for
896896 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
@@ -2356,7 +2356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23562356 // possible. This can help substantially when there are
23572357 // indirect dependencies that don't seem worth tracking
23582358 // precisely.
2359- self . select_obligations_where_possible ( false ) ;
2359+ self . select_obligations_where_possible ( false , |_| { } ) ;
23602360 ty = self . resolve_vars_if_possible ( & ty) ;
23612361
23622362 debug ! ( "resolve_type_vars_with_obligations: ty={:?}" , ty) ;
@@ -2807,7 +2807,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28072807 fn resolve_generator_interiors ( & self , def_id : DefId ) {
28082808 let mut generators = self . deferred_generator_interiors . borrow_mut ( ) ;
28092809 for ( body_id, interior, kind) in generators. drain ( ..) {
2810- self . select_obligations_where_possible ( false ) ;
2810+ self . select_obligations_where_possible ( false , |_| { } ) ;
28112811 generator_interior:: resolve_interior ( self , def_id, body_id, interior, kind) ;
28122812 }
28132813 }
@@ -2844,8 +2844,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28442844 }
28452845
28462846 /// 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) ;
28492854 self . report_fulfillment_errors ( & errors, self . inh . body_id , fallback_has_occurred) ;
28502855 }
28512856 }
@@ -3267,20 +3272,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32673272 // an "opportunistic" vtable resolution of any trait bounds on
32683273 // the call. This helps coercions.
32693274 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| {
32763276 self . point_at_arg_instead_of_call_if_possible (
3277- & mut errors,
3277+ errors,
32783278 & final_arg_types[ ..] ,
32793279 sp,
32803280 & args,
32813281 ) ;
3282- self . report_fulfillment_errors ( & errors, self . inh . body_id , false ) ;
3283- }
3282+ } )
32843283 }
32853284
32863285 // For C-variadic functions, we don't have a declared type for all of
@@ -3394,8 +3393,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
33943393 }
33953394 }
33963395 }
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 ;
33993407 error. points_at_arg_span = true ;
34003408 }
34013409 }
0 commit comments