@@ -3070,12 +3070,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30703070 fn check_method_argument_types (
30713071 & self ,
30723072 sp : Span ,
3073- expr_sp : Span ,
3073+ expr : & ' tcx hir :: Expr ,
30743074 method : Result < MethodCallee < ' tcx > , ( ) > ,
30753075 args_no_rcvr : & ' tcx [ hir:: Expr ] ,
30763076 tuple_arguments : TupleArgumentsFlag ,
30773077 expected : Expectation < ' tcx > ,
30783078 ) -> Ty < ' tcx > {
3079+
30793080 let has_error = match method {
30803081 Ok ( method) => {
30813082 method. substs . references_error ( ) || method. sig . references_error ( )
@@ -3090,8 +3091,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30903091 TupleArguments => vec ! [ self . tcx. intern_tup( & err_inputs[ ..] ) ] ,
30913092 } ;
30923093
3093- self . check_argument_types ( sp, expr_sp, & err_inputs[ ..] , & [ ] , args_no_rcvr,
3094- false , tuple_arguments, None ) ;
3094+ self . check_argument_types (
3095+ sp,
3096+ expr,
3097+ & err_inputs[ ..] ,
3098+ & [ ] ,
3099+ args_no_rcvr,
3100+ false ,
3101+ tuple_arguments,
3102+ None ,
3103+ ) ;
30953104 return self . tcx . types . err ;
30963105 }
30973106
@@ -3103,9 +3112,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31033112 method. sig . output ( ) ,
31043113 & method. sig . inputs ( ) [ 1 ..]
31053114 ) ;
3106- self . check_argument_types ( sp, expr_sp, & method. sig . inputs ( ) [ 1 ..] , & expected_arg_tys[ ..] ,
3107- args_no_rcvr, method. sig . c_variadic , tuple_arguments,
3108- self . tcx . hir ( ) . span_if_local ( method. def_id ) ) ;
3115+ self . check_argument_types (
3116+ sp,
3117+ expr,
3118+ & method. sig . inputs ( ) [ 1 ..] ,
3119+ & expected_arg_tys[ ..] ,
3120+ args_no_rcvr,
3121+ method. sig . c_variadic ,
3122+ tuple_arguments,
3123+ self . tcx . hir ( ) . span_if_local ( method. def_id ) ,
3124+ ) ;
31093125 method. sig . output ( )
31103126 }
31113127
@@ -3182,7 +3198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31823198 fn check_argument_types (
31833199 & self ,
31843200 sp : Span ,
3185- expr_sp : Span ,
3201+ expr : & ' tcx hir :: Expr ,
31863202 fn_inputs : & [ Ty < ' tcx > ] ,
31873203 expected_arg_tys : & [ Ty < ' tcx > ] ,
31883204 args : & ' tcx [ hir:: Expr ] ,
@@ -3191,7 +3207,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31913207 def_span : Option < Span > ,
31923208 ) {
31933209 let tcx = self . tcx ;
3194-
31953210 // Grab the argument types, supplying fresh type variables
31963211 // if the wrong number of arguments were supplied
31973212 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
@@ -3225,7 +3240,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32253240 err. span_label ( def_s, "defined here" ) ;
32263241 }
32273242 if sugg_unit {
3228- let sugg_span = tcx. sess . source_map ( ) . end_point ( expr_sp ) ;
3243+ let sugg_span = tcx. sess . source_map ( ) . end_point ( expr . span ) ;
32293244 // remove closing `)` from the span
32303245 let sugg_span = sugg_span. shrink_to_lo ( ) ;
32313246 err. span_suggestion (
@@ -3319,6 +3334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
33193334 // the call. This helps coercions.
33203335 if check_closures {
33213336 self . select_obligations_where_possible ( false , |errors| {
3337+ self . point_at_type_arg_instead_of_call_if_possible ( errors, expr) ;
33223338 self . point_at_arg_instead_of_call_if_possible (
33233339 errors,
33243340 & final_arg_types[ ..] ,
@@ -3456,6 +3472,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
34563472 }
34573473 }
34583474
3475+ /// Given a vec of evaluated `FullfillmentError`s and an `fn` call expression, we walk the
3476+ /// `PathSegment`s and resolve their type parameters to see if any of the `FullfillmentError`s
3477+ /// were caused by them. If they were, we point at the corresponding type argument's span
3478+ /// instead of the `fn` call path span.
3479+ fn point_at_type_arg_instead_of_call_if_possible (
3480+ & self ,
3481+ errors : & mut Vec < traits:: FulfillmentError < ' _ > > ,
3482+ call_expr : & ' tcx hir:: Expr ,
3483+ ) {
3484+ if let hir:: ExprKind :: Call ( path, _args) = & call_expr. node {
3485+ if let hir:: ExprKind :: Path ( qpath) = & path. node {
3486+ if let hir:: QPath :: Resolved ( _self, path) = & qpath {
3487+ for error in errors {
3488+ if let ty:: Predicate :: Trait ( predicate) = error. obligation . predicate {
3489+ // If any of the type arguments in this path segment caused the
3490+ // `FullfillmentError`, point at its span (#61860).
3491+ for segment in & path. segments {
3492+ if let Some ( args) = & segment. args {
3493+ for arg in & args. args {
3494+ if let hir:: GenericArg :: Type ( hir_ty) = & arg {
3495+ if let hir:: TyKind :: Path (
3496+ hir:: QPath :: TypeRelative ( ..) ,
3497+ ) = & hir_ty. node {
3498+ // Avoid ICE with associated types. As this is best
3499+ // effort only, it's ok to ignore the case. It
3500+ // would trigger in `is_send::<T::AssocType>();`
3501+ // from `typeck-default-trait-impl-assoc-type.rs`.
3502+ } else {
3503+ let ty = AstConv :: ast_ty_to_ty ( self , hir_ty) ;
3504+ let ty = self . resolve_vars_if_possible ( & ty) ;
3505+ if ty == predicate. skip_binder ( ) . self_ty ( ) {
3506+ error. obligation . cause . span = hir_ty. span ;
3507+ }
3508+ }
3509+ }
3510+ }
3511+ }
3512+ }
3513+ }
3514+ }
3515+ }
3516+ }
3517+ }
3518+ }
3519+
34593520 // AST fragment checking
34603521 fn check_lit ( & self ,
34613522 lit : & hir:: Lit ,
0 commit comments