-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Conversation
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()); |
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 length provided_args.len()
, but is only populated with Some
(by demand_compatible
) up to expected_input_tys.len()
. This unwrap was panicking in a bunch of cases.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
I think these were swapped -- dst_arg
is an "expected argument"-like index, and dst_input
is a "provided argument"-like index.
@@ -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 comment
The reason will be displayed to describe this comment to others. Learn more.
Should be using input_idx
. Not sure if this is "correct" (though I think it is), but regardless, if there are more expected args than provided args, then using arg_idx
might be out of bounds.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
This should actually probably be expected_ty
instead of final_arg_types[input_idx].1
, but this will just provide a bad suggestion, and not panic.
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.
What about changing emit_coerce_suggestions
to take an Option
here instead (and make it not emit the invalid suggestion when it is None
)?
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.
but emit_coerce_suggestions can't do anything if we don't have a target type to coerce to, right?
8986bd2
to
4b26d41
Compare
help: consider removing the `` | ||
| | ||
LL - foo(&&A, B, C, D, E, F, G); | ||
LL + foo(&&A, B, C, D, E, F, G); | ||
| |
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.
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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
The technical explanation is that we're trying to coerce &&A
into &&A
, and the current suggestion logic goes "ah yes, dereference it zero times" (well, actually, remove &
zero times).
help: remove the extra arguments | ||
| | ||
LL | foo(&&A, D, {&E}, G); | ||
| ~~~~~~~~~~~~~~~~~~~~ |
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.
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 comment
The 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.
Beta backport not accepted in favor of #97701. T-compiler Zulip discussion, especially around this comment. @rustbot label -beta-nominated |
@bors r+ |
📌 Commit 4b26d41 has been approved by |
…piler-errors Rollup of 9 pull requests Successful merges: - rust-lang#97557 (Fix indices and remove some unwraps in arg mismatch algorithm) - rust-lang#97830 (Add std::alloc::set_alloc_error_hook example) - rust-lang#97856 (Don't suggest adding `let` in certain `if` conditions) - rust-lang#97857 (Suggest escaping `box` as identifier) - rust-lang#97871 (Suggest using `iter()` or `into_iter()` for `Vec`) - rust-lang#97882 (Add regresion test for rust-lang#67498) - rust-lang#97883 (Remove `ignore-compare-mode-nll` annotations from tests) - rust-lang#97891 (Update books) - rust-lang#97894 (Fix polonius compare mode.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
…kh726 Use typed indices in argument mismatch algorithm I kinda went overboard with the renames, but in general, "arg" is renamed to "expected", and "input" is renamed to "provided", and we use new typed indices to make sure we're indexing into the right sized array. Other drive-by changes: 1. Factor this logic into a new function, so we don't need to `break 'label` to escape it. 1. Factored out dependence on `final_arg_types`, which is never populated for arguments greater than the number of expected args. Instead, we just grab the final coerced expression type from `in_progress_typeck_results`. 1. Adjust the criteria we use to print (provided) type names, before we didn't suggest anything that had infer vars, but now we suggest thing that have infer vars but aren't `_`. ~Also, sorry in advance, I kinda want to backport this but I know I have folded in a lot of unnecessary drive-by changes that might discourage that. I would be open to brainstorming how to get some of these changes on beta at least.~ edit: Minimized the ICE-fixing changes to rust-lang#97557 cc `@jackh726` as author of rust-lang#92364, and `@estebank` as reviewer of the PR. fixes rust-lang#97484
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 😅