From bbfbecd59ff99b51d1ccf7764641ef32209b9dad Mon Sep 17 00:00:00 2001 From: Mu42 Date: Sun, 2 Apr 2023 10:48:01 +0800 Subject: [PATCH 1/2] Do not repeat idx --- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 11 ++-- tests/ui/argument-suggestions/109831.rs | 9 ++++ tests/ui/argument-suggestions/109831.stderr | 51 +++++++++++++++++++ 3 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 tests/ui/argument-suggestions/109831.rs create mode 100644 tests/ui/argument-suggestions/109831.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 61338ac613a..32c603e4897 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1156,14 +1156,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ``` // which includes the replacement of the first two `()` for the correct type, and the // removal of the last `()`. - let mut prev = -1; + let mut idx = -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); + idx = match provided_idx { + Some(provided_idx) => provided_idx.index() as i64 + 1, + None => idx + 1, + }; + let idx = ProvidedIdx::from_usize(idx as usize); if let None = provided_idx && let Some((_, arg_span)) = provided_arg_tys.get(idx) { diff --git a/tests/ui/argument-suggestions/109831.rs b/tests/ui/argument-suggestions/109831.rs new file mode 100644 index 00000000000..2e8ae40f630 --- /dev/null +++ b/tests/ui/argument-suggestions/109831.rs @@ -0,0 +1,9 @@ +struct A; +struct B; + +fn f(b1: B, b2: B, a2: C) {} //~ ERROR E0412 + +fn main() { + f(A, A, B, C); //~ ERROR E0425 + //~^ ERROR E0061 +} diff --git a/tests/ui/argument-suggestions/109831.stderr b/tests/ui/argument-suggestions/109831.stderr new file mode 100644 index 00000000000..861f6d67baf --- /dev/null +++ b/tests/ui/argument-suggestions/109831.stderr @@ -0,0 +1,51 @@ +error[E0412]: cannot find type `C` in this scope + --> $DIR/109831.rs:4:24 + | +LL | struct A; + | --------- similarly named struct `A` defined here +... +LL | fn f(b1: B, b2: B, a2: C) {} + | ^ + | +help: a struct with a similar name exists + | +LL | fn f(b1: B, b2: B, a2: A) {} + | ~ +help: you might be missing a type parameter + | +LL | fn f(b1: B, b2: B, a2: C) {} + | +++ + +error[E0425]: cannot find value `C` in this scope + --> $DIR/109831.rs:7:16 + | +LL | struct A; + | --------- similarly named unit struct `A` defined here +... +LL | f(A, A, B, C); + | ^ help: a unit struct with a similar name exists: `A` + +error[E0061]: this function takes 3 arguments but 4 arguments were supplied + --> $DIR/109831.rs:7:5 + | +LL | f(A, A, B, C); + | ^ - - - unexpected argument + | | | + | | expected `B`, found `A` + | expected `B`, found `A` + | +note: function defined here + --> $DIR/109831.rs:4:4 + | +LL | fn f(b1: B, b2: B, a2: C) {} + | ^ ----- ----- ----- +help: remove the extra argument + | +LL - f(A, A, B, C); +LL + f(/* B */, /* B */, B); + | + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0061, E0412, E0425. +For more information about an error, try `rustc --explain E0061`. From 80e428553144d441893fc07ea2b88081d93806fe Mon Sep 17 00:00:00 2001 From: Mu42 Date: Sun, 2 Apr 2023 11:41:50 +0800 Subject: [PATCH 2/2] Make each idx is used once --- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 17 ++++++++--------- .../{109831.rs => issue-109831.rs} | 0 .../{109831.stderr => issue-109831.stderr} | 8 ++++---- 3 files changed, 12 insertions(+), 13 deletions(-) rename tests/ui/argument-suggestions/{109831.rs => issue-109831.rs} (100%) rename tests/ui/argument-suggestions/{109831.stderr => issue-109831.stderr} (90%) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 32c603e4897..6bcc2bae98a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1156,18 +1156,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ``` // which includes the replacement of the first two `()` for the correct type, and the // removal of the last `()`. - let mut idx = -1; + 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. - idx = match provided_idx { - Some(provided_idx) => provided_idx.index() as i64 + 1, - None => idx + 1, - }; - let idx = ProvidedIdx::from_usize(idx as usize); - if let None = provided_idx - && let Some((_, arg_span)) = provided_arg_tys.get(idx) - { + if let Some(provided_idx) = provided_idx { + prev = provided_idx.index() as i64; + continue; + } + let idx = ProvidedIdx::from_usize((prev + 1) as usize); + if let Some((_, arg_span)) = provided_arg_tys.get(idx) { + prev += 1; // 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 diff --git a/tests/ui/argument-suggestions/109831.rs b/tests/ui/argument-suggestions/issue-109831.rs similarity index 100% rename from tests/ui/argument-suggestions/109831.rs rename to tests/ui/argument-suggestions/issue-109831.rs diff --git a/tests/ui/argument-suggestions/109831.stderr b/tests/ui/argument-suggestions/issue-109831.stderr similarity index 90% rename from tests/ui/argument-suggestions/109831.stderr rename to tests/ui/argument-suggestions/issue-109831.stderr index 861f6d67baf..7b9a3c9ef2c 100644 --- a/tests/ui/argument-suggestions/109831.stderr +++ b/tests/ui/argument-suggestions/issue-109831.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `C` in this scope - --> $DIR/109831.rs:4:24 + --> $DIR/issue-109831.rs:4:24 | LL | struct A; | --------- similarly named struct `A` defined here @@ -17,7 +17,7 @@ LL | fn f(b1: B, b2: B, a2: C) {} | +++ error[E0425]: cannot find value `C` in this scope - --> $DIR/109831.rs:7:16 + --> $DIR/issue-109831.rs:7:16 | LL | struct A; | --------- similarly named unit struct `A` defined here @@ -26,7 +26,7 @@ LL | f(A, A, B, C); | ^ help: a unit struct with a similar name exists: `A` error[E0061]: this function takes 3 arguments but 4 arguments were supplied - --> $DIR/109831.rs:7:5 + --> $DIR/issue-109831.rs:7:5 | LL | f(A, A, B, C); | ^ - - - unexpected argument @@ -35,7 +35,7 @@ LL | f(A, A, B, C); | expected `B`, found `A` | note: function defined here - --> $DIR/109831.rs:4:4 + --> $DIR/issue-109831.rs:4:4 | LL | fn f(b1: B, b2: B, a2: C) {} | ^ ----- ----- -----