@@ -3844,17 +3844,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38443844 error_code : & str ,
38453845 c_variadic : bool ,
38463846 sugg_unit : bool | {
3847+ let ( span, start_span, args) = match & expr. kind {
3848+ hir:: ExprKind :: Call ( hir:: Expr { span, .. } , args) => ( * span, * span, & args[ ..] ) ,
3849+ hir:: ExprKind :: MethodCall ( path_segment, span, args) => (
3850+ * span,
3851+ // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3852+ path_segment
3853+ . args
3854+ . and_then ( |args| args. args . iter ( ) . last ( ) )
3855+ // Account for `foo.bar::<T>()`.
3856+ . map ( |arg| {
3857+ // Skip the closing `>`.
3858+ tcx. sess
3859+ . source_map ( )
3860+ . next_point ( tcx. sess . source_map ( ) . next_point ( arg. span ( ) ) )
3861+ } )
3862+ . unwrap_or ( * span) ,
3863+ & args[ 1 ..] , // Skip the receiver.
3864+ ) ,
3865+ k => span_bug ! ( sp, "checking argument types on a non-call: `{:?}`" , k) ,
3866+ } ;
3867+ let arg_spans = if args. is_empty ( ) {
3868+ // foo()
3869+ // ^^^-- supplied 0 arguments
3870+ // |
3871+ // expected 2 arguments
3872+ vec ! [ tcx. sess. source_map( ) . next_point( start_span) . with_hi( sp. hi( ) ) ]
3873+ } else {
3874+ // foo(1, 2, 3)
3875+ // ^^^ - - - supplied 3 arguments
3876+ // |
3877+ // expected 2 arguments
3878+ args. iter ( ) . map ( |arg| arg. span ) . collect :: < Vec < Span > > ( )
3879+ } ;
3880+
38473881 let mut err = tcx. sess . struct_span_err_with_code (
3848- sp ,
3882+ span ,
38493883 & format ! (
38503884 "this function takes {}{} but {} {} supplied" ,
38513885 if c_variadic { "at least " } else { "" } ,
3852- potentially_plural_count( expected_count, "parameter " ) ,
3853- potentially_plural_count( arg_count, "parameter " ) ,
3886+ potentially_plural_count( expected_count, "argument " ) ,
3887+ potentially_plural_count( arg_count, "argument " ) ,
38543888 if arg_count == 1 { "was" } else { "were" }
38553889 ) ,
38563890 DiagnosticId :: Error ( error_code. to_owned ( ) ) ,
38573891 ) ;
3892+ let label = format ! ( "supplied {}" , potentially_plural_count( arg_count, "argument" ) ) ;
3893+ for ( i, span) in arg_spans. into_iter ( ) . enumerate ( ) {
3894+ err. span_label (
3895+ span,
3896+ if arg_count == 0 || i + 1 == arg_count { & label } else { "" } ,
3897+ ) ;
3898+ }
38583899
38593900 if let Some ( def_s) = def_span. map ( |sp| tcx. sess . source_map ( ) . def_span ( sp) ) {
38603901 err. span_label ( def_s, "defined here" ) ;
@@ -3871,11 +3912,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38713912 ) ;
38723913 } else {
38733914 err. span_label (
3874- sp ,
3915+ span ,
38753916 format ! (
38763917 "expected {}{}" ,
38773918 if c_variadic { "at least " } else { "" } ,
3878- potentially_plural_count( expected_count, "parameter " )
3919+ potentially_plural_count( expected_count, "argument " )
38793920 ) ,
38803921 ) ;
38813922 }
@@ -5577,8 +5618,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
55775618
55785619 self . tcx . sess . span_err (
55795620 span,
5580- "this function can only be invoked \
5581- directly, not through a function pointer",
5621+ "this function can only be invoked directly, not through a function pointer" ,
55825622 ) ;
55835623 }
55845624
0 commit comments