rust-clippy icon indicating copy to clipboard operation
rust-clippy copied to clipboard

Add iterator reduction coverage to never_loop

Open cuongleqq opened this issue 3 months ago • 1 comments

Fixes rust-lang/rust-clippy#16061.

Extend never_loop to also lint iterator reduction methods (e.g. for_each, try_for_each, fold, try_fold, reduce, all, any) when the closure’s body diverges (return type !). Add a UI test never_loop_iterator_reduction to cover these cases.

Testing:

  • TESTNAME=never_loop_iterator_reduction cargo uitest

changelog: [never_loop]: lint diverging iterator reduction closures like for_each and fold

cuongleqq avatar Dec 12 '25 03:12 cuongleqq

r? @Jarcho

rustbot has assigned @Jarcho. They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

rustbot avatar Dec 12 '25 03:12 rustbot

Reminder, once the PR becomes ready for a review, use @rustbot ready.

rustbot avatar Dec 13 '25 04:12 rustbot

I pushed an update to address all 4 comments

  • Combined the method check for both unused_enumerate_index and never_loop
  • Use a more direct check for Iterator trait
  • Use HasPlaceholders for the applicability
  • Use snippet_with_context instead of make_iterator_snippet

@rustbot ready

cuongleqq avatar Dec 13 '25 14:12 cuongleqq

Addressed the requested changes:

  • Switched to a single match for the MethodCall handling

@rustbot ready

cuongleqq avatar Dec 14 '25 03:12 cuongleqq

Thanks for the quick review!

I pushed an update to address the comments:

  • is_iterator_method() stays behind the cheap name/arg checks
  • moved the shared iterator + closure checks into check_expr
  • pass the closure into never_loop / unused_enumerate_index instead of re-parsing inside

@rustbot ready

@Jarcho: I’m repeating if let ExprKind::Closure(closure) = arg.kind && is_iterator_method() in all match arms to keep the expensive check last. Do you want me to make a small helper for this, or is it fine as-is?

cuongleqq avatar Dec 15 '25 08:12 cuongleqq

I’m repeating if let ExprKind::Closure(closure) = arg.kind && is_iterator_method() in all match arms to keep the expensive check last. Do you want me to make a small helper for this, or is it fine as-is?

A helper function would end up harder to read. It's two steps that are, without external context, unrelated to each other. Having to jump to another spot to just to read what it does is also a pain.

Jarcho avatar Dec 15 '25 12:12 Jarcho