about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2023-03-30 17:11:06 +0000
committerMaybe Waffle <waffle.lapkin@gmail.com>2023-03-30 17:26:12 +0000
commitb9d5a6b709be1e21961f2a867d6e6542ffa557f2 (patch)
tree8d28d42d0f1309f271bdcee05fd1cf2dfade38c7
parent6975b77e3b170902e66bfd2b411624b1b1ba23e9 (diff)
downloadrust-b9d5a6b709be1e21961f2a867d6e6542ffa557f2.tar.gz
rust-b9d5a6b709be1e21961f2a867d6e6542ffa557f2.zip
Don't leave a comma at the start of argument list when removing arguments
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs44
-rw-r--r--tests/ui/argument-suggestions/issue-109425.fixed20
-rw-r--r--tests/ui/argument-suggestions/issue-109425.rs2
-rw-r--r--tests/ui/argument-suggestions/issue-109425.stderr24
-rw-r--r--tests/ui/suggestions/issue-109396.stderr2
5 files changed, 73 insertions, 19 deletions
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::astconv::AstConv;
 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::visit::TypeVisitableExt;
 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         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