Skip to content

manual_pop_if: lint when the popped value is discarded - #17630

Open
Iurig wants to merge 3 commits into
rust-lang:masterfrom
Iurig:manual_pop_if_bare_pop
Open

manual_pop_if: lint when the popped value is discarded#17630
Iurig wants to merge 3 commits into
rust-lang:masterfrom
Iurig:manual_pop_if_bare_pop

Conversation

@Iurig

@Iurig Iurig commented Aug 25, 2026

Copy link
Copy Markdown

changelog: [manual_pop_if]: also lint when the popped value is discarded, e.g. vec.pop();

if vec.last().is_some_and(|x| *x > 5) { vec.pop(); } is exactly vec.pop_if(|x| *x > 5);, but the lint only fired when the popped value was unwrapped. Accept a pop whose value is thrown away as well, both as a plain collection.pop(); statement and as let _ = collection.pop();.

A discarded pop is only recognised in statement position. Unlike .unwrap(), a collection.pop() in value position carries no assertion that the collection is non-empty, so walking every expression for one would be a large false-positive surface for no benefit.

An annotated let _: Option<i32> = collection.pop(); is left alone too: the suggestion replaces the whole statement, and the annotation may be the only thing pinning down the element type of the collection.

`if vec.last().is_some_and(|x| *x > 5) { vec.pop(); }` is exactly
`vec.pop_if(|x| *x > 5);`, but the lint only fired when the popped value
was unwrapped. Accept a pop whose value is thrown away as well, both as a
plain `collection.pop();` statement and as `let _ = collection.pop();`.

A discarded pop is only recognised in statement position. Unlike
`.unwrap()`, a `collection.pop()` in value position carries no assertion
that the collection is non-empty, so walking every expression for one
would be a large false-positive surface for no benefit.

An annotated `let _: Option<i32> = collection.pop();` is left alone too:
the suggestion replaces the whole statement, and the annotation may be
the only thing pinning down the element type of the collection.
@rustbot rustbot added the S-waiting-on-community-reviews Status: This is awaiting for positive reviews from the community before a maintainer is assigned. label Aug 25, 2026
@rustbot

rustbot commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome!

You should hear from one of our reviewers after this PR gets at least 2 reviews from the community.

Please see the contribution instructions for more information.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Aug 25, 2026

@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.

Looks to be about the code we need.
Two minor cleanups.

View changes since this review

Comment thread clippy_lints/src/manual_pop_if.rs Outdated
Comment on lines +449 to +455
// A statement that pops and throws the value away: `collection.pop();` or
// `let _ = collection.pop();`. Unlike a bare `collection.pop()` in value position,
// this is exactly what `pop_if` does, so it is worth linting on its own.
//
// An annotated `let _: Option<i32> = collection.pop();` is left alone: the whole
// statement is replaced by the suggestion, and the annotation may be what pins down
// the element type of the collection.

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.

please write comments a bit more human.
no weird semicolons, one sentence per line, short sentnces.

this goes for all the code comments you added.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

let me know if this is succint enough, I can rework if not.

Comment thread clippy_lints/src/manual_pop_if.rs Outdated
// Returns the pop call of a statement, along with the position the replaced code
// starts at (which is the start of the statement itself, as e.g. the `let _ =` of a
// discarded pop is replaced as well).
let as_pop_stmt = |stmt: &Stmt<'tcx>| -> Option<(&'tcx Expr<'tcx>, Span, BytePos)> {

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.

only used once, please inline where you got the code from.
you can extract code, but this does not seem intentional.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

yeah, that was leftover from an earlier iteration, not intentional.
inlined it back into the single statement check.

Iurig added 2 commits August 25, 2026 21:40
Inline `as_pop_stmt` into its single call site.
Reword the added comments into short sentences, one per line.
Let sentences wrap across lines instead of forcing one per line, in line
with the surrounding comment style.

@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: lgtm

View changes since this review

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.

3 participants