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

Warn about explicit self-assignment #5894

Merged
merged 4 commits into from
Aug 16, 2020
Merged

Warn about explicit self-assignment #5894

merged 4 commits into from
Aug 16, 2020

Conversation

tmiasko
Copy link
Contributor

@tmiasko tmiasko commented Aug 11, 2020

Warn about assignments where left-hand side place expression is the same
as right-hand side value expression. For example, warn about assignment in:

pub struct Event {
    id: usize,
    x: i32,
    y: i32,
}

pub fn copy_position(a: &mut Event, b: &Event) {
    a.x = b.x;
    a.y = a.y;
}

changelog: New lint self_assignment, checks for explicit self-assignments.

@rust-highfive
Copy link

r? @Manishearth

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Aug 11, 2020
@tesuji
Copy link
Contributor

tesuji commented Aug 15, 2020

Not locking this lint from merging, but I find this lint really helpful: Why not lint it in rustc ?

@tmiasko
Copy link
Contributor Author

tmiasko commented Aug 15, 2020

I would expect that rustc version would have to be very conservative with
respect to any user defined Deref / Index / IndexMut, limiting the utility of
the lint. But if this isn't actually the case, moving to rustc would be OK.

Advice about this aspect would be appreciated.

@Manishearth
Copy link
Member

Not locking this lint from merging, but I find this lint really helpful: Why not lint it in rustc ?

rustc is conservative to accept lints. You can always file an issue on rustc to uplift a lint, they're often open to that, but it's up to them

}

/// Returns true if two expressions are the same and don't have any "obvious" side-effects.
fn is_same_expr<'tcx>(mut a: &Expr<'tcx>, mut b: &Expr<'tcx>, place_expr: bool) -> bool {
Copy link
Member

Choose a reason for hiding this comment

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

this should go in utils (and perhaps check if something like this doesn't already exist)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The implementation is similar to SpanlessEq::eq_expr. The main difference is
that the one here returns false for expressions with side-effects (except for
those that might involve Deref, Index, IndexMut), while SpanlessEq has option
to exclude side-effects but only in the form of function calls.

For now I retained custom impl, but moved it to utils.

Copy link
Member

@flip1995 flip1995 Aug 16, 2020

Choose a reason for hiding this comment

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

Would it make sense to enhance SpanlessEq with an option to exclude all side effects?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, after reviewing all uses of SpanlessEq::ignore_fn, it is clear that intent
behind it is the same, even if details differed previously. I extended it to
consider additional side effects, renamed ignore_fn to deny_side_effects,
and introduced eq_expr_value as a short-cut.

@bors
Copy link
Collaborator

bors commented Aug 16, 2020

☔ The latest upstream changes (presumably #5903) made this pull request unmergeable. Please resolve the merge conflicts.

Introduce `eq_expr_value(cx, a, b)` as a shortcut for
`SpanlessEq::new(cx).ignore_fn().eq_expr(cx, a, b)`.

No functional changes intended.
No functional changes intended.
Warn about assignments where left-hand side place expression is the same
as right-hand side value expression. For example, warn about assignment in:

```rust
pub struct Event {
    id: usize,
    x: i32,
    y: i32,
}

pub fn copy_position(a: &mut Event, b: &Event) {
    a.x = b.x;
    a.y = a.y;
}
```
@Manishearth
Copy link
Member

@bors r+

sweet, this is much cleaner, thanks

@bors
Copy link
Collaborator

bors commented Aug 16, 2020

📌 Commit 4f4abf4 has been approved by Manishearth

@bors
Copy link
Collaborator

bors commented Aug 16, 2020

⌛ Testing commit 4f4abf4 with merge 8332fe8...

@bors
Copy link
Collaborator

bors commented Aug 16, 2020

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: Manishearth
Pushing 8332fe8 to master...

@bors bors merged commit 8332fe8 into rust-lang:master Aug 16, 2020
@tmiasko tmiasko deleted the self-assignment branch August 16, 2020 22:22
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.

None yet

6 participants