Skip to content
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

Merged
merged 3 commits into from
Jun 9, 2022

Conversation

compiler-errors
Copy link
Member

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 😅

@compiler-errors compiler-errors added the beta-nominated Nominated for backporting to the compiler in the beta channel. label May 30, 2022
@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label May 30, 2022
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 30, 2022
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());
Copy link
Member Author

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]);
Copy link
Member Author

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]
Copy link
Member Author

@compiler-errors compiler-errors May 30, 2022

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]
Copy link
Member Author

@compiler-errors compiler-errors May 30, 2022

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.

Copy link
Contributor

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)?

Copy link
Member Author

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?

Comment on lines +15 to +19
help: consider removing the ``
|
LL - foo(&&A, B, C, D, E, F, G);
LL + foo(&&A, B, C, D, E, F, G);
|
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Member Author

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).

Comment on lines +20 to +23
help: remove the extra arguments
|
LL | foo(&&A, D, {&E}, G);
| ~~~~~~~~~~~~~~~~~~~~
Copy link
Contributor

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 :)

Copy link
Member Author

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.

@apiraino
Copy link
Contributor

apiraino commented Jun 8, 2022

Beta backport not accepted in favor of #97701. T-compiler Zulip discussion, especially around this comment.

@rustbot label -beta-nominated

@rustbot rustbot removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label Jun 8, 2022
@compiler-errors
Copy link
Member Author

@estebank and @jackh726, would appreciate a review from either of y'all sometime so we could land this on nightly, especially if the larger rewrite is going to take a longer time to review

@jackh726
Copy link
Member

jackh726 commented Jun 8, 2022

@bors r+

@bors
Copy link
Contributor

bors commented Jun 8, 2022

📌 Commit 4b26d41 has been approved by jackh726

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 8, 2022
bors added a commit to rust-lang-ci/rust that referenced this pull request Jun 8, 2022
…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
@bors bors merged commit 1922f0b into rust-lang:master Jun 9, 2022
@rustbot rustbot added this to the 1.63.0 milestone Jun 9, 2022
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Jun 29, 2022
…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
@compiler-errors compiler-errors deleted the arg-mismatch-mini branch August 11, 2023 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Broke rustc while refactoring method args in async yolo code
7 participants