Skip to content

Commit dff10d0

Browse files
committed
Re-add replacement logic and add comment explaining it
1 parent 755252b commit dff10d0

File tree

6 files changed

+71
-35
lines changed

6 files changed

+71
-35
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+38-14
Original file line numberDiff line numberDiff line change
@@ -1135,20 +1135,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11351135
}
11361136
}
11371137

1138-
// // Incorporate the argument changes in the removal suggestion.
1139-
// let mut prev = -1;
1140-
// for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
1141-
// if let Some(provided_idx) = provided_idx {
1142-
// prev = provided_idx.index() as i64;
1143-
// }
1144-
// let idx = ProvidedIdx::from_usize((prev + 1) as usize);
1145-
// if let None = provided_idx
1146-
// && let Some((_, arg_span)) = provided_arg_tys.get(idx)
1147-
// {
1148-
// let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
1149-
// suggestions.push((*arg_span, ty_to_snippet(expected_ty, expected_idx)));
1150-
// }
1151-
// }
1138+
// Incorporate the argument changes in the removal suggestion.
1139+
// When a type is *missing*, and the rest are additional, we want to suggest these with a
1140+
// multipart suggestion, but in order to do so we need to figure out *where* the arg that
1141+
// was provided but had the wrong type should go, because when looking at `expected_idx`
1142+
// that is the position in the argument list in the definition, while `provided_idx` will
1143+
// not be present. So we have to look at what the *last* provided position was, and point
1144+
// one after to suggest the replacement. FIXME(estebank): This is hacky, and there's
1145+
// probably a better more involved change we can make to make this work.
1146+
// For example, if we have
1147+
// ```
1148+
// fn foo(i32, &'static str) {}
1149+
// foo((), (), ());
1150+
// ```
1151+
// what should be suggested is
1152+
// ```
1153+
// foo(/* i32 */, /* &str */);
1154+
// ```
1155+
// which includes the replacement of the first two `()` for the correct type, and the
1156+
// removal of the last `()`.
1157+
let mut prev = -1;
1158+
for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
1159+
// We want to point not at the *current* argument expression index, but rather at the
1160+
// index position where it *should have been*, which is *after* the previous one.
1161+
if let Some(provided_idx) = provided_idx {
1162+
prev = provided_idx.index() as i64;
1163+
}
1164+
let idx = ProvidedIdx::from_usize((prev + 1) as usize);
1165+
if let None = provided_idx
1166+
&& let Some((_, arg_span)) = provided_arg_tys.get(idx)
1167+
{
1168+
// There is a type that was *not* found anywhere, so it isn't a move, but a
1169+
// replacement and we look at what type it should have been. This will allow us
1170+
// To suggest a multipart suggestion when encountering `foo(1, "")` where the def
1171+
// was `fn foo(())`.
1172+
let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
1173+
suggestions.push((*arg_span, ty_to_snippet(expected_ty, expected_idx)));
1174+
}
1175+
}
11521176

11531177
// If we have less than 5 things to say, it would be useful to call out exactly what's wrong
11541178
if labels.len() <= 5 {

tests/ui/argument-suggestions/issue-97484.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ LL | foo(&&A, B, C, D, &E, F, G);
2020
help: remove the extra arguments
2121
|
2222
LL - foo(&&A, B, C, D, E, F, G);
23-
LL + foo(&&A, D, E, G);
23+
LL + foo(&&A, D, /* &E */, G);
2424
|
2525

2626
error: aborting due to previous error

tests/ui/argument-suggestions/mixed_cases.stderr

+7-4
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
22
--> $DIR/mixed_cases.rs:10:3
33
|
44
LL | two_args(1, "", X {});
5-
| ^^^^^^^^ --------
6-
| | | |
7-
| | | unexpected argument of type `X`
8-
| | help: remove the extra argument
5+
| ^^^^^^^^ -- ---- unexpected argument of type `X`
6+
| |
97
| expected `f32`, found `&str`
108
|
119
note: function defined here
1210
--> $DIR/mixed_cases.rs:5:4
1311
|
1412
LL | fn two_args(_a: i32, _b: f32) {}
1513
| ^^^^^^^^ ------- -------
14+
help: remove the extra argument
15+
|
16+
LL - two_args(1, "", X {});
17+
LL + two_args(1, /* f32 */);
18+
|
1619

1720
error[E0061]: this function takes 3 arguments but 4 arguments were supplied
1821
--> $DIR/mixed_cases.rs:11:3

tests/ui/mismatched_types/overloaded-calls-bad.stderr

+7-4
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,20 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied
3232
--> $DIR/overloaded-calls-bad.rs:37:15
3333
|
3434
LL | let ans = s("burma", "shave");
35-
| ^ ----------------
36-
| | | |
37-
| | | unexpected argument of type `&'static str`
38-
| | help: remove the extra argument
35+
| ^ ------- ------- unexpected argument of type `&'static str`
36+
| |
3937
| expected `isize`, found `&str`
4038
|
4139
note: implementation defined here
4240
--> $DIR/overloaded-calls-bad.rs:10:1
4341
|
4442
LL | impl FnMut<(isize,)> for S {
4543
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
44+
help: remove the extra argument
45+
|
46+
LL - let ans = s("burma", "shave");
47+
LL + let ans = s(/* isize */);
48+
|
4649

4750
error[E0308]: mismatched types
4851
--> $DIR/overloaded-calls-bad.rs:40:7

tests/ui/suggestions/args-instead-of-tuple-errors.stderr

+12-8
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
22
--> $DIR/args-instead-of-tuple-errors.rs:6:34
33
|
44
LL | let _: Option<(i32, bool)> = Some(1, 2);
5-
| ^^^^ ---
6-
| | |
7-
| | unexpected argument of type `{integer}`
8-
| help: remove the extra argument
5+
| ^^^^ - unexpected argument of type `{integer}`
96
|
107
note: expected `(i32, bool)`, found integer
118
--> $DIR/args-instead-of-tuple-errors.rs:6:39
@@ -23,15 +20,17 @@ LL | let _: Option<(i32, bool)> = Some(1, 2);
2320
| this argument influences the type of `Some`
2421
note: tuple variant defined here
2522
--> $SRC_DIR/core/src/option.rs:LL:COL
23+
help: remove the extra argument
24+
|
25+
LL - let _: Option<(i32, bool)> = Some(1, 2);
26+
LL + let _: Option<(i32, bool)> = Some(/* (i32, bool) */);
27+
|
2628

2729
error[E0061]: this function takes 1 argument but 2 arguments were supplied
2830
--> $DIR/args-instead-of-tuple-errors.rs:8:5
2931
|
3032
LL | int_bool(1, 2);
31-
| ^^^^^^^^ ---
32-
| | |
33-
| | unexpected argument of type `{integer}`
34-
| help: remove the extra argument
33+
| ^^^^^^^^ - unexpected argument of type `{integer}`
3534
|
3635
note: expected `(i32, bool)`, found integer
3736
--> $DIR/args-instead-of-tuple-errors.rs:8:14
@@ -45,6 +44,11 @@ note: function defined here
4544
|
4645
LL | fn int_bool(_: (i32, bool)) {
4746
| ^^^^^^^^ --------------
47+
help: remove the extra argument
48+
|
49+
LL - int_bool(1, 2);
50+
LL + int_bool(/* (i32, bool) */);
51+
|
4852

4953
error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
5054
--> $DIR/args-instead-of-tuple-errors.rs:11:28

tests/ui/tuple/wrong_argument_ice-3.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ error[E0061]: this method takes 1 argument but 2 arguments were supplied
22
--> $DIR/wrong_argument_ice-3.rs:9:16
33
|
44
LL | groups.push(new_group, vec![process]);
5-
| ^^^^ ---------------
6-
| | |
7-
| | unexpected argument of type `Vec<&Process>`
8-
| help: remove the extra argument
5+
| ^^^^ ------------- unexpected argument of type `Vec<&Process>`
96
|
107
note: expected `(Vec<String>, Vec<Process>)`, found `Vec<String>`
118
--> $DIR/wrong_argument_ice-3.rs:9:21
@@ -16,6 +13,11 @@ LL | groups.push(new_group, vec![process]);
1613
found struct `Vec<String>`
1714
note: associated function defined here
1815
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
16+
help: remove the extra argument
17+
|
18+
LL - groups.push(new_group, vec![process]);
19+
LL + groups.push(/* (Vec<String>, Vec<Process>) */);
20+
|
1921

2022
error: aborting due to previous error
2123

0 commit comments

Comments
 (0)