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

needless_borrows_for_generic_args: Fix for &mut #12892

Merged
merged 2 commits into from
Jul 25, 2024

Conversation

meithecatte
Copy link
Contributor

@meithecatte meithecatte commented Jun 5, 2024

This commit fixes a bug introduced in #12706, where the behavior of the lint has been changed, to avoid suggestions that introduce a move. The motivation in the commit message is quite poor (if the detection for significant drops is not sufficient because it's not transitive, the proper fix would be to make it transitive). However, #12454, the linked issue, provides a good reason for the change — if the value being borrowed is bound to a variable, then moving it will only introduce friction into future refactorings.

Thus #12706 changes the logic so that the lint triggers if the value being borrowed is Copy, or is the result of a function call, simplifying the logic to the point where analysing "is this the only use of this value" isn't necessary.

However, said PR also introduces an undocumented carveout, where referents that themselves are mutable references are treated as Copy, to catch some cases that we do want to lint against. However, that is not sound — it's possible to consume a mutable reference by moving it.

To avoid emitting false suggestions, this PR reintroduces the referent_used_exactly_once logic and runs that check for referents that are themselves mutable references.

Thinking about the code shape of &mut x, where x: &mut T, raises the point that while removing the &mut outright won't work, the extra indirection is still undesirable, and perhaps instead we should suggest reborrowing: &mut *x. That, however, is left as possible future work.

Fixes #12856

changelog: none

@rustbot
Copy link
Collaborator

rustbot commented Jun 5, 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 Jun 5, 2024
@meithecatte meithecatte force-pushed the needless-borrows-mutrefs branch 2 times, most recently from 1ce1b47 to 2f21dcf Compare June 6, 2024 13:56
This commit fixes a bug introduced in rust-lang#12706, where the behavior of the
lint has been changed, to avoid suggestions that introduce a move. The
motivation in the commit message is quite poor (if the detection for
significant drops is not sufficient because it's not transitive, the
proper fix would be to make it transitive). However, rust-lang#12454, the linked
issue, provides a good reason for the change — if the value being
borrowed is bound to a variable, then moving it will only introduce
friction into future refactorings.

Thus rust-lang#12706 changes the logic so that the lint triggers if the value
being borrowed is Copy, or is the result of a function call, simplifying
the logic to the point where analysing "is this the only use of this
value" isn't necessary.

However, said PR also introduces an undocumented carveout, where
referents that themselves are mutable references are treated as Copy,
to catch some cases that we do want to lint against. However, that is
not sound — it's possible to consume a mutable reference by moving it.

To avoid emitting false suggestions, this PR reintroduces the
referent_used_exactly_once logic and runs that check for referents that
are themselves mutable references.

Thinking about the code shape of &mut x, where x: &mut T, raises the
point that while removing the &mut outright won't work, the extra
indirection is still undesirable, and perhaps instead we should suggest
reborrowing: &mut *x. That, however, is left as possible future work.

Fixes rust-lang#12856
@meithecatte meithecatte force-pushed the needless-borrows-mutrefs branch from 2f21dcf to c6cc160 Compare June 6, 2024 15:04
@xFrednet
Copy link
Member

Hey, this is triage: It looks like @Jarcho is currently busy, let's pick a new reviewer.

r? clippy

@rustbot rustbot assigned dswij and unassigned Jarcho Jun 20, 2024
@xFrednet
Copy link
Member

Hey @dswij, rustbot has chosen you as a new reviewer. If you don't have the time, you can reassign it with r? clippy

@xFrednet
Copy link
Member

Hey, this is triage: It looks like @Jarcho is currently busy, let's pick a new reviewer.

r? xFrednet

@rustbot rustbot assigned xFrednet and unassigned dswij Jul 23, 2024
&& let ExprKind::AddrOf(_, _, inner) = reference.kind
&& !matches!(inner.kind, ExprKind::Call(..) | ExprKind::MethodCall(..))
if !(is_copy(cx, referent_ty)
|| referent_ty.is_ref() && referent_used_exactly_once(cx, possible_borrowers, reference)
Copy link
Member

Choose a reason for hiding this comment

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

In the PR description you mention:

To avoid emitting false suggestions, this PR reintroduces the referent_used_exactly_once logic and runs that check for referents that are themselves mutable references.

Where is the mutability checked?


Alos, when is this check ever run? &T/&mut T should both be copy, which should short circit the || on this line. 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

&mut T is not copy, as it must be unique. Observe how #[derive(Clone, Copy)] struct Meow<'a>(&'a mut i32); doesn't compile.

In most contexts it does behave like it is Copy, but under the hood it's actually a reborrow – and when passing a &mut to a function that takes impl Trait, the coercion that causes the reborrow doesn't happen.

Copy link
Member

Choose a reason for hiding this comment

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

Ahh, interesting TIL. Then this checks out

tests/ui/needless_borrows_for_generic_args.rs Outdated Show resolved Hide resolved
Co-authored-by: Fridtjof Stoldt <[email protected]>
@meithecatte meithecatte force-pushed the needless-borrows-mutrefs branch from 5778e49 to e63061d Compare July 24, 2024 20:29
@xFrednet
Copy link
Member

LGTM, thanks!


Roses are red,
Violets are blue,
A regression fixed,
A merge in queue

@bors
Copy link
Contributor

bors commented Jul 25, 2024

📌 Commit e63061d has been approved by xFrednet

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented Jul 25, 2024

⌛ Testing commit e63061d with merge 062b66d...

@bors
Copy link
Contributor

bors commented Jul 25, 2024

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: xFrednet
Pushing 062b66d to master...

@bors bors merged commit 062b66d into rust-lang:master Jul 25, 2024
8 checks passed
jrray added a commit to spkenv/spk that referenced this pull request Aug 2, 2024
A fix for this appears to be coming soon:
rust-lang/rust-clippy#12892

Signed-off-by: J Robert Ray <[email protected]>
@Jarcho Jarcho added the beta-nominated Nominated for backporting to the compiler in the beta channel. label Aug 7, 2024
@Jarcho
Copy link
Contributor

Jarcho commented Aug 7, 2024

Don't know if this made it into the 1.81 beta.

thomaskrause added a commit to korpling/graphANNIS that referenced this pull request Aug 20, 2024
@Jarcho Jarcho added beta-accepted Accepted for backporting to the compiler in the beta channel. and removed beta-nominated Nominated for backporting to the compiler in the beta channel. labels Aug 26, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 28, 2024
[beta] Clippy backports

r? `@Mark-Simulacrum`

Backports:
- rust-lang/rust-clippy#12892
- rust-lang/rust-clippy#13168
- rust-lang/rust-clippy#13290

Both 12892 and 13290 are fixes for stable regressions. The first is a little large, but mostly just reverts the change that caused the regression. 13168 is to handle the `Error` trait moving to core in 1.81.
@xFrednet xFrednet removed the beta-accepted Accepted for backporting to the compiler in the beta channel. label Aug 29, 2024
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_borrows_for_generic_args]: FP for &mut in generic argument
6 participants