From 6975b77e3b170902e66bfd2b411624b1b1ba23e9 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 30 Mar 2023 17:09:24 +0000 Subject: [PATCH 1/3] Add a test for issue 109396 --- tests/ui/argument-suggestions/issue-109425.rs | 18 ++++ .../argument-suggestions/issue-109425.stderr | 98 +++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 tests/ui/argument-suggestions/issue-109425.rs create mode 100644 tests/ui/argument-suggestions/issue-109425.stderr diff --git a/tests/ui/argument-suggestions/issue-109425.rs b/tests/ui/argument-suggestions/issue-109425.rs new file mode 100644 index 00000000000..2b92b6dccd7 --- /dev/null +++ b/tests/ui/argument-suggestions/issue-109425.rs @@ -0,0 +1,18 @@ +fn f() {} +fn i(_: u32) {} +fn is(_: u32, _: &str) {} +fn s(_: &str) {} + +fn main() { + // code expected suggestion + f(0, 1,); // f() + //~^ error: this function takes 0 arguments but 2 arguments were supplied + i(0, 1, 2,); // i(0,) + //~^ error: this function takes 1 argument but 3 arguments were supplied + i(0, 1, 2); // i(0) + //~^ 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 + 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 new file mode 100644 index 00000000000..59febb68222 --- /dev/null +++ b/tests/ui/argument-suggestions/issue-109425.stderr @@ -0,0 +1,98 @@ +error[E0061]: this function takes 0 arguments but 2 arguments were supplied + --> $DIR/issue-109425.rs:8:5 + | +LL | f(0, 1,); // f() + | ^ - - unexpected argument of type `{integer}` + | | + | unexpected argument of type `{integer}` + | +note: function defined here + --> $DIR/issue-109425.rs:1:4 + | +LL | fn f() {} + | ^ +help: remove the extra arguments + | +LL - f(0, 1,); // f() +LL + f(,); // f() + | + +error[E0061]: this function takes 1 argument but 3 arguments were supplied + --> $DIR/issue-109425.rs:10:5 + | +LL | i(0, 1, 2,); // i(0,) + | ^ - - unexpected argument of type `{integer}` + | | + | unexpected argument of type `{integer}` + | +note: function defined here + --> $DIR/issue-109425.rs:2:4 + | +LL | fn i(_: u32) {} + | ^ ------ +help: remove the extra arguments + | +LL - i(0, 1, 2,); // i(0,) +LL + i(0,); // i(0,) + | + +error[E0061]: this function takes 1 argument but 3 arguments were supplied + --> $DIR/issue-109425.rs:12:5 + | +LL | i(0, 1, 2); // i(0) + | ^ - - unexpected argument of type `{integer}` + | | + | unexpected argument of type `{integer}` + | +note: function defined here + --> $DIR/issue-109425.rs:2:4 + | +LL | fn i(_: u32) {} + | ^ ------ +help: remove the extra arguments + | +LL - i(0, 1, 2); // i(0) +LL + i(0); // i(0) + | + +error[E0061]: this function takes 2 arguments but 4 arguments were supplied + --> $DIR/issue-109425.rs:14:5 + | +LL | is(0, 1, 2, ""); // is(0, "") + | ^^ - - unexpected argument of type `{integer}` + | | + | unexpected argument of type `{integer}` + | +note: function defined here + --> $DIR/issue-109425.rs:3:4 + | +LL | fn is(_: u32, _: &str) {} + | ^^ ------ ------- +help: remove the extra arguments + | +LL - is(0, 1, 2, ""); // is(0, "") +LL + is(0, ""); // is(0, "") + | + +error[E0061]: this function takes 1 argument but 3 arguments were supplied + --> $DIR/issue-109425.rs:16:5 + | +LL | s(0, 1, ""); // s("") + | ^ - - unexpected argument of type `{integer}` + | | + | unexpected argument of type `{integer}` + | +note: function defined here + --> $DIR/issue-109425.rs:4:4 + | +LL | fn s(_: &str) {} + | ^ ------- +help: remove the extra arguments + | +LL - s(0, 1, ""); // s("") +LL + s(, ""); // s("") + | + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0061`. From b9d5a6b709be1e21961f2a867d6e6542ffa557f2 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 30 Mar 2023 17:11:06 +0000 Subject: [PATCH 2/3] Don't leave a comma at the start of argument list when removing arguments --- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 44 ++++++++++++++++--- .../argument-suggestions/issue-109425.fixed | 20 +++++++++ tests/ui/argument-suggestions/issue-109425.rs | 2 + .../argument-suggestions/issue-109425.stderr | 24 +++++----- tests/ui/suggestions/issue-109396.stderr | 2 +- 5 files changed, 73 insertions(+), 19 deletions(-) create mode 100644 tests/ui/argument-suggestions/issue-109425.fixed diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 61338ac613a..bb1063538b4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -21,7 +21,7 @@ use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::structured_errors::StructuredDiagnostic; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::TypeTrace; @@ -31,7 +31,7 @@ use rustc_middle::ty::{self, IsSuggestable, Ty}; use rustc_session::Session; use rustc_span::symbol::{kw, Ident}; -use rustc_span::{self, sym, Span}; +use rustc_span::{self, sym, BytePos, Span}; use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext}; use std::iter; @@ -894,8 +894,13 @@ enum SuggestionText { }; let mut errors = errors.into_iter().peekable(); + let mut only_extras_so_far = errors + .peek() + .map_or(false, |first| matches!(first, Error::Extra(arg_idx) if arg_idx.index() == 0)); let mut suggestions = vec![]; while let Some(error) = errors.next() { + only_extras_so_far &= matches!(error, Error::Extra(_)); + match error { Error::Invalid(provided_idx, expected_idx, compatibility) => { let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx]; @@ -941,10 +946,37 @@ enum SuggestionText { if arg_idx.index() > 0 && let Some((_, prev)) = provided_arg_tys .get(ProvidedIdx::from_usize(arg_idx.index() - 1) - ) { - // Include previous comma - span = prev.shrink_to_hi().to(span); - } + ) { + // Include previous comma + span = prev.shrink_to_hi().to(span); + } + + // Is last argument for deletion in a row starting from the 0-th argument? + // Then delete the next comma, so we are not left with `f(, ...)` + // + // fn f() {} + // - f(0, 1,) + // + f() + if only_extras_so_far + && errors + .peek() + .map_or(true, |next_error| !matches!(next_error, Error::Extra(_))) + { + let next = provided_arg_tys + .get(arg_idx.plus(1)) + .map(|&(_, sp)| sp) + .unwrap_or_else(|| { + // Subtract one to move before `)` + call_expr + .span + .shrink_to_hi() + .with_lo(call_expr.span.hi() - BytePos(1)) + }); + + // Include next comma + span = span.until(next); + } + suggestions.push((span, String::new())); suggestion_text = match suggestion_text { diff --git a/tests/ui/argument-suggestions/issue-109425.fixed b/tests/ui/argument-suggestions/issue-109425.fixed new file mode 100644 index 00000000000..143ddf99586 --- /dev/null +++ b/tests/ui/argument-suggestions/issue-109425.fixed @@ -0,0 +1,20 @@ +// run-rustfix + +fn f() {} +fn i(_: u32) {} +fn is(_: u32, _: &str) {} +fn s(_: &str) {} + +fn main() { + // code expected suggestion + f(); // f() + //~^ error: this function takes 0 arguments but 2 arguments were supplied + i(0,); // i(0,) + //~^ error: this function takes 1 argument but 3 arguments were supplied + i(0); // i(0) + //~^ 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 + 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 2b92b6dccd7..a845c419555 100644 --- a/tests/ui/argument-suggestions/issue-109425.rs +++ b/tests/ui/argument-suggestions/issue-109425.rs @@ -1,3 +1,5 @@ +// run-rustfix + fn f() {} fn i(_: u32) {} fn is(_: u32, _: &str) {} diff --git a/tests/ui/argument-suggestions/issue-109425.stderr b/tests/ui/argument-suggestions/issue-109425.stderr index 59febb68222..1514f1cb487 100644 --- a/tests/ui/argument-suggestions/issue-109425.stderr +++ b/tests/ui/argument-suggestions/issue-109425.stderr @@ -1,5 +1,5 @@ error[E0061]: this function takes 0 arguments but 2 arguments were supplied - --> $DIR/issue-109425.rs:8:5 + --> $DIR/issue-109425.rs:10:5 | LL | f(0, 1,); // f() | ^ - - unexpected argument of type `{integer}` @@ -7,18 +7,18 @@ LL | f(0, 1,); // f() | unexpected argument of type `{integer}` | note: function defined here - --> $DIR/issue-109425.rs:1:4 + --> $DIR/issue-109425.rs:3:4 | LL | fn f() {} | ^ help: remove the extra arguments | LL - f(0, 1,); // f() -LL + f(,); // f() +LL + f(); // f() | error[E0061]: this function takes 1 argument but 3 arguments were supplied - --> $DIR/issue-109425.rs:10:5 + --> $DIR/issue-109425.rs:12:5 | LL | i(0, 1, 2,); // i(0,) | ^ - - unexpected argument of type `{integer}` @@ -26,7 +26,7 @@ LL | i(0, 1, 2,); // i(0,) | unexpected argument of type `{integer}` | note: function defined here - --> $DIR/issue-109425.rs:2:4 + --> $DIR/issue-109425.rs:4:4 | LL | fn i(_: u32) {} | ^ ------ @@ -37,7 +37,7 @@ LL + i(0,); // i(0,) | error[E0061]: this function takes 1 argument but 3 arguments were supplied - --> $DIR/issue-109425.rs:12:5 + --> $DIR/issue-109425.rs:14:5 | LL | i(0, 1, 2); // i(0) | ^ - - unexpected argument of type `{integer}` @@ -45,7 +45,7 @@ LL | i(0, 1, 2); // i(0) | unexpected argument of type `{integer}` | note: function defined here - --> $DIR/issue-109425.rs:2:4 + --> $DIR/issue-109425.rs:4:4 | LL | fn i(_: u32) {} | ^ ------ @@ -56,7 +56,7 @@ LL + i(0); // i(0) | error[E0061]: this function takes 2 arguments but 4 arguments were supplied - --> $DIR/issue-109425.rs:14:5 + --> $DIR/issue-109425.rs:16:5 | LL | is(0, 1, 2, ""); // is(0, "") | ^^ - - unexpected argument of type `{integer}` @@ -64,7 +64,7 @@ LL | is(0, 1, 2, ""); // is(0, "") | unexpected argument of type `{integer}` | note: function defined here - --> $DIR/issue-109425.rs:3:4 + --> $DIR/issue-109425.rs:5:4 | LL | fn is(_: u32, _: &str) {} | ^^ ------ ------- @@ -75,7 +75,7 @@ LL + is(0, ""); // is(0, "") | error[E0061]: this function takes 1 argument but 3 arguments were supplied - --> $DIR/issue-109425.rs:16:5 + --> $DIR/issue-109425.rs:18:5 | LL | s(0, 1, ""); // s("") | ^ - - unexpected argument of type `{integer}` @@ -83,14 +83,14 @@ LL | s(0, 1, ""); // s("") | unexpected argument of type `{integer}` | note: function defined here - --> $DIR/issue-109425.rs:4:4 + --> $DIR/issue-109425.rs:6:4 | LL | fn s(_: &str) {} | ^ ------- help: remove the extra arguments | LL - s(0, 1, ""); // s("") -LL + s(, ""); // s("") +LL + s(""); // s("") | error: aborting due to 5 previous errors diff --git a/tests/ui/suggestions/issue-109396.stderr b/tests/ui/suggestions/issue-109396.stderr index eca160e2fab..d4956872a39 100644 --- a/tests/ui/suggestions/issue-109396.stderr +++ b/tests/ui/suggestions/issue-109396.stderr @@ -25,7 +25,7 @@ note: function defined here help: remove the extra arguments | LL - file.as_raw_fd(), -LL + , +LL + ); | error: aborting due to 2 previous errors From 48c16411c31d27772cb9c05a9914c2b9a26b5df5 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Wed, 5 Apr 2023 16:04:19 +0000 Subject: [PATCH 3/3] nit picks from review --- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index bb1063538b4..b02eae19fce 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -21,7 +21,7 @@ use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::structured_errors::StructuredDiagnostic; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::TypeTrace; @@ -963,14 +963,11 @@ enum SuggestionText { .map_or(true, |next_error| !matches!(next_error, Error::Extra(_))) { let next = provided_arg_tys - .get(arg_idx.plus(1)) + .get(arg_idx + 1) .map(|&(_, sp)| sp) .unwrap_or_else(|| { // Subtract one to move before `)` - call_expr - .span - .shrink_to_hi() - .with_lo(call_expr.span.hi() - BytePos(1)) + call_expr.span.with_lo(call_expr.span.hi() - BytePos(1)) }); // Include next comma