@@ -3761,17 +3761,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3761
3761
error_code : & str ,
3762
3762
c_variadic : bool ,
3763
3763
sugg_unit : bool | {
3764
+ let ( span, start_span, args) = match & expr. kind {
3765
+ hir:: ExprKind :: Call ( hir:: Expr { span, .. } , args) => ( * span, * span, & args[ ..] ) ,
3766
+ hir:: ExprKind :: MethodCall ( path_segment, span, args) => (
3767
+ * span,
3768
+ // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3769
+ path_segment
3770
+ . args
3771
+ . and_then ( |args| args. args . iter ( ) . last ( ) )
3772
+ // Account for `foo.bar::<T>()`.
3773
+ . map ( |arg| {
3774
+ // Skip the closing `>`.
3775
+ tcx. sess
3776
+ . source_map ( )
3777
+ . next_point ( tcx. sess . source_map ( ) . next_point ( arg. span ( ) ) )
3778
+ } )
3779
+ . unwrap_or ( * span) ,
3780
+ & args[ 1 ..] , // Skip the receiver.
3781
+ ) ,
3782
+ k => span_bug ! ( sp, "checking argument types on a non-call: `{:?}`" , k) ,
3783
+ } ;
3784
+ let arg_spans = if args. is_empty ( ) {
3785
+ // foo()
3786
+ // ^^^-- supplied 0 arguments
3787
+ // |
3788
+ // expected 2 arguments
3789
+ vec ! [ tcx. sess. source_map( ) . next_point( start_span) . with_hi( sp. hi( ) ) ]
3790
+ } else {
3791
+ // foo(1, 2, 3)
3792
+ // ^^^ - - - supplied 3 arguments
3793
+ // |
3794
+ // expected 2 arguments
3795
+ args. iter ( ) . map ( |arg| arg. span ) . collect :: < Vec < Span > > ( )
3796
+ } ;
3797
+
3764
3798
let mut err = tcx. sess . struct_span_err_with_code (
3765
- sp ,
3799
+ span ,
3766
3800
& format ! (
3767
3801
"this function takes {}{} but {} {} supplied" ,
3768
3802
if c_variadic { "at least " } else { "" } ,
3769
- potentially_plural_count( expected_count, "parameter " ) ,
3770
- potentially_plural_count( arg_count, "parameter " ) ,
3803
+ potentially_plural_count( expected_count, "argument " ) ,
3804
+ potentially_plural_count( arg_count, "argument " ) ,
3771
3805
if arg_count == 1 { "was" } else { "were" }
3772
3806
) ,
3773
3807
DiagnosticId :: Error ( error_code. to_owned ( ) ) ,
3774
3808
) ;
3809
+ let label = format ! ( "supplied {}" , potentially_plural_count( arg_count, "argument" ) ) ;
3810
+ for ( i, span) in arg_spans. into_iter ( ) . enumerate ( ) {
3811
+ err. span_label (
3812
+ span,
3813
+ if arg_count == 0 || i + 1 == arg_count { & label } else { "" } ,
3814
+ ) ;
3815
+ }
3775
3816
3776
3817
if let Some ( def_s) = def_span. map ( |sp| tcx. sess . source_map ( ) . def_span ( sp) ) {
3777
3818
err. span_label ( def_s, "defined here" ) ;
@@ -3788,11 +3829,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3788
3829
) ;
3789
3830
} else {
3790
3831
err. span_label (
3791
- sp ,
3832
+ span ,
3792
3833
format ! (
3793
3834
"expected {}{}" ,
3794
3835
if c_variadic { "at least " } else { "" } ,
3795
- potentially_plural_count( expected_count, "parameter " )
3836
+ potentially_plural_count( expected_count, "argument " )
3796
3837
) ,
3797
3838
) ;
3798
3839
}
@@ -5494,8 +5535,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5494
5535
5495
5536
self . tcx . sess . span_err (
5496
5537
span,
5497
- "this function can only be invoked \
5498
- directly, not through a function pointer",
5538
+ "this function can only be invoked directly, not through a function pointer" ,
5499
5539
) ;
5500
5540
}
5501
5541
0 commit comments