Skip to content

manual_filter: don't eat comments in the and_then suggestion#17377

Open
costajohnt wants to merge 1 commit into
rust-lang:masterfrom
costajohnt:fix/17376-manual-filter-eats-comments
Open

manual_filter: don't eat comments in the and_then suggestion#17377
costajohnt wants to merge 1 commit into
rust-lang:masterfrom
costajohnt:fix/17376-manual-filter-eats-comments

Conversation

@costajohnt

@costajohnt costajohnt commented Jul 7, 2026

Copy link
Copy Markdown

Fixes #17376.

clippy::manual_filter rewrites opt.and_then(|x| { /* comment */ if cond { Some(x) } else { None } }) to opt.filter(|&x| cond), dropping any comment inside the closure. Under --fix this silently deletes the comment.

Mark the suggestion MaybeIncorrect when the replaced span contains a comment, so clippy --fix no longer applies it automatically. This mirrors the existing span_contains_comment handling in manual_ok_err, manual_unwrap_or, and manual_flatten.

The commented case lives in a new manual_filter_unfixable.rs (//@no-rustfix), since the UI-test harness applies every suggestion to .fixed regardless of applicability.

Happy to instead preserve the comment in the rewrite (the issue's "desired output", the way some_filter keeps the block) if you'd prefer that over the applicability downgrade.

changelog: [manual_filter]: don't silently drop comments in the and_then suggestion under --fix

The `opt.and_then(|x| { /* comment */ if .. { Some(x) } else { None } })`
to `filter` rewrite drops any comment inside the closure. Mark the
suggestion `MaybeIncorrect` when the replaced span contains a comment, so
`clippy --fix` no longer applies it silently. This matches the existing
`span_contains_comment` handling in manual_ok_err / manual_unwrap_or /
manual_flatten.
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jul 7, 2026
@rustbot

rustbot commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome! The Rust Project is excited to review your changes, and you should hear from @llogiq (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
Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: 8 candidates
  • 8 candidates expanded to 8 candidates
  • Random selection from Jarcho, llogiq, samueltardieu

@pacak

pacak commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

If refusing to automatically apply the fix is more consistent with existing behavior - that would work as well. The desired part is not eating comments.

@costajohnt

Copy link
Copy Markdown
Author

That's what this PR does. When the replaced span contains a comment the suggestion drops to MaybeIncorrect, so cargo clippy --fix won't apply it and the comment stays put. The suggestion still shows up in the warning for anyone applying it by hand. It's the same pattern manual_unwrap_or and manual_ok_err already use for this situation.

Comment on lines +1 to +15
//@no-rustfix: the suggestion drops the closure's comment, so it is not machine-applicable

#![warn(clippy::manual_filter)]

fn issue17376(opt: Option<u32>) {
// Rewriting to `filter` would drop the comment below, so the suggestion must not be
// machine-applicable here. Otherwise `clippy --fix` would silently eat the comment (#17376).
opt.and_then(|x| {
//~^ manual_filter
// keep this explanation
if x < 10 { Some(x) } else { None }
});
}

fn main() {}

@Gri-ffin Gri-ffin Jul 9, 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.

Wouldn't //@no-rustfix here defeat the purpose of what you are trying to achieve? If you disable rustfix, the test would still pass even if the suggestion accidentally remains MachineApplicable

View changes since the review

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.

Good catch, but rustfix wouldn't actually guard that here. clippy's UI tests run with RustfixMode::Everything, which applies every suggestion regardless of applicability, so MaybeIncorrect gets applied too. The .fixed would come out identical either way (comment dropped), so it can't tell MachineApplicable from MaybeIncorrect, and turning rustfix on would just bless a .fixed showing the comment eaten.

So //@no-rustfix here, same as manual_unwrap_or_default_unfixable.rs. The comment-free path is still rustfix-tested over in manual_filter.rs. You're right that a regression back to MachineApplicable wouldn't be caught, but I don't think the harness exposes applicability anywhere to assert on. Open to it if you know a way.

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.

clippy --fix can eat comments

5 participants