@@ -62,7 +62,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
62
62
|| self . suggest_coercing_result_via_try_operator ( err, expr, expected, expr_ty) ;
63
63
64
64
if !suggested {
65
- self . note_source_of_type_mismatch_constraint ( err, expr, expected) ;
65
+ self . note_source_of_type_mismatch_constraint (
66
+ err,
67
+ expr,
68
+ TypeMismatchSource :: Ty ( expected) ,
69
+ ) ;
66
70
}
67
71
}
68
72
@@ -222,7 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
222
226
& self ,
223
227
err : & mut Diagnostic ,
224
228
expr : & hir:: Expr < ' _ > ,
225
- expected_ty : Ty < ' tcx > ,
229
+ source : TypeMismatchSource < ' tcx > ,
226
230
) -> bool {
227
231
let hir = self . tcx . hir ( ) ;
228
232
@@ -295,6 +299,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
295
299
} ,
296
300
} ;
297
301
302
+ let expected_ty = match source {
303
+ TypeMismatchSource :: Ty ( expected_ty) => expected_ty,
304
+ TypeMismatchSource :: Arg ( call_expr, idx) => {
305
+ let hir:: ExprKind :: MethodCall ( segment, _, args, _) = call_expr. kind else {
306
+ return false ;
307
+ } ;
308
+ let Some ( arg_ty) = self . node_ty_opt ( args[ idx] . hir_id ) else {
309
+ return false ;
310
+ } ;
311
+ let possible_rcvr_ty = expr_finder. uses . iter ( ) . find_map ( |binding| {
312
+ let possible_rcvr_ty = self . node_ty_opt ( binding. hir_id ) ?;
313
+ let possible_rcvr_ty = possible_rcvr_ty. fold_with ( & mut fudger) ;
314
+ let method = self
315
+ . lookup_method (
316
+ possible_rcvr_ty,
317
+ segment,
318
+ DUMMY_SP ,
319
+ call_expr,
320
+ binding,
321
+ args,
322
+ )
323
+ . ok ( ) ?;
324
+ let _ = self
325
+ . at ( & ObligationCause :: dummy ( ) , self . param_env )
326
+ . eq ( DefineOpaqueTypes :: No , method. sig . inputs ( ) [ idx + 1 ] , arg_ty)
327
+ . ok ( ) ?;
328
+ self . select_obligations_where_possible ( |errs| {
329
+ // Yeet the errors, we're already reporting errors.
330
+ errs. clear ( ) ;
331
+ } ) ;
332
+ Some ( self . resolve_vars_if_possible ( possible_rcvr_ty) )
333
+ } ) ;
334
+ if let Some ( rcvr_ty) = possible_rcvr_ty {
335
+ rcvr_ty
336
+ } else {
337
+ return false ;
338
+ }
339
+ }
340
+ } ;
341
+
298
342
if !self . can_eq ( self . param_env , expected_ty, init_ty. fold_with ( & mut fudger) ) {
299
343
return false ;
300
344
}
@@ -360,7 +404,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
360
404
"... which constrains `{ident}` to have type `{next_use_ty}`"
361
405
) ,
362
406
) ;
363
- if let Ok ( ideal_method_sig) = ideal_method_sig {
407
+ if matches ! ( source, TypeMismatchSource :: Ty ( _) )
408
+ && let Ok ( ideal_method_sig) = ideal_method_sig
409
+ {
364
410
self . emit_type_mismatch_suggestions (
365
411
err,
366
412
arg_expr,
@@ -2044,3 +2090,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2044
2090
}
2045
2091
}
2046
2092
}
2093
+
2094
+ pub enum TypeMismatchSource < ' tcx > {
2095
+ Ty ( Ty < ' tcx > ) ,
2096
+ Arg ( & ' tcx hir:: Expr < ' tcx > , usize ) ,
2097
+ }
0 commit comments