@@ -62,7 +62,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6262 || self . suggest_coercing_result_via_try_operator ( err, expr, expected, expr_ty) ;
6363
6464 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+ ) ;
6670 }
6771 }
6872
@@ -222,7 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
222226 & self ,
223227 err : & mut Diagnostic ,
224228 expr : & hir:: Expr < ' _ > ,
225- expected_ty : Ty < ' tcx > ,
229+ source : TypeMismatchSource < ' tcx > ,
226230 ) -> bool {
227231 let hir = self . tcx . hir ( ) ;
228232
@@ -295,6 +299,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
295299 } ,
296300 } ;
297301
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+
298342 if !self . can_eq ( self . param_env , expected_ty, init_ty. fold_with ( & mut fudger) ) {
299343 return false ;
300344 }
@@ -360,7 +404,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
360404 "... which constrains `{ident}` to have type `{next_use_ty}`"
361405 ) ,
362406 ) ;
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+ {
364410 self . emit_type_mismatch_suggestions (
365411 err,
366412 arg_expr,
@@ -2044,3 +2090,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20442090 }
20452091 }
20462092}
2093+
2094+ pub enum TypeMismatchSource < ' tcx > {
2095+ Ty ( Ty < ' tcx > ) ,
2096+ Arg ( & ' tcx hir:: Expr < ' tcx > , usize ) ,
2097+ }
0 commit comments