@@ -3070,12 +3070,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3070
3070
fn check_method_argument_types (
3071
3071
& self ,
3072
3072
sp : Span ,
3073
- expr_sp : Span ,
3073
+ expr : & ' tcx hir :: Expr ,
3074
3074
method : Result < MethodCallee < ' tcx > , ( ) > ,
3075
3075
args_no_rcvr : & ' tcx [ hir:: Expr ] ,
3076
3076
tuple_arguments : TupleArgumentsFlag ,
3077
3077
expected : Expectation < ' tcx > ,
3078
3078
) -> Ty < ' tcx > {
3079
+
3079
3080
let has_error = match method {
3080
3081
Ok ( method) => {
3081
3082
method. substs . references_error ( ) || method. sig . references_error ( )
@@ -3090,8 +3091,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3090
3091
TupleArguments => vec ! [ self . tcx. intern_tup( & err_inputs[ ..] ) ] ,
3091
3092
} ;
3092
3093
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
+ ) ;
3095
3104
return self . tcx . types . err ;
3096
3105
}
3097
3106
@@ -3103,9 +3112,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3103
3112
method. sig . output ( ) ,
3104
3113
& method. sig . inputs ( ) [ 1 ..]
3105
3114
) ;
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
+ ) ;
3109
3125
method. sig . output ( )
3110
3126
}
3111
3127
@@ -3182,7 +3198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3182
3198
fn check_argument_types (
3183
3199
& self ,
3184
3200
sp : Span ,
3185
- expr_sp : Span ,
3201
+ expr : & ' tcx hir :: Expr ,
3186
3202
fn_inputs : & [ Ty < ' tcx > ] ,
3187
3203
expected_arg_tys : & [ Ty < ' tcx > ] ,
3188
3204
args : & ' tcx [ hir:: Expr ] ,
@@ -3191,7 +3207,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3191
3207
def_span : Option < Span > ,
3192
3208
) {
3193
3209
let tcx = self . tcx ;
3194
-
3195
3210
// Grab the argument types, supplying fresh type variables
3196
3211
// if the wrong number of arguments were supplied
3197
3212
let supplied_arg_count = if tuple_arguments == DontTupleArguments {
@@ -3225,7 +3240,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3225
3240
err. span_label ( def_s, "defined here" ) ;
3226
3241
}
3227
3242
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 ) ;
3229
3244
// remove closing `)` from the span
3230
3245
let sugg_span = sugg_span. shrink_to_lo ( ) ;
3231
3246
err. span_suggestion (
@@ -3319,6 +3334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3319
3334
// the call. This helps coercions.
3320
3335
if check_closures {
3321
3336
self . select_obligations_where_possible ( false , |errors| {
3337
+ self . point_at_type_arg_instead_of_call_if_possible ( errors, expr) ;
3322
3338
self . point_at_arg_instead_of_call_if_possible (
3323
3339
errors,
3324
3340
& final_arg_types[ ..] ,
@@ -3456,6 +3472,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3456
3472
}
3457
3473
}
3458
3474
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
+
3459
3520
// AST fragment checking
3460
3521
fn check_lit ( & self ,
3461
3522
lit : & hir:: Lit ,
0 commit comments