Skip to content

manual_pop_if: avoid invalid automatic suggestions - #17561

Open
cuishuang wants to merge 3 commits into
rust-lang:masterfrom
cuishuang:fix-manual-pop-if-captured-collection
Open

manual_pop_if: avoid invalid automatic suggestions#17561
cuishuang wants to merge 3 commits into
rust-lang:masterfrom
cuishuang:fix-manual-pop-if-captured-collection

Conversation

@cuishuang

Copy link
Copy Markdown
Contributor

changelog: [manual_pop_if]: avoid invalid automatic suggestions when the predicate borrows the collection

manual_pop_if could emit a machine-applicable suggestion when the predicate also referenced the collection being popped from.

For example, rewriting:

if vec
    .last()
    .is_some_and(|x| vec.len() > 1 && *x > 10)
{
    vec.pop().unwrap();
}

to vec.pop_if(...) requires a mutable borrow of vec while the predicate closure also immutably borrows it, causing E0502.

Only provide an automatic suggestion when the collection is a simple local path and the predicate does not reference that local. Continue emitting the lint with a help message for captured or non-local collection expressions.

Also retain the parameter pattern and avoid automatic rewrites for non-default binding modes such as ref and mut, since the predicate parameter changes from &T to &mut T.

Add UI coverage for all supported condition forms, complex collection expressions, and non-default parameter bindings.

@rustbot rustbot added S-waiting-on-community-reviews Status: This is awaiting for positive reviews from the community before a maintainer is assigned. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Aug 14, 2026
@rustbot

rustbot commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request. A reviewer will take a look after it receives 2 community reviews.

In the meantime, we would highly appreciate if you could try to review any of PRs waiting on community reviews.

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

@cuishuang
cuishuang force-pushed the fix-manual-pop-if-captured-collection branch from dd2bc7a to 92276c9 Compare August 16, 2026 00:28

@NicDevTV NicDevTV left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Could we also handle indirect borrows here? For example, let r = &vec; ... |x| r.len() > 1 ... isn’t detected, but rewriting to vec.pop_if(...) fails with E0502. The automatic suggestion should be suppressed in this case.

View changes since this review

@CommanderStorm CommanderStorm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

community review:
Code wise good start, I am not quite happy with the wording of the new diags...

View changes since this review

Comment thread tests/ui/manual_pop_if_unfixable.stderr Outdated
Comment thread tests/ui/manual_pop_if_unfixable.stderr
Comment thread tests/ui/manual_pop_if_unfixable.stderr
Comment thread tests/ui/manual_pop_if_unfixable.stderr Outdated
Comment thread clippy_lints/src/manual_pop_if.rs Outdated
Comment thread tests/ui/manual_pop_if_unfixable.rs
@rustbot

This comment has been minimized.

@cuishuang
cuishuang force-pushed the fix-manual-pop-if-captured-collection branch from 92276c9 to 9731f93 Compare August 21, 2026 05:27
@rustbot

rustbot commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@cuishuang

Copy link
Copy Markdown
Contributor Author

@CommanderStorm Thanks for the detailed feedback. I addressed the comments as follows:

  • Removed the confusing explanation about automatic rewrites for non-default binding patterns.
  • Added a span label at the collection use inside predicates that borrow the collection.
  • Simplified the help for complex collection expressions.
  • Moved suggestion classification into check_pop_unwrap.
  • Kept pattern-preserving rewrites such as |ref x| out of this PR to keep the scope focused on avoiding invalid MachineApplicable suggestions. This can be handled in a follow-up.

I also rebased onto the latest upstream master and resolved the merge conflict. Please review it again.

Comment on lines +57 to +60
LL | if vec.last().is_some_and(|x| vec.len() > 1 && *x > 10) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^^^^^^^^^^^^^^^^^^^^^
| |
| the predicate borrows the collection here

@CommanderStorm CommanderStorm Aug 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is the span here entierly correct? It also includes the if...

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, the secondary span is intended to cover only the vec path in vec.len(). The surrounding ^ characters belong to the primary lint span, which covers the whole if condition. The --- section is the secondary label for the collection borrow, so it does not include the if.
I agree that the overlapping spans make the rendered output a little confusing.

Comment on lines +143 to +146
LL | if vec.len() > 1 && *x > 10 {
| ^^^---^^^^^^^^^^^^^^^^^^^^^
| |
| the predicate borrows the collection here

@CommanderStorm CommanderStorm Aug 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the span here also seems a bit suspect.. You sure that this is correct?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The same applies here. The secondary span is taken from the HIR span of the vec path used in the predicate. The ^^^ before it belongs to the existing primary span for the inner condition, while the --- marks only the collection use.

So the labeled span is limited to vec, not the surrounding if. I can adjust the diagnostic presentation if the overlapping spans are considered too confusing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-community-reviews Status: This is awaiting for positive reviews from the community before a maintainer is assigned. 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.

4 participants