-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix indices and remove some unwraps in arg mismatch algorithm #97557
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be using |
||
.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] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should actually probably be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about changing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but emit_coerce_suggestions can't do anything if we don't have a target type to coerce to, right? |
||
.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]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these were swapped -- |
||
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), | ||
)); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
| | ||
Comment on lines
+15
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is buggy (which, fair, you're sidestepping the ICE). Given that after this we suggest removing some args, it tells me that we can better handle this case to not emit it at all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually know how to fix this one, and I think I fixed it on the more extensive fix. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The technical explanation is that we're trying to coerce |
||
help: remove the extra arguments | ||
| | ||
LL | foo(&&A, D, {&E}, G); | ||
| ~~~~~~~~~~~~~~~~~~~~ | ||
Comment on lines
+20
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This tells me that we should teach the suggestion to add and remove borrows as well :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should fall out of coercion suggestions which we attempt when we see an "invalid" argument. |
||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0061`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final_arg_types
is a vector of lengthprovided_args.len()
, but is only populated withSome
(bydemand_compatible
) up toexpected_input_tys.len()
. This unwrap was panicking in a bunch of cases.