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 needless_borrow suggestion #7105

Merged
merged 2 commits into from May 21, 2021
Merged

Conversation

Jarcho
Copy link
Contributor

@Jarcho Jarcho commented Apr 18, 2021

fixes: #2610

While I'm working on this, should needless_borrow be split into two? One lint for expressions and another for patterns. In expression it only lints when the compiler inserts a dereference, but for patterns it's whenever a double reference is created. I think at least the case where a double reference is needed should be split into a new lint as it's not 'needless', it can just be done without a ref binding.

For illustration:

fn foo(x: &&str) {}

match Some("test") {
    // ref binding is useless here
    Some(ref x) => *x,
    _ => (),
}

match Some("test") {
    // ref binding is useless here
    Some(ref x) => x.len(),
    _ => (),
}

match Some("test") {
    // double reference is needed, but could be `Some(x) => foo(&x)`
    Some(ref x) => foo(x),
    _ => (),
}

changelog: Improve the suggestion for needless_borrow in patterns to change all usage sites as needed.
changelog: Add lint ref_binding_to_reference

@rust-highfive
Copy link

r? @camsteffen

(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 Apr 18, 2021
@Jarcho Jarcho force-pushed the needless_borrow_pat branch 3 times, most recently from 8b641ae to 484a2af Compare April 18, 2021 02:28
@camsteffen
Copy link
Contributor

should needless_borrow be split into two?

I think that would be a good idea since needless_borrow will be a rather noisy lint. And it would be a clean, sensible split to lint patterns separately.

the case where a double reference is needed should be split into a new lint as it's not 'needless', it can just be done without a ref binding

Consider the case where you have a variable var that is a &T and you pass it to a function as fun(&var). This is creating a double reference, but not in a pattern. Also consider the case where you have a ref binding to a value that is Copy. That is a needless ref binding, but not a double reference. So there is a matrix of possibilities. I would call the split lint needless_ref_binding. Both lints may detect a double reference or a reference of a Copy. But one lint applies to ref patterns and the other applies to & borrows.

@Jarcho
Copy link
Contributor Author

Jarcho commented Apr 19, 2021

I'm fine with splitting this between patterns and expressions. I don't see it as particularly beneficial, but I also don't see it as particularly harmful to do so either. In both cases a value is borrowed when there was no need to do so. References to other copy types aren't linted at all right now, but would definitely fit the current name.

For the pattern part of this lint, however, it currently triggers on any reference-to-reference created, even when it's actually needed (see the final example). It's this that I believe should definitely be split out as the borrow isn't needless. The choice of where the borrow is created is more stylistic than anything.

The split can be done in a different PR anyways, This is currently in the nursery, and this is behaviour that already existed.

@camsteffen
Copy link
Contributor

For the pattern part of this lint, however, it currently triggers on any reference-to-reference created, even when it's actually needed (see the final example). It's this that I believe should definitely be split out as the borrow isn't needless.

I don't think that case should lint at all. That is, only lint if every usage of the binding has an implicit or explicit deref.

@camsteffen
Copy link
Contributor

camsteffen commented Apr 19, 2021

Hmm I see now the value in making a separate lint for that. Like double_ref_binding, but only lint cases not already linted by needless_borrow?

Copy link
Member

@flip1995 flip1995 left a comment

Choose a reason for hiding this comment

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

Just a quick comment

clippy_lints/src/needless_borrow.rs Outdated Show resolved Hide resolved
@Jarcho
Copy link
Contributor Author

Jarcho commented Apr 21, 2021

The case where the reference is needed has been split into it's own lint. Should the pattern part of needless borrow still be separated? Would probably be called something like needless_ref_binding.

@camsteffen
Copy link
Contributor

Should the pattern part of needless borrow still be separated? Would probably be called something like needless_ref_binding.

I'm in favor. But I'd rather split lints in a separate PR.

@Jarcho
Copy link
Contributor Author

Jarcho commented Apr 22, 2021

Sounds good.

clippy_lints/src/needless_borrow.rs Outdated Show resolved Hide resolved
clippy_utils/src/visitors.rs Outdated Show resolved Hide resolved
tests/ui/needless_borrow_pat.rs Outdated Show resolved Hide resolved
clippy_lints/src/needless_borrow.rs Outdated Show resolved Hide resolved
clippy_lints/src/needless_borrow.rs Outdated Show resolved Hide resolved
clippy_lints/src/needless_borrow.rs Show resolved Hide resolved
clippy_lints/src/needless_borrow.rs Show resolved Hide resolved
clippy_lints/src/needless_borrow.rs Outdated Show resolved Hide resolved
clippy_lints/src/needless_borrow.rs Outdated Show resolved Hide resolved
clippy_lints/src/needless_borrow.rs Show resolved Hide resolved
@giraffate
Copy link
Contributor

ping from triage @Jarcho. There seems to be some fixes left to be done. Can you have any updates on this?

@Jarcho
Copy link
Contributor Author

Jarcho commented May 19, 2021

Ended up requiring the pattern to not come from a macro. There's a lot of ways for that to be a false positive.

@Jarcho Jarcho force-pushed the needless_borrow_pat branch 2 times, most recently from 33cd006 to bc84d30 Compare May 19, 2021 04:00
@camsteffen
Copy link
Contributor

camsteffen commented May 19, 2021

Implementation is looking good. Nice work @Jarcho!

I just want to consider the lint categories before merging...

I think this resolves the only major bug for needless_borrow, so it can be moved out of nursery in this PR? I'm a bit worried about how noisy the lint will be, but otherwise it seems to fit style since it strictly simplifies code. So I think it's okay to move it to style if there are no other concerns.

For ref_binding_to_reference, I'm just not sure if it should warn-by-default. For example, the lint will suggest

- ref x => x,
+ x => &x,

The change seems pedantic. But on the other hand, I like the idea of banning double references by default. It gives me peace of mind to know that code doesn't have any double referenced bindings. But maybe that's just me worrying about a non-issue. That is - I am pedantic? Would like to hear other opinions. Are double referenced bindings decidedly bad style?

CC @rust-lang/clippy

@flip1995
Copy link
Member

flip1995 commented May 19, 2021

For ref_binding_to_reference I would say that it should be pedantic. Not because it is too pedantic, but because it is too opinionated IMO. I don't think Clippy should suggest that using &x in the body than ref x in the pattern is generally the better way (at least not by default).

About the needless_borrow lint: Did you run the lintcheck tool over it? I think we want to do that before moving it back to style.

@Manishearth
Copy link
Member

I agree with @flip1995 on both counts here

@Jarcho Jarcho force-pushed the needless_borrow_pat branch 3 times, most recently from 27da6a1 to 9132e4d Compare May 19, 2021 19:36
@Jarcho
Copy link
Contributor Author

Jarcho commented May 19, 2021

I thought I did put it in pedantic. Fixed now.

needless_borrow will have to wait to change categories. It has another hundred instances in clippy (I just fixed those a couple of months ago). Lintcheck has 18 for it, not too bad.

@camsteffen
Copy link
Contributor

I thought I did put it in pedantic. Fixed now.

needless_borrow will have to wait to change categories. It has another hundred instances in clippy (I just fixed those a couple of months ago). Lintcheck has 18 for it, not too bad.

Okay. Please squash commits.

@bors
Copy link
Collaborator

bors commented May 20, 2021

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

The spans given for derived traits used to not indicate they were from a macro expansion.
Suggest changing usages of ref bindings to match the new type
Split out some cases into new lint `ref_binding_to_reference`
@camsteffen
Copy link
Contributor

Thanks!

@bors r+

@bors
Copy link
Collaborator

bors commented May 21, 2021

📌 Commit 6d4dc35 has been approved by camsteffen

@bors
Copy link
Collaborator

bors commented May 21, 2021

⌛ Testing commit 6d4dc35 with merge 029c326...

@bors
Copy link
Collaborator

bors commented May 21, 2021

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: camsteffen
Pushing 029c326 to master...

@bors bors merged commit 029c326 into rust-lang:master May 21, 2021
bors added a commit that referenced this pull request May 21, 2021
Move `needless_borrow` to style

fixes: #3742

#7105 should be merged first to fix the false positive.

changelog: move `needless_borrow` from `nursery` to `style`
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.

needless_borrow suggests bad code when reference-to-reference is required
7 participants