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