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: identity_op suggestions use correct parenthesis #13647

Merged
merged 4 commits into from
Nov 9, 2024

Conversation

hcbarker
Copy link
Contributor

@hcbarker hcbarker commented Nov 3, 2024

The identity_op lint was suggesting code fixes that resulted in incorrect or broken code, due to missing parenthesis in the fix that changed the semantics of the code.

For a binary expression, left op right, if the left was redundant, it would check if the right side needed parenthesis, but if the right was redundant, it would just assume that the left side did not need parenthesis.

This can result in rustfix generating broken code and failing, or generating code that has different behavior than before the fix. e.g. -(x + y + 0) would turn into -x + y, changing the behavior, and 1u64 + (x + y + 0i32) as u64 where x: i32 and y: i32 would turn into 1u64 + x + y as u64, creating an error where x cannot be added to the other values, as it was never cast to u64.

This commit fixes both of these problems by always checking the non-redundant child of a binary expression for needed parenthesis.

fixes #13470

changelog: [identity_op]: Fix suggested code that is broken or has changed behavior

The `identity_op` lint was suggesting code fixes that resulted
in incorrect or broken code, due to missing parenthesis in the fix
that changed the semantics of the code.

For a binary expression, `left op right`, if the `left` was redundant,
it would check if the right side needed parenthesis, but if the `right`
was redundant, it would just assume that the left side did not need
parenthesis.

This can result in either rustfix generating broken code and failing,
or code that has different behavior than before the fix.
e.g. `-(x + y + 0)` would turn into `-x + y`, changing the behavior,
and `1u64 + (x + y + 0i32) as u64` where `x: i32` and `y: i32` would
turn into `1u64 + x + y as u64`, creating broken code where `x` cannot
be added to the other values, as it was never cast to `u64`.

This commit fixes both of these cases by always checking the
non-redundant child of a binary expression for needed parenthesis, and
makes it so if we need parenthesis, but they already exist, we don't add
any redundant ones.

Fixes rust-lang#13470
@rustbot
Copy link
Collaborator

rustbot commented Nov 3, 2024

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Jarcho (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Nov 3, 2024
@@ -234,7 +220,13 @@ fn span_ineffective_operation(
expr_snippet.into_owned()
};
let suggestion = match parens {
Parens::Needed => format!("({expr_snippet})"),
Parens::Needed => {
if !expr_snippet.starts_with('(') && !expr_snippet.ends_with(')') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't actually work. Something like (x) + (y) would act as though it has parenthesis.

Comment on lines 367 to 368
LL | let _ = 2 + (x + (y * z) + 0);
| ^^^^^^^^^^^^^^^^^ help: consider reducing it to: `x + (y * z)`
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 a very subtle behaviour change that can result in an overflow. x + (y*z) can exceed the minimum value on signed integers in cases where 2 + x + (x*z) do not.

Even without that this shouldn't be suggesting to remove the parenthesis.

It was an incorrect, and could lead to behavior changes in the
suggested code
@hcbarker
Copy link
Contributor Author

hcbarker commented Nov 8, 2024

@Jarcho Thanks a bunch for the review, I believe I have resolved both of the issues you pointed out!

@Jarcho
Copy link
Contributor

Jarcho commented Nov 9, 2024

Thank you. @bors r+

@bors
Copy link
Contributor

bors commented Nov 9, 2024

@Jarcho: 🔑 Insufficient privileges: Not in reviewers

@Jarcho Jarcho added this pull request to the merge queue Nov 9, 2024
Merged via the queue into rust-lang:master with commit 8cfb959 Nov 9, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

clippy --fix "failed to automatically apply fixes suggested by rustc"
4 participants