Skip to content

Commit b9d5a6b

Browse files
committed
Don't leave a comma at the start of argument list when removing arguments
1 parent 6975b77 commit b9d5a6b

File tree

5 files changed

+73
-19
lines changed

5 files changed

+73
-19
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+38-6
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_hir_analysis::astconv::AstConv;
2121
use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
2222
use rustc_hir_analysis::check::potentially_plural_count;
2323
use rustc_hir_analysis::structured_errors::StructuredDiagnostic;
24-
use rustc_index::vec::IndexVec;
24+
use rustc_index::vec::{Idx, IndexVec};
2525
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
2626
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
2727
use rustc_infer::infer::TypeTrace;
@@ -31,7 +31,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
3131
use rustc_middle::ty::{self, IsSuggestable, Ty};
3232
use rustc_session::Session;
3333
use rustc_span::symbol::{kw, Ident};
34-
use rustc_span::{self, sym, Span};
34+
use rustc_span::{self, sym, BytePos, Span};
3535
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
3636

3737
use std::iter;
@@ -894,8 +894,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
894894
};
895895

896896
let mut errors = errors.into_iter().peekable();
897+
let mut only_extras_so_far = errors
898+
.peek()
899+
.map_or(false, |first| matches!(first, Error::Extra(arg_idx) if arg_idx.index() == 0));
897900
let mut suggestions = vec![];
898901
while let Some(error) = errors.next() {
902+
only_extras_so_far &= matches!(error, Error::Extra(_));
903+
899904
match error {
900905
Error::Invalid(provided_idx, expected_idx, compatibility) => {
901906
let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
@@ -941,10 +946,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
941946
if arg_idx.index() > 0
942947
&& let Some((_, prev)) = provided_arg_tys
943948
.get(ProvidedIdx::from_usize(arg_idx.index() - 1)
944-
) {
945-
// Include previous comma
946-
span = prev.shrink_to_hi().to(span);
947-
}
949+
) {
950+
// Include previous comma
951+
span = prev.shrink_to_hi().to(span);
952+
}
953+
954+
// Is last argument for deletion in a row starting from the 0-th argument?
955+
// Then delete the next comma, so we are not left with `f(, ...)`
956+
//
957+
// fn f() {}
958+
// - f(0, 1,)
959+
// + f()
960+
if only_extras_so_far
961+
&& errors
962+
.peek()
963+
.map_or(true, |next_error| !matches!(next_error, Error::Extra(_)))
964+
{
965+
let next = provided_arg_tys
966+
.get(arg_idx.plus(1))
967+
.map(|&(_, sp)| sp)
968+
.unwrap_or_else(|| {
969+
// Subtract one to move before `)`
970+
call_expr
971+
.span
972+
.shrink_to_hi()
973+
.with_lo(call_expr.span.hi() - BytePos(1))
974+
});
975+
976+
// Include next comma
977+
span = span.until(next);
978+
}
979+
948980
suggestions.push((span, String::new()));
949981

950982
suggestion_text = match suggestion_text {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// run-rustfix
2+
3+
fn f() {}
4+
fn i(_: u32) {}
5+
fn is(_: u32, _: &str) {}
6+
fn s(_: &str) {}
7+
8+
fn main() {
9+
// code expected suggestion
10+
f(); // f()
11+
//~^ error: this function takes 0 arguments but 2 arguments were supplied
12+
i(0,); // i(0,)
13+
//~^ error: this function takes 1 argument but 3 arguments were supplied
14+
i(0); // i(0)
15+
//~^ error: this function takes 1 argument but 3 arguments were supplied
16+
is(0, ""); // is(0, "")
17+
//~^ error: this function takes 2 arguments but 4 arguments were supplied
18+
s(""); // s("")
19+
//~^ error: this function takes 1 argument but 3 arguments were supplied
20+
}

tests/ui/argument-suggestions/issue-109425.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// run-rustfix
2+
13
fn f() {}
24
fn i(_: u32) {}
35
fn is(_: u32, _: &str) {}

tests/ui/argument-suggestions/issue-109425.stderr

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
error[E0061]: this function takes 0 arguments but 2 arguments were supplied
2-
--> $DIR/issue-109425.rs:8:5
2+
--> $DIR/issue-109425.rs:10:5
33
|
44
LL | f(0, 1,); // f()
55
| ^ - - unexpected argument of type `{integer}`
66
| |
77
| unexpected argument of type `{integer}`
88
|
99
note: function defined here
10-
--> $DIR/issue-109425.rs:1:4
10+
--> $DIR/issue-109425.rs:3:4
1111
|
1212
LL | fn f() {}
1313
| ^
1414
help: remove the extra arguments
1515
|
1616
LL - f(0, 1,); // f()
17-
LL + f(,); // f()
17+
LL + f(); // f()
1818
|
1919

2020
error[E0061]: this function takes 1 argument but 3 arguments were supplied
21-
--> $DIR/issue-109425.rs:10:5
21+
--> $DIR/issue-109425.rs:12:5
2222
|
2323
LL | i(0, 1, 2,); // i(0,)
2424
| ^ - - unexpected argument of type `{integer}`
2525
| |
2626
| unexpected argument of type `{integer}`
2727
|
2828
note: function defined here
29-
--> $DIR/issue-109425.rs:2:4
29+
--> $DIR/issue-109425.rs:4:4
3030
|
3131
LL | fn i(_: u32) {}
3232
| ^ ------
@@ -37,15 +37,15 @@ LL + i(0,); // i(0,)
3737
|
3838

3939
error[E0061]: this function takes 1 argument but 3 arguments were supplied
40-
--> $DIR/issue-109425.rs:12:5
40+
--> $DIR/issue-109425.rs:14:5
4141
|
4242
LL | i(0, 1, 2); // i(0)
4343
| ^ - - unexpected argument of type `{integer}`
4444
| |
4545
| unexpected argument of type `{integer}`
4646
|
4747
note: function defined here
48-
--> $DIR/issue-109425.rs:2:4
48+
--> $DIR/issue-109425.rs:4:4
4949
|
5050
LL | fn i(_: u32) {}
5151
| ^ ------
@@ -56,15 +56,15 @@ LL + i(0); // i(0)
5656
|
5757

5858
error[E0061]: this function takes 2 arguments but 4 arguments were supplied
59-
--> $DIR/issue-109425.rs:14:5
59+
--> $DIR/issue-109425.rs:16:5
6060
|
6161
LL | is(0, 1, 2, ""); // is(0, "")
6262
| ^^ - - unexpected argument of type `{integer}`
6363
| |
6464
| unexpected argument of type `{integer}`
6565
|
6666
note: function defined here
67-
--> $DIR/issue-109425.rs:3:4
67+
--> $DIR/issue-109425.rs:5:4
6868
|
6969
LL | fn is(_: u32, _: &str) {}
7070
| ^^ ------ -------
@@ -75,22 +75,22 @@ LL + is(0, ""); // is(0, "")
7575
|
7676

7777
error[E0061]: this function takes 1 argument but 3 arguments were supplied
78-
--> $DIR/issue-109425.rs:16:5
78+
--> $DIR/issue-109425.rs:18:5
7979
|
8080
LL | s(0, 1, ""); // s("")
8181
| ^ - - unexpected argument of type `{integer}`
8282
| |
8383
| unexpected argument of type `{integer}`
8484
|
8585
note: function defined here
86-
--> $DIR/issue-109425.rs:4:4
86+
--> $DIR/issue-109425.rs:6:4
8787
|
8888
LL | fn s(_: &str) {}
8989
| ^ -------
9090
help: remove the extra arguments
9191
|
9292
LL - s(0, 1, ""); // s("")
93-
LL + s(, ""); // s("")
93+
LL + s(""); // s("")
9494
|
9595

9696
error: aborting due to 5 previous errors

tests/ui/suggestions/issue-109396.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ note: function defined here
2525
help: remove the extra arguments
2626
|
2727
LL - file.as_raw_fd(),
28-
LL + ,
28+
LL + );
2929
|
3030

3131
error: aborting due to 2 previous errors

0 commit comments

Comments
 (0)