diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index bf8cc462189..f29d6199a87 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1097,6 +1097,7 @@ enum SuggestionText { let mut only_extras_so_far = errors .peek() .is_some_and(|first| matches!(first, Error::Extra(arg_idx) if arg_idx.index() == 0)); + let mut prev_extra_idx = None; let mut suggestions = vec![]; while let Some(error) = errors.next() { only_extras_so_far &= matches!(error, Error::Extra(_)); @@ -1165,11 +1166,29 @@ enum SuggestionText { // fn f() {} // - f(0, 1,) // + f() - if only_extras_so_far - && !errors - .peek() - .is_some_and(|next_error| matches!(next_error, Error::Extra(_))) - { + let trim_next_comma = match errors.peek() { + Some(Error::Extra(provided_idx)) + if only_extras_so_far + && provided_idx.index() > arg_idx.index() + 1 => + // If the next Error::Extra ("next") doesn't next to current ("current"), + // fn foo(_: (), _: u32) {} + // - foo("current", (), 1u32, "next") + // + foo((), 1u32) + // If the previous error is not a `Error::Extra`, then do not trim the next comma + // - foo((), "current", 42u32, "next") + // + foo((), 42u32) + { + prev_extra_idx.map_or(true, |prev_extra_idx| { + prev_extra_idx + 1 == arg_idx.index() + }) + } + // If no error left, we need to delete the next comma + None if only_extras_so_far => true, + // Not sure if other error type need to be handled as well + _ => false, + }; + + if trim_next_comma { let next = provided_arg_tys .get(arg_idx + 1) .map(|&(_, sp)| sp) @@ -1192,6 +1211,7 @@ enum SuggestionText { SuggestionText::Remove(_) => SuggestionText::Remove(true), _ => SuggestionText::DidYouMean, }; + prev_extra_idx = Some(arg_idx.index()) } } Error::Missing(expected_idx) => { diff --git a/tests/ui/argument-suggestions/issue-109425.fixed b/tests/ui/argument-suggestions/issue-109425.fixed index 5d96f457c88..4b3aaa46d86 100644 --- a/tests/ui/argument-suggestions/issue-109425.fixed +++ b/tests/ui/argument-suggestions/issue-109425.fixed @@ -15,6 +15,10 @@ fn main() { //~^ error: this function takes 1 argument but 3 arguments were supplied is(0, ""); // is(0, "") //~^ error: this function takes 2 arguments but 4 arguments were supplied + is(1, ""); + //~^ error: this function takes 2 arguments but 4 arguments were supplied + is(1, ""); + //~^ error: this function takes 2 arguments but 4 arguments were supplied s(""); // s("") //~^ error: this function takes 1 argument but 3 arguments were supplied } diff --git a/tests/ui/argument-suggestions/issue-109425.rs b/tests/ui/argument-suggestions/issue-109425.rs index bb9d37ee0ff..56816681337 100644 --- a/tests/ui/argument-suggestions/issue-109425.rs +++ b/tests/ui/argument-suggestions/issue-109425.rs @@ -15,6 +15,10 @@ fn main() { //~^ error: this function takes 1 argument but 3 arguments were supplied is(0, 1, 2, ""); // is(0, "") //~^ error: this function takes 2 arguments but 4 arguments were supplied + is((), 1, "", ()); + //~^ error: this function takes 2 arguments but 4 arguments were supplied + is(1, (), "", ()); + //~^ error: this function takes 2 arguments but 4 arguments were supplied s(0, 1, ""); // s("") //~^ error: this function takes 1 argument but 3 arguments were supplied } diff --git a/tests/ui/argument-suggestions/issue-109425.stderr b/tests/ui/argument-suggestions/issue-109425.stderr index bfe007793d4..2cd53ed528e 100644 --- a/tests/ui/argument-suggestions/issue-109425.stderr +++ b/tests/ui/argument-suggestions/issue-109425.stderr @@ -74,9 +74,47 @@ LL - is(0, 1, 2, ""); // is(0, "") LL + is(0, ""); // is(0, "") | -error[E0061]: this function takes 1 argument but 3 arguments were supplied +error[E0061]: this function takes 2 arguments but 4 arguments were supplied --> $DIR/issue-109425.rs:18:5 | +LL | is((), 1, "", ()); + | ^^ -- -- unexpected argument #4 of type `()` + | | + | unexpected argument #1 of type `()` + | +note: function defined here + --> $DIR/issue-109425.rs:5:4 + | +LL | fn is(_: u32, _: &str) {} + | ^^ ------ ------- +help: remove the extra arguments + | +LL - is((), 1, "", ()); +LL + is(1, ""); + | + +error[E0061]: this function takes 2 arguments but 4 arguments were supplied + --> $DIR/issue-109425.rs:20:5 + | +LL | is(1, (), "", ()); + | ^^ -- -- unexpected argument #4 of type `()` + | | + | unexpected argument #2 of type `()` + | +note: function defined here + --> $DIR/issue-109425.rs:5:4 + | +LL | fn is(_: u32, _: &str) {} + | ^^ ------ ------- +help: remove the extra arguments + | +LL - is(1, (), "", ()); +LL + is(1, ""); + | + +error[E0061]: this function takes 1 argument but 3 arguments were supplied + --> $DIR/issue-109425.rs:22:5 + | LL | s(0, 1, ""); // s("") | ^ - - unexpected argument #2 of type `{integer}` | | @@ -93,6 +131,6 @@ LL - s(0, 1, ""); // s("") LL + s(""); // s("") | -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/argument-suggestions/issue-112507.stderr b/tests/ui/argument-suggestions/issue-112507.stderr index 908ed35c669..e2ea9af7dc2 100644 --- a/tests/ui/argument-suggestions/issue-112507.stderr +++ b/tests/ui/argument-suggestions/issue-112507.stderr @@ -18,8 +18,9 @@ LL | Float(Option), | ^^^^^ help: remove the extra arguments | -LL ~ , -LL ~ None); +LL - 0, +LL - None, +LL + None); | error: aborting due to 1 previous error