@@ -3844,17 +3844,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3844
3844
error_code : & str ,
3845
3845
c_variadic : bool ,
3846
3846
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
+
3847
3881
let mut err = tcx. sess . struct_span_err_with_code (
3848
- sp ,
3882
+ span ,
3849
3883
& format ! (
3850
3884
"this function takes {}{} but {} {} supplied" ,
3851
3885
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 " ) ,
3854
3888
if arg_count == 1 { "was" } else { "were" }
3855
3889
) ,
3856
3890
DiagnosticId :: Error ( error_code. to_owned ( ) ) ,
3857
3891
) ;
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
+ }
3858
3899
3859
3900
if let Some ( def_s) = def_span. map ( |sp| tcx. sess . source_map ( ) . def_span ( sp) ) {
3860
3901
err. span_label ( def_s, "defined here" ) ;
@@ -3871,11 +3912,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3871
3912
) ;
3872
3913
} else {
3873
3914
err. span_label (
3874
- sp ,
3915
+ span ,
3875
3916
format ! (
3876
3917
"expected {}{}" ,
3877
3918
if c_variadic { "at least " } else { "" } ,
3878
- potentially_plural_count( expected_count, "parameter " )
3919
+ potentially_plural_count( expected_count, "argument " )
3879
3920
) ,
3880
3921
) ;
3881
3922
}
@@ -5577,8 +5618,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5577
5618
5578
5619
self . tcx . sess . span_err (
5579
5620
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" ,
5582
5622
) ;
5583
5623
}
5584
5624
0 commit comments