about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-04-06 18:42:58 +0200
committerGitHub <noreply@github.com>2023-04-06 18:42:58 +0200
commitb153e2bd122ab5993fa9837a81b7647266ae6178 (patch)
tree2d0f778fa9cd62350ded96433e5d6712c3a0dd79
parentc86c9339e6991dbf9a9a4ae210492e94b142a728 (diff)
parent48c16411c31d27772cb9c05a9914c2b9a26b5df5 (diff)
downloadrust-b153e2bd122ab5993fa9837a81b7647266ae6178.tar.gz
rust-b153e2bd122ab5993fa9837a81b7647266ae6178.zip
Rollup merge of #109782 - WaffleLapkin:nocommawhenremovingarguments, r=oli-obk
Don't leave a comma at the start of argument list when removing arguments

Fixes #109425

Quite a dirty hack, but at least it works ig.
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs39
-rw-r--r--tests/ui/argument-suggestions/issue-109425.fixed20
-rw-r--r--tests/ui/argument-suggestions/issue-109425.rs20
-rw-r--r--tests/ui/argument-suggestions/issue-109425.stderr98
-rw-r--r--tests/ui/suggestions/issue-109396.stderr2
5 files changed, 173 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 61338ac613a..b02eae19fce 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -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,34 @@ 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 + 1)
+                                .map(|&(_, sp)| sp)
+                                .unwrap_or_else(|| {
+                                    // Subtract one to move before `)`
+                                    call_expr.span.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
new file mode 100644
index 00000000000..a845c419555
--- /dev/null
+++ b/tests/ui/argument-suggestions/issue-109425.rs
@@ -0,0 +1,20 @@
+// run-rustfix
+
+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..1514f1cb487
--- /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:10:5
+   |
+LL |     f(0, 1,);        // f()
+   |     ^ -  - unexpected argument of type `{integer}`
+   |       |
+   |       unexpected argument of type `{integer}`
+   |
+note: function defined here
+  --> $DIR/issue-109425.rs:3: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: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:4: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:14: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:4: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:16: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:5: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:18:5
+   |
+LL |     s(0, 1, "");     // s("")
+   |     ^ -  - unexpected argument of type `{integer}`
+   |       |
+   |       unexpected argument of type `{integer}`
+   |
+note: function defined here
+  --> $DIR/issue-109425.rs:6: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`.
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