Rollup merge of #97557 - compiler-errors:arg-mismatch-mini, r=jackh726
Fix indices and remove some unwraps in arg mismatch algorithm This is a more conservative fix than #97542, addressing some indices which were used incorectly and unwraps which are bound to panic (e.g. when the provided and expected arg counts differ). Beta nominating this as it's quite easy to cause ICEs -- I wrote a fuzzer and found hundreds of examples of ICEs. cc `@jackh726` as author of #92364, and `@estebank` as reviewer of that PR. fixes #97484 r? `@jackh726` this should be _much_ easier to review than the other PR 😅
This commit is contained in:
commit
1922f0b980
@ -445,16 +445,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let found_errors = !errors.is_empty();
|
||||
|
||||
errors.drain_filter(|error| {
|
||||
let Error::Invalid(input_idx, arg_idx, Compatibility::Incompatible(error)) = error else { return false };
|
||||
let Error::Invalid(input_idx, arg_idx, Compatibility::Incompatible(Some(e))) = error else { return false };
|
||||
let expected_ty = expected_input_tys[*arg_idx];
|
||||
let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap();
|
||||
let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap_or_else(|| tcx.ty_error());
|
||||
let cause = &self.misc(provided_args[*input_idx].span);
|
||||
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
|
||||
if let Some(e) = error {
|
||||
if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
|
||||
self.report_and_explain_type_error(trace, e).emit();
|
||||
return true;
|
||||
}
|
||||
if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
|
||||
self.report_and_explain_type_error(trace, e).emit();
|
||||
return true;
|
||||
}
|
||||
false
|
||||
});
|
||||
@ -585,7 +583,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
)) = errors.iter().next()
|
||||
{
|
||||
let expected_ty = expected_input_tys[*arg_idx];
|
||||
let provided_ty = final_arg_types[*arg_idx].map(|ty| ty.0).unwrap();
|
||||
let provided_ty = final_arg_types[*input_idx]
|
||||
.map(|ty| ty.0)
|
||||
.unwrap_or_else(|| tcx.ty_error());
|
||||
let expected_ty = self.resolve_vars_if_possible(expected_ty);
|
||||
let provided_ty = self.resolve_vars_if_possible(provided_ty);
|
||||
let cause = &self.misc(provided_args[*input_idx].span);
|
||||
@ -595,7 +595,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&mut err,
|
||||
&provided_args[*input_idx],
|
||||
provided_ty,
|
||||
final_arg_types[*input_idx].map(|ty| ty.1).unwrap(),
|
||||
final_arg_types[*input_idx]
|
||||
.map(|ty| ty.1)
|
||||
.unwrap_or_else(|| tcx.ty_error()),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
@ -652,7 +654,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
match error {
|
||||
Error::Invalid(input_idx, arg_idx, compatibility) => {
|
||||
let expected_ty = expected_input_tys[arg_idx];
|
||||
let provided_ty = final_arg_types[input_idx].map(|ty| ty.0).unwrap();
|
||||
let provided_ty = final_arg_types[input_idx]
|
||||
.map(|ty| ty.0)
|
||||
.unwrap_or_else(|| tcx.ty_error());
|
||||
let expected_ty = self.resolve_vars_if_possible(expected_ty);
|
||||
let provided_ty = self.resolve_vars_if_possible(provided_ty);
|
||||
if let Compatibility::Incompatible(error) = &compatibility {
|
||||
@ -674,8 +678,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.emit_coerce_suggestions(
|
||||
&mut err,
|
||||
&provided_args[input_idx],
|
||||
final_arg_types[input_idx].map(|ty| ty.0).unwrap(),
|
||||
final_arg_types[input_idx].map(|ty| ty.1).unwrap(),
|
||||
provided_ty,
|
||||
// FIXME(compiler-errors): expected_ty?
|
||||
final_arg_types[input_idx]
|
||||
.map(|ty| ty.1)
|
||||
.unwrap_or_else(|| tcx.ty_error()),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
@ -860,7 +867,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let first_expected_ty =
|
||||
self.resolve_vars_if_possible(expected_input_tys[arg_idx]);
|
||||
let first_provided_ty = if let Some((ty, _)) = final_arg_types[input_idx] {
|
||||
format!(",found `{}`", ty)
|
||||
format!(", found `{}`", ty)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
@ -872,7 +879,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.resolve_vars_if_possible(expected_input_tys[other_arg_idx]);
|
||||
let other_provided_ty =
|
||||
if let Some((ty, _)) = final_arg_types[other_input_idx] {
|
||||
format!(",found `{}`", ty)
|
||||
format!(", found `{}`", ty)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
@ -888,14 +895,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Error::Permutation(args) => {
|
||||
for (dst_arg, dest_input) in args {
|
||||
let expected_ty =
|
||||
self.resolve_vars_if_possible(expected_input_tys[dest_input]);
|
||||
let provided_ty = if let Some((ty, _)) = final_arg_types[dst_arg] {
|
||||
format!(",found `{}`", ty)
|
||||
self.resolve_vars_if_possible(expected_input_tys[dst_arg]);
|
||||
let provided_ty = if let Some((ty, _)) = final_arg_types[dest_input] {
|
||||
format!(", found `{}`", ty)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
labels.push((
|
||||
provided_args[dst_arg].span,
|
||||
provided_args[dest_input].span,
|
||||
format!("expected `{}`{}", expected_ty, provided_ty),
|
||||
));
|
||||
}
|
||||
|
@ -48,9 +48,9 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/basic.rs:23:5
|
||||
|
|
||||
LL | swapped("", 1);
|
||||
| ^^^^^^^ -- - expected `&str`,found `{integer}`
|
||||
| ^^^^^^^ -- - expected `&str`, found `{integer}`
|
||||
| |
|
||||
| expected `u32`,found `&'static str`
|
||||
| expected `u32`, found `&'static str`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/basic.rs:16:4
|
||||
@ -66,10 +66,10 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/basic.rs:24:5
|
||||
|
|
||||
LL | permuted(Y {}, Z {}, X {});
|
||||
| ^^^^^^^^ ---- ---- ---- expected `Z`,found `X`
|
||||
| ^^^^^^^^ ---- ---- ---- expected `Z`, found `X`
|
||||
| | |
|
||||
| | expected `Y`,found `Z`
|
||||
| expected `X`,found `Y`
|
||||
| | expected `Y`, found `Z`
|
||||
| expected `X`, found `Y`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/basic.rs:17:4
|
||||
|
14
src/test/ui/argument-suggestions/issue-97484.rs
Normal file
14
src/test/ui/argument-suggestions/issue-97484.rs
Normal file
@ -0,0 +1,14 @@
|
||||
struct A;
|
||||
struct B;
|
||||
struct C;
|
||||
struct D;
|
||||
struct E;
|
||||
struct F;
|
||||
struct G;
|
||||
|
||||
fn foo(a: &A, d: D, e: &E, g: G) {}
|
||||
|
||||
fn main() {
|
||||
foo(&&A, B, C, D, E, F, G);
|
||||
//~^ ERROR this function takes 4 arguments but 7 arguments were supplied
|
||||
}
|
27
src/test/ui/argument-suggestions/issue-97484.stderr
Normal file
27
src/test/ui/argument-suggestions/issue-97484.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
error[E0061]: this function takes 4 arguments but 7 arguments were supplied
|
||||
--> $DIR/issue-97484.rs:12:5
|
||||
|
|
||||
LL | foo(&&A, B, C, D, E, F, G);
|
||||
| ^^^ - - - argument unexpected
|
||||
| | |
|
||||
| | argument of type `&E` unexpected
|
||||
| argument of type `D` unexpected
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/issue-97484.rs:9:4
|
||||
|
|
||||
LL | fn foo(a: &A, d: D, e: &E, g: G) {}
|
||||
| ^^^ ----- ---- ----- ----
|
||||
help: consider removing the ``
|
||||
|
|
||||
LL - foo(&&A, B, C, D, E, F, G);
|
||||
LL + foo(&&A, B, C, D, E, F, G);
|
||||
|
|
||||
help: remove the extra arguments
|
||||
|
|
||||
LL | foo(&&A, D, {&E}, G);
|
||||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0061`.
|
@ -76,10 +76,10 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/mixed_cases.rs:20:3
|
||||
|
|
||||
LL | three_args("", X {}, 1);
|
||||
| ^^^^^^^^^^ -- ---- - expected `&str`,found `{integer}`
|
||||
| ^^^^^^^^^^ -- ---- - expected `&str`, found `{integer}`
|
||||
| | |
|
||||
| | expected `f32`, found struct `X`
|
||||
| expected `i32`,found `&'static str`
|
||||
| expected `i32`, found `&'static str`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/mixed_cases.rs:6:4
|
||||
@ -98,8 +98,8 @@ LL | three_args("", 1);
|
||||
| ^^^^^^^^^^ -- -
|
||||
| | |
|
||||
| | an argument of type `f32` is missing
|
||||
| | expected `&str`,found `{integer}`
|
||||
| expected `i32`,found `&'static str`
|
||||
| | expected `&str`, found `{integer}`
|
||||
| expected `i32`, found `&'static str`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/mixed_cases.rs:6:4
|
||||
|
@ -2,10 +2,10 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/permuted_arguments.rs:10:3
|
||||
|
|
||||
LL | three_args(1.0, "", 1);
|
||||
| ^^^^^^^^^^ --- -- - expected `&str`,found `{integer}`
|
||||
| ^^^^^^^^^^ --- -- - expected `&str`, found `{integer}`
|
||||
| | |
|
||||
| | expected `f32`,found `&'static str`
|
||||
| expected `i32`,found `{float}`
|
||||
| | expected `f32`, found `&'static str`
|
||||
| expected `i32`, found `{float}`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/permuted_arguments.rs:5:4
|
||||
@ -21,12 +21,12 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/permuted_arguments.rs:12:3
|
||||
|
|
||||
LL | many_args(X {}, Y {}, 1, 1.0, "");
|
||||
| ^^^^^^^^^ ---- ---- - --- -- expected `Y`,found `&'static str`
|
||||
| ^^^^^^^^^ ---- ---- - --- -- expected `Y`, found `&'static str`
|
||||
| | | | |
|
||||
| | | | expected `X`,found `{float}`
|
||||
| | | expected `&str`,found `{integer}`
|
||||
| | expected `f32`,found `Y`
|
||||
| expected `i32`,found `X`
|
||||
| | | | expected `X`, found `{float}`
|
||||
| | | expected `&str`, found `{integer}`
|
||||
| | expected `f32`, found `Y`
|
||||
| expected `i32`, found `X`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/permuted_arguments.rs:6:4
|
||||
|
@ -2,9 +2,9 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/swapped_arguments.rs:8:3
|
||||
|
|
||||
LL | two_args(1.0, 1);
|
||||
| ^^^^^^^^ --- - expected `f32`,found `{integer}`
|
||||
| ^^^^^^^^ --- - expected `f32`, found `{integer}`
|
||||
| |
|
||||
| expected `i32`,found `{float}`
|
||||
| expected `i32`, found `{float}`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/swapped_arguments.rs:3:4
|
||||
@ -20,9 +20,9 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/swapped_arguments.rs:9:3
|
||||
|
|
||||
LL | three_args(1.0, 1, "");
|
||||
| ^^^^^^^^^^ --- - expected `f32`,found `{integer}`
|
||||
| ^^^^^^^^^^ --- - expected `f32`, found `{integer}`
|
||||
| |
|
||||
| expected `i32`,found `{float}`
|
||||
| expected `i32`, found `{float}`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/swapped_arguments.rs:4:4
|
||||
@ -38,9 +38,9 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/swapped_arguments.rs:10:3
|
||||
|
|
||||
LL | three_args( 1, "", 1.0);
|
||||
| ^^^^^^^^^^ -- --- expected `&str`,found `{float}`
|
||||
| ^^^^^^^^^^ -- --- expected `&str`, found `{float}`
|
||||
| |
|
||||
| expected `f32`,found `&'static str`
|
||||
| expected `f32`, found `&'static str`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/swapped_arguments.rs:4:4
|
||||
@ -56,9 +56,9 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/swapped_arguments.rs:11:3
|
||||
|
|
||||
LL | three_args( "", 1.0, 1);
|
||||
| ^^^^^^^^^^ -- - expected `&str`,found `{integer}`
|
||||
| ^^^^^^^^^^ -- - expected `&str`, found `{integer}`
|
||||
| |
|
||||
| expected `i32`,found `&'static str`
|
||||
| expected `i32`, found `&'static str`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/swapped_arguments.rs:4:4
|
||||
@ -74,11 +74,11 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/swapped_arguments.rs:13:3
|
||||
|
|
||||
LL | four_args(1.0, 1, X {}, "");
|
||||
| ^^^^^^^^^ --- - ---- -- expected `X`,found `&'static str`
|
||||
| ^^^^^^^^^ --- - ---- -- expected `X`, found `&'static str`
|
||||
| | | |
|
||||
| | | expected `&str`,found `X`
|
||||
| | expected `f32`,found `{integer}`
|
||||
| expected `i32`,found `{float}`
|
||||
| | | expected `&str`, found `X`
|
||||
| | expected `f32`, found `{integer}`
|
||||
| expected `i32`, found `{float}`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/swapped_arguments.rs:5:4
|
||||
|
Loading…
x
Reference in New Issue
Block a user