unnecessary_fold: lint folding over an Option's iterator (#17445)
*[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust-clippy/pull/17445)* Fixes rust-lang/rust-clippy#1658 Folding over an `Option`'s iterator visits zero or one items, which is `map_or` in disguise: ```rust opt.iter().fold(init, |acc, x| f(acc, x)) // is opt.as_ref().map_or(init, |x| f(init, x)) ``` (`as_mut()` for `iter_mut()`, plain `map_or` for `into_iter()`, which consumes the `Option`.) This extends `unnecessary_fold` rather than adding a new lint, and only runs when none of the existing `any`/`all`/`sum`/`product` cases fired, so existing behavior and test expectations are unchanged. Suggestion details: - accumulator uses in the closure body are replaced with the `init` expression via a multipart suggestion - only lints when `init` is a literal or a binding of a `Copy` type, so every suggestion is machine-applicable - closure parameters are not accepted as `init`: with nested folds the enclosing closure may itself be rewritten by this lint, which would leave the copied name unresolved (covered in `unnecessary_fold_nested.rs`) - bails out when any rewritten span comes from a different syntax context changelog: [`unnecessary_fold`]: lint `fold` over an `Option`'s iterator and suggest `map_or`
L
llogiq committed
cde6ea0eb4b31769ed5806ed31efec4795913085
Committed by GitHub <noreply@github.com>
on 8/22/2026, 10:28:47 AM