Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix incorrect suggestion for extra argument with a type error #127253

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return err.emit();
}

// Special case, we found an extra argument is provided, which is very common in practice.
// but there is a obviously better removing suggestion compared to the current one,
// try to find the argument with Error type, if we removed it all the types will become good,
// then we will replace the current suggestion.
if let [Error::Extra(provided_idx)] = &errors[..] {
let remove_idx_is_perfect = |idx: usize| -> bool {
let removed_arg_tys = provided_arg_tys
.iter()
.enumerate()
.filter_map(|(j, arg)| if idx == j { None } else { Some(arg) })
.collect::<IndexVec<ProvidedIdx, _>>();
std::iter::zip(formal_and_expected_inputs.iter(), removed_arg_tys.iter()).all(
|((expected_ty, _), (provided_ty, _))| {
!provided_ty.references_error()
&& self.can_coerce(*provided_ty, *expected_ty)
},
)
};

if !remove_idx_is_perfect(provided_idx.as_usize()) {
if let Some(i) = (0..provided_args.len()).find(|&i| remove_idx_is_perfect(i)) {
errors = vec![Error::Extra(ProvidedIdx::from_usize(i))];
}
}
}

let mut err = if formal_and_expected_inputs.len() == provided_args.len() {
struct_span_code_err!(
self.dcx(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
fn add_one(x: i32) -> i32 {
x + 1
}

fn add_two(x: i32, y: i32) -> i32 {
x + y
}

fn main() {
add_one(2, 2); //~ ERROR this function takes 1 argument but 2 arguments were supplied
add_one(no_such_local, 10); //~ ERROR cannot find value `no_such_local` in this scope
//~| ERROR this function takes 1 argument but 2 arguments were supplied
add_one(10, no_such_local); //~ ERROR cannot find value `no_such_local` in this scope
//~| ERROR this function takes 1 argument but 2 arguments were supplied
add_two(10, no_such_local, 10); //~ ERROR cannot find value `no_such_local` in this scope
//~| ERROR this function takes 2 arguments but 3 arguments were supplied
add_two(no_such_local, 10, 10); //~ ERROR cannot find value `no_such_local` in this scope
//~| ERROR this function takes 2 arguments but 3 arguments were supplied
add_two(10, 10, no_such_local); //~ ERROR cannot find value `no_such_local` in this scope
//~| ERROR this function takes 2 arguments but 3 arguments were supplied
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
error[E0425]: cannot find value `no_such_local` in this scope
--> $DIR/suggest-better-removing-issue-126246.rs:11:13
|
LL | add_one(no_such_local, 10);
| ^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find value `no_such_local` in this scope
--> $DIR/suggest-better-removing-issue-126246.rs:13:17
|
LL | add_one(10, no_such_local);
| ^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find value `no_such_local` in this scope
--> $DIR/suggest-better-removing-issue-126246.rs:15:17
|
LL | add_two(10, no_such_local, 10);
| ^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find value `no_such_local` in this scope
--> $DIR/suggest-better-removing-issue-126246.rs:17:13
|
LL | add_two(no_such_local, 10, 10);
| ^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find value `no_such_local` in this scope
--> $DIR/suggest-better-removing-issue-126246.rs:19:21
|
LL | add_two(10, 10, no_such_local);
| ^^^^^^^^^^^^^ not found in this scope

error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/suggest-better-removing-issue-126246.rs:10:5
|
LL | add_one(2, 2);
| ^^^^^^^ ---
| | |
| | unexpected argument of type `{integer}`
| help: remove the extra argument
|
note: function defined here
--> $DIR/suggest-better-removing-issue-126246.rs:1:4
|
LL | fn add_one(x: i32) -> i32 {
| ^^^^^^^ ------

error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/suggest-better-removing-issue-126246.rs:11:5
|
LL | add_one(no_such_local, 10);
| ^^^^^^^ ---------------
| |
| unexpected argument
| help: remove the extra argument
|
note: function defined here
--> $DIR/suggest-better-removing-issue-126246.rs:1:4
|
LL | fn add_one(x: i32) -> i32 {
| ^^^^^^^ ------

error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/suggest-better-removing-issue-126246.rs:13:5
|
LL | add_one(10, no_such_local);
| ^^^^^^^ ---------------
| | |
| | unexpected argument
| help: remove the extra argument
|
note: function defined here
--> $DIR/suggest-better-removing-issue-126246.rs:1:4
|
LL | fn add_one(x: i32) -> i32 {
| ^^^^^^^ ------

error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/suggest-better-removing-issue-126246.rs:15:5
|
LL | add_two(10, no_such_local, 10);
| ^^^^^^^ ---------------
| | |
| | unexpected argument
| help: remove the extra argument
|
note: function defined here
--> $DIR/suggest-better-removing-issue-126246.rs:5:4
|
LL | fn add_two(x: i32, y: i32) -> i32 {
| ^^^^^^^ ------ ------

error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/suggest-better-removing-issue-126246.rs:17:5
|
LL | add_two(no_such_local, 10, 10);
| ^^^^^^^ ---------------
| |
| unexpected argument
| help: remove the extra argument
|
note: function defined here
--> $DIR/suggest-better-removing-issue-126246.rs:5:4
|
LL | fn add_two(x: i32, y: i32) -> i32 {
| ^^^^^^^ ------ ------

error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/suggest-better-removing-issue-126246.rs:19:5
|
LL | add_two(10, 10, no_such_local);
| ^^^^^^^ ---------------
| | |
| | unexpected argument
| help: remove the extra argument
|
note: function defined here
--> $DIR/suggest-better-removing-issue-126246.rs:5:4
|
LL | fn add_two(x: i32, y: i32) -> i32 {
| ^^^^^^^ ------ ------

error: aborting due to 11 previous errors

Some errors have detailed explanations: E0061, E0425.
For more information about an error, try `rustc --explain E0061`.
Loading