@@ -3843,17 +3843,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38433843 error_code : & str ,
38443844 c_variadic : bool ,
38453845 sugg_unit : bool | {
3846+ let ( span, start_span, args) = match & expr. kind {
3847+ hir:: ExprKind :: Call ( hir:: Expr { span, .. } , args) => ( * span, * span, & args[ ..] ) ,
3848+ hir:: ExprKind :: MethodCall ( path_segment, span, args) => (
3849+ * span,
3850+ // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3851+ path_segment
3852+ . args
3853+ . and_then ( |args| args. args . iter ( ) . last ( ) )
3854+ // Account for `foo.bar::<T>()`.
3855+ . map ( |arg| {
3856+ // Skip the closing `>`.
3857+ tcx. sess
3858+ . source_map ( )
3859+ . next_point ( tcx. sess . source_map ( ) . next_point ( arg. span ( ) ) )
3860+ } )
3861+ . unwrap_or ( * span) ,
3862+ & args[ 1 ..] , // Skip the receiver.
3863+ ) ,
3864+ k => span_bug ! ( sp, "checking argument types on a non-call: `{:?}`" , k) ,
3865+ } ;
3866+ let arg_spans = if args. is_empty ( ) {
3867+ // foo()
3868+ // ^^^-- supplied 0 arguments
3869+ // |
3870+ // expected 2 arguments
3871+ vec ! [ tcx. sess. source_map( ) . next_point( start_span) . with_hi( sp. hi( ) ) ]
3872+ } else {
3873+ // foo(1, 2, 3)
3874+ // ^^^ - - - supplied 3 arguments
3875+ // |
3876+ // expected 2 arguments
3877+ args. iter ( ) . map ( |arg| arg. span ) . collect :: < Vec < Span > > ( )
3878+ } ;
3879+
38463880 let mut err = tcx. sess . struct_span_err_with_code (
3847- sp ,
3881+ span ,
38483882 & format ! (
38493883 "this function takes {}{} but {} {} supplied" ,
38503884 if c_variadic { "at least " } else { "" } ,
3851- potentially_plural_count( expected_count, "parameter " ) ,
3852- potentially_plural_count( arg_count, "parameter " ) ,
3885+ potentially_plural_count( expected_count, "argument " ) ,
3886+ potentially_plural_count( arg_count, "argument " ) ,
38533887 if arg_count == 1 { "was" } else { "were" }
38543888 ) ,
38553889 DiagnosticId :: Error ( error_code. to_owned ( ) ) ,
38563890 ) ;
3891+ let label = format ! ( "supplied {}" , potentially_plural_count( arg_count, "argument" ) ) ;
3892+ for ( i, span) in arg_spans. into_iter ( ) . enumerate ( ) {
3893+ err. span_label (
3894+ span,
3895+ if arg_count == 0 || i + 1 == arg_count { & label } else { "" } ,
3896+ ) ;
3897+ }
38573898
38583899 if let Some ( def_s) = def_span. map ( |sp| tcx. sess . source_map ( ) . def_span ( sp) ) {
38593900 err. span_label ( def_s, "defined here" ) ;
@@ -3870,11 +3911,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38703911 ) ;
38713912 } else {
38723913 err. span_label (
3873- sp ,
3914+ span ,
38743915 format ! (
38753916 "expected {}{}" ,
38763917 if c_variadic { "at least " } else { "" } ,
3877- potentially_plural_count( expected_count, "parameter " )
3918+ potentially_plural_count( expected_count, "argument " )
38783919 ) ,
38793920 ) ;
38803921 }
@@ -5622,8 +5663,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
56225663
56235664 self . tcx . sess . span_err (
56245665 span,
5625- "this function can only be invoked \
5626- directly, not through a function pointer",
5666+ "this function can only be invoked directly, not through a function pointer" ,
56275667 ) ;
56285668 }
56295669
0 commit comments