From 205aa88921ce63898f7fd3db6e9070c70987be2e Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sat, 31 Jul 2021 09:32:54 -0400 Subject: [PATCH] Fix `while_let_on_iterator` When the iterator is one field within a local correctly check for usages of the field --- clippy_lints/src/loops/while_let_on_iterator.rs | 2 +- tests/ui/while_let_on_iterator.fixed | 9 +++++++++ tests/ui/while_let_on_iterator.rs | 9 +++++++++ tests/ui/while_let_on_iterator.stderr | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs index 6655e2e445c..ef822e0cbe5 100644 --- a/clippy_lints/src/loops/while_let_on_iterator.rs +++ b/clippy_lints/src/loops/while_let_on_iterator.rs @@ -146,7 +146,7 @@ fn is_expr_same_child_or_parent_field(cx: &LateContext<'_>, expr: &Expr<'_>, fie match expr.kind { ExprKind::Field(base, name) => { if let Some((head_field, tail_fields)) = fields.split_first() { - if name.name == *head_field && is_expr_same_field(cx, base, fields, path_res) { + if name.name == *head_field && is_expr_same_field(cx, base, tail_fields, path_res) { return true; } // Check if the expression is a parent field diff --git a/tests/ui/while_let_on_iterator.fixed b/tests/ui/while_let_on_iterator.fixed index 52c70ced2bd..cdcdd808c94 100644 --- a/tests/ui/while_let_on_iterator.fixed +++ b/tests/ui/while_let_on_iterator.fixed @@ -357,6 +357,15 @@ fn issue7510() { println!("{}", it.0.next().unwrap()); } +fn exact_match_with_single_field() { + struct S(T); + let mut s = S(0..10); + // Don't lint. `s.0` is used inside the loop. + while let Some(_) = s.0.next() { + let _ = &mut s.0; + } +} + fn main() { let mut it = 0..20; for _ in it { diff --git a/tests/ui/while_let_on_iterator.rs b/tests/ui/while_let_on_iterator.rs index 8434acaf582..72f34257d1f 100644 --- a/tests/ui/while_let_on_iterator.rs +++ b/tests/ui/while_let_on_iterator.rs @@ -357,6 +357,15 @@ fn issue7510() { println!("{}", it.0.next().unwrap()); } +fn exact_match_with_single_field() { + struct S(T); + let mut s = S(0..10); + // Don't lint. `s.0` is used inside the loop. + while let Some(_) = s.0.next() { + let _ = &mut s.0; + } +} + fn main() { let mut it = 0..20; while let Some(..) = it.next() { diff --git a/tests/ui/while_let_on_iterator.stderr b/tests/ui/while_let_on_iterator.stderr index 50bcc26cec2..ff9b08996da 100644 --- a/tests/ui/while_let_on_iterator.stderr +++ b/tests/ui/while_let_on_iterator.stderr @@ -123,7 +123,7 @@ LL | while let Some(x) = it.0.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in &mut *it.0` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:362:5 + --> $DIR/while_let_on_iterator.rs:371:5 | LL | while let Some(..) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it`