@@ -440,30 +440,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
440440 call_expr : & hir:: Expr < ' tcx > ,
441441 ) {
442442 // Next, let's construct the error
443- let ( error_span, full_call_span, ctor_of) = match & call_expr. kind {
443+ let ( error_span, full_call_span, ctor_of, is_method ) = match & call_expr. kind {
444444 hir:: ExprKind :: Call (
445445 hir:: Expr { hir_id, span, kind : hir:: ExprKind :: Path ( qpath) , .. } ,
446446 _,
447447 ) => {
448448 if let Res :: Def ( DefKind :: Ctor ( of, _) , _) =
449449 self . typeck_results . borrow ( ) . qpath_res ( qpath, * hir_id)
450450 {
451- ( call_span, * span, Some ( of) )
451+ ( call_span, * span, Some ( of) , false )
452452 } else {
453- ( call_span, * span, None )
453+ ( call_span, * span, None , false )
454454 }
455455 }
456- hir:: ExprKind :: Call ( hir:: Expr { span, .. } , _) => ( call_span, * span, None ) ,
456+ hir:: ExprKind :: Call ( hir:: Expr { span, .. } , _) => ( call_span, * span, None , false ) ,
457457 hir:: ExprKind :: MethodCall ( path_segment, _, span) => {
458458 let ident_span = path_segment. ident . span ;
459459 let ident_span = if let Some ( args) = path_segment. args {
460460 ident_span. with_hi ( args. span_ext . hi ( ) )
461461 } else {
462462 ident_span
463463 } ;
464- (
465- * span, ident_span, None , // methods are never ctors
466- )
464+ // methods are never ctors
465+ ( * span, ident_span, None , true )
467466 }
468467 k => span_bug ! ( call_span, "checking argument types on a non-call: `{:?}`" , k) ,
469468 } ;
@@ -659,7 +658,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
659658 Applicability :: MachineApplicable ,
660659 ) ;
661660 } ;
662- self . label_fn_like ( & mut err, fn_def_id, callee_ty) ;
661+ self . label_fn_like ( & mut err, fn_def_id, callee_ty, Some ( mismatch_idx ) , is_method ) ;
663662 err. emit ( ) ;
664663 return ;
665664 }
@@ -701,16 +700,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
701700 }
702701
703702 errors. drain_filter ( |error| {
704- let Error :: Invalid ( provided_idx, expected_idx, Compatibility :: Incompatible ( error ) ) = error else { return false } ;
703+ let Error :: Invalid ( provided_idx, expected_idx, Compatibility :: Incompatible ( Some ( e ) ) ) = error else { return false } ;
705704 let ( provided_ty, provided_span) = provided_arg_tys[ * provided_idx] ;
706705 let ( expected_ty, _) = formal_and_expected_inputs[ * expected_idx] ;
707706 let cause = & self . misc ( provided_span) ;
708707 let trace = TypeTrace :: types ( cause, true , expected_ty, provided_ty) ;
709- if let Some ( e) = error {
710- if !matches ! ( trace. cause. as_failure_code( e) , FailureCode :: Error0308 ( _) ) {
711- self . report_and_explain_type_error ( trace, e) . emit ( ) ;
712- return true ;
713- }
708+ if !matches ! ( trace. cause. as_failure_code( e) , FailureCode :: Error0308 ( _) ) {
709+ self . report_and_explain_type_error ( trace, e) . emit ( ) ;
710+ return true ;
714711 }
715712 false
716713 } ) ;
@@ -749,7 +746,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
749746 format ! ( "arguments to this {} are incorrect" , call_name) ,
750747 ) ;
751748 // Call out where the function is defined
752- self . label_fn_like ( & mut err, fn_def_id, callee_ty) ;
749+ self . label_fn_like (
750+ & mut err,
751+ fn_def_id,
752+ callee_ty,
753+ Some ( expected_idx. as_usize ( ) ) ,
754+ is_method,
755+ ) ;
753756 err. emit ( ) ;
754757 return ;
755758 }
@@ -1031,7 +1034,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10311034 }
10321035
10331036 // Call out where the function is defined
1034- self . label_fn_like ( & mut err, fn_def_id, callee_ty) ;
1037+ self . label_fn_like ( & mut err, fn_def_id, callee_ty, None , is_method ) ;
10351038
10361039 // And add a suggestion block for all of the parameters
10371040 let suggestion_text = match suggestion_text {
@@ -1781,6 +1784,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17811784 err : & mut Diagnostic ,
17821785 callable_def_id : Option < DefId > ,
17831786 callee_ty : Option < Ty < ' tcx > > ,
1787+ // A specific argument should be labeled, instead of all of them
1788+ expected_idx : Option < usize > ,
1789+ is_method : bool ,
17841790 ) {
17851791 let Some ( mut def_id) = callable_def_id else {
17861792 return ;
@@ -1881,14 +1887,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18811887 . get_if_local ( def_id)
18821888 . and_then ( |node| node. body_id ( ) )
18831889 . into_iter ( )
1884- . flat_map ( |id| self . tcx . hir ( ) . body ( id) . params ) ;
1890+ . flat_map ( |id| self . tcx . hir ( ) . body ( id) . params )
1891+ . skip ( if is_method { 1 } else { 0 } ) ;
18851892
1886- for param in params {
1893+ for ( _, param) in params
1894+ . into_iter ( )
1895+ . enumerate ( )
1896+ . filter ( |( idx, _) | expected_idx. map_or ( true , |expected_idx| expected_idx == * idx) )
1897+ {
18871898 spans. push_span_label ( param. span , "" ) ;
18881899 }
18891900
18901901 let def_kind = self . tcx . def_kind ( def_id) ;
18911902 err. span_note ( spans, & format ! ( "{} defined here" , def_kind. descr( def_id) ) ) ;
1903+ } else if let Some ( hir:: Node :: Expr ( e) ) = self . tcx . hir ( ) . get_if_local ( def_id)
1904+ && let hir:: ExprKind :: Closure ( hir:: Closure { body, .. } ) = & e. kind
1905+ {
1906+ let param = expected_idx
1907+ . and_then ( |expected_idx| self . tcx . hir ( ) . body ( * body) . params . get ( expected_idx) ) ;
1908+ let ( kind, span) = if let Some ( param) = param {
1909+ ( "closure parameter" , param. span )
1910+ } else {
1911+ ( "closure" , self . tcx . def_span ( def_id) )
1912+ } ;
1913+ err. span_note ( span, & format ! ( "{} defined here" , kind) ) ;
18921914 } else {
18931915 let def_kind = self . tcx . def_kind ( def_id) ;
18941916 err. span_note (
0 commit comments