about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2023-02-02 15:59:02 +0000
committerEsteban Küber <esteban@kuber.com.ar>2023-02-14 20:22:10 +0000
commitdff10d0668a1e89782fb660e033d6a57ab122266 (patch)
tree700a20ab9b1f43178c727a8c986eb46eae2db976
parent755252bf51c121b17436f59b35cfdbc7f0058d96 (diff)
downloadrust-dff10d0668a1e89782fb660e033d6a57ab122266.tar.gz
rust-dff10d0668a1e89782fb660e033d6a57ab122266.zip
Re-add replacement logic and add comment explaining it
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs52
-rw-r--r--tests/ui/argument-suggestions/issue-97484.stderr2
-rw-r--r--tests/ui/argument-suggestions/mixed_cases.stderr11
-rw-r--r--tests/ui/mismatched_types/overloaded-calls-bad.stderr11
-rw-r--r--tests/ui/suggestions/args-instead-of-tuple-errors.stderr20
-rw-r--r--tests/ui/tuple/wrong_argument_ice-3.stderr10
6 files changed, 71 insertions, 35 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 6d164d1c2b2..63b170a3c63 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1135,20 +1135,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        // // Incorporate the argument changes in the removal suggestion.
-        // let mut prev = -1;
-        // for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
-        //     if let Some(provided_idx) = provided_idx {
-        //         prev = provided_idx.index() as i64;
-        //     }
-        //     let idx = ProvidedIdx::from_usize((prev + 1) as usize);
-        //     if let None = provided_idx
-        //         && let Some((_, arg_span)) = provided_arg_tys.get(idx)
-        //     {
-        //         let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
-        //         suggestions.push((*arg_span, ty_to_snippet(expected_ty, expected_idx)));
-        //     }
-        // }
+        // Incorporate the argument changes in the removal suggestion.
+        // When a type is *missing*, and the rest are additional, we want to suggest these with a
+        // multipart suggestion, but in order to do so we need to figure out *where* the arg that
+        // was provided but had the wrong type should go, because when looking at `expected_idx`
+        // that is the position in the argument list in the definition, while `provided_idx` will
+        // not be present. So we have to look at what the *last* provided position was, and point
+        // one after to suggest the replacement. FIXME(estebank): This is hacky, and there's
+        // probably a better more involved change we can make to make this work.
+        // For example, if we have
+        // ```
+        // fn foo(i32, &'static str) {}
+        // foo((), (), ());
+        // ```
+        // what should be suggested is
+        // ```
+        // foo(/* i32 */, /* &str */);
+        // ```
+        // which includes the replacement of the first two `()` for the correct type, and the
+        // removal of the last `()`.
+        let mut prev = -1;
+        for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
+            // We want to point not at the *current* argument expression index, but rather at the
+            // index position where it *should have been*, which is *after* the previous one.
+            if let Some(provided_idx) = provided_idx {
+                prev = provided_idx.index() as i64;
+            }
+            let idx = ProvidedIdx::from_usize((prev + 1) as usize);
+            if let None = provided_idx
+                && let Some((_, arg_span)) = provided_arg_tys.get(idx)
+            {
+                // There is a type that was *not* found anywhere, so it isn't a move, but a
+                // replacement and we look at what type it should have been. This will allow us
+                // To suggest a multipart suggestion when encountering `foo(1, "")` where the def
+                // was `fn foo(())`.
+                let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
+                suggestions.push((*arg_span, ty_to_snippet(expected_ty, expected_idx)));
+            }
+        }
 
         // If we have less than 5 things to say, it would be useful to call out exactly what's wrong
         if labels.len() <= 5 {
diff --git a/tests/ui/argument-suggestions/issue-97484.stderr b/tests/ui/argument-suggestions/issue-97484.stderr
index 2c2797b3911..a86cbbf1802 100644
--- a/tests/ui/argument-suggestions/issue-97484.stderr
+++ b/tests/ui/argument-suggestions/issue-97484.stderr
@@ -20,7 +20,7 @@ LL |     foo(&&A, B, C, D, &E, F, G);
 help: remove the extra arguments
    |
 LL -     foo(&&A, B, C, D, E, F, G);
-LL +     foo(&&A, D, E, G);
+LL +     foo(&&A, D, /* &E */, G);
    |
 
 error: aborting due to previous error
diff --git a/tests/ui/argument-suggestions/mixed_cases.stderr b/tests/ui/argument-suggestions/mixed_cases.stderr
index cfa5702ab7f..c645dd38179 100644
--- a/tests/ui/argument-suggestions/mixed_cases.stderr
+++ b/tests/ui/argument-suggestions/mixed_cases.stderr
@@ -2,10 +2,8 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/mixed_cases.rs:10:3
    |
 LL |   two_args(1, "", X {});
-   |   ^^^^^^^^    --------
-   |               | | |
-   |               | | unexpected argument of type `X`
-   |               | help: remove the extra argument
+   |   ^^^^^^^^    --  ---- unexpected argument of type `X`
+   |               |
    |               expected `f32`, found `&str`
    |
 note: function defined here
@@ -13,6 +11,11 @@ note: function defined here
    |
 LL | fn two_args(_a: i32, _b: f32) {}
    |    ^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL -   two_args(1, "", X {});
+LL +   two_args(1, /* f32 */);
+   |
 
 error[E0061]: this function takes 3 arguments but 4 arguments were supplied
   --> $DIR/mixed_cases.rs:11:3
diff --git a/tests/ui/mismatched_types/overloaded-calls-bad.stderr b/tests/ui/mismatched_types/overloaded-calls-bad.stderr
index 8032aa32b4f..cd483e7ad2c 100644
--- a/tests/ui/mismatched_types/overloaded-calls-bad.stderr
+++ b/tests/ui/mismatched_types/overloaded-calls-bad.stderr
@@ -32,10 +32,8 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/overloaded-calls-bad.rs:37:15
    |
 LL |     let ans = s("burma", "shave");
-   |               ^ ----------------
-   |                 |      | |
-   |                 |      | unexpected argument of type `&'static str`
-   |                 |      help: remove the extra argument
+   |               ^ -------  ------- unexpected argument of type `&'static str`
+   |                 |
    |                 expected `isize`, found `&str`
    |
 note: implementation defined here
@@ -43,6 +41,11 @@ note: implementation defined here
    |
 LL | impl FnMut<(isize,)> for S {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: remove the extra argument
+   |
+LL -     let ans = s("burma", "shave");
+LL +     let ans = s(/* isize */);
+   |
 
 error[E0308]: mismatched types
   --> $DIR/overloaded-calls-bad.rs:40:7
diff --git a/tests/ui/suggestions/args-instead-of-tuple-errors.stderr b/tests/ui/suggestions/args-instead-of-tuple-errors.stderr
index 143363321da..510b99bb5af 100644
--- a/tests/ui/suggestions/args-instead-of-tuple-errors.stderr
+++ b/tests/ui/suggestions/args-instead-of-tuple-errors.stderr
@@ -2,10 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:6:34
    |
 LL |     let _: Option<(i32, bool)> = Some(1, 2);
-   |                                  ^^^^  ---
-   |                                        | |
-   |                                        | unexpected argument of type `{integer}`
-   |                                        help: remove the extra argument
+   |                                  ^^^^    - unexpected argument of type `{integer}`
    |
 note: expected `(i32, bool)`, found integer
   --> $DIR/args-instead-of-tuple-errors.rs:6:39
@@ -23,15 +20,17 @@ LL |     let _: Option<(i32, bool)> = Some(1, 2);
    |                                       this argument influences the type of `Some`
 note: tuple variant defined here
   --> $SRC_DIR/core/src/option.rs:LL:COL
+help: remove the extra argument
+   |
+LL -     let _: Option<(i32, bool)> = Some(1, 2);
+LL +     let _: Option<(i32, bool)> = Some(/* (i32, bool) */);
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:8:5
    |
 LL |     int_bool(1, 2);
-   |     ^^^^^^^^  ---
-   |               | |
-   |               | unexpected argument of type `{integer}`
-   |               help: remove the extra argument
+   |     ^^^^^^^^    - unexpected argument of type `{integer}`
    |
 note: expected `(i32, bool)`, found integer
   --> $DIR/args-instead-of-tuple-errors.rs:8:14
@@ -45,6 +44,11 @@ note: function defined here
    |
 LL | fn int_bool(_: (i32, bool)) {
    |    ^^^^^^^^ --------------
+help: remove the extra argument
+   |
+LL -     int_bool(1, 2);
+LL +     int_bool(/* (i32, bool) */);
+   |
 
 error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:11:28
diff --git a/tests/ui/tuple/wrong_argument_ice-3.stderr b/tests/ui/tuple/wrong_argument_ice-3.stderr
index 8b4fca4de7d..7143c959478 100644
--- a/tests/ui/tuple/wrong_argument_ice-3.stderr
+++ b/tests/ui/tuple/wrong_argument_ice-3.stderr
@@ -2,10 +2,7 @@ error[E0061]: this method takes 1 argument but 2 arguments were supplied
   --> $DIR/wrong_argument_ice-3.rs:9:16
    |
 LL |         groups.push(new_group, vec![process]);
-   |                ^^^^          ---------------
-   |                              | |
-   |                              | unexpected argument of type `Vec<&Process>`
-   |                              help: remove the extra argument
+   |                ^^^^            ------------- unexpected argument of type `Vec<&Process>`
    |
 note: expected `(Vec<String>, Vec<Process>)`, found `Vec<String>`
   --> $DIR/wrong_argument_ice-3.rs:9:21
@@ -16,6 +13,11 @@ LL |         groups.push(new_group, vec![process]);
              found struct `Vec<String>`
 note: associated function defined here
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+help: remove the extra argument
+   |
+LL -         groups.push(new_group, vec![process]);
+LL +         groups.push(/* (Vec<String>, Vec<Process>) */);
+   |
 
 error: aborting due to previous error