From a8370d4460ffaa6e1ded585db0bbdd30dc287c62 Mon Sep 17 00:00:00 2001 From: andylizi Date: Wed, 15 Jun 2022 17:54:43 +0800 Subject: [PATCH] Fix false positive for `never_loop` struct expression fields --- clippy_lints/src/loops/never_loop.rs | 12 +++++++++--- tests/ui/never_loop.rs | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index c025f5972d5..5d9f1887550 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -117,13 +117,20 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult { | ExprKind::Type(e, _) | ExprKind::Field(e, _) | ExprKind::AddrOf(_, _, e) - | ExprKind::Struct(_, _, Some(e)) | ExprKind::Repeat(e, _) | ExprKind::DropTemps(e) => never_loop_expr(e, main_loop_id), ExprKind::Let(let_expr) => never_loop_expr(let_expr.init, main_loop_id), ExprKind::Array(es) | ExprKind::MethodCall(_, es, _) | ExprKind::Tup(es) => { never_loop_expr_all(&mut es.iter(), main_loop_id) }, + ExprKind::Struct(_, fields, base) => { + let fields = never_loop_expr_all(&mut fields.iter().map(|f| f.expr), main_loop_id); + if let Some(base) = base { + combine_both(fields, never_loop_expr(base, main_loop_id)) + } else { + fields + } + }, ExprKind::Call(e, es) => never_loop_expr_all(&mut once(e).chain(es.iter()), main_loop_id), ExprKind::Binary(_, e1, e2) | ExprKind::Assign(e1, e2, _) @@ -180,8 +187,7 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult { | InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise, }) .fold(NeverLoopResult::Otherwise, combine_both), - ExprKind::Struct(_, _, None) - | ExprKind::Yield(_, _) + ExprKind::Yield(_, _) | ExprKind::Closure(_, _, _, _, _) | ExprKind::Path(_) | ExprKind::ConstBlock(_) diff --git a/tests/ui/never_loop.rs b/tests/ui/never_loop.rs index 2770eb2b2ab..0a21589dd0d 100644 --- a/tests/ui/never_loop.rs +++ b/tests/ui/never_loop.rs @@ -186,6 +186,23 @@ pub fn test16() { } } +// Issue #9001: `continue` in struct expression fields +pub fn test17() { + struct Foo { + f: (), + } + + let mut n = 0; + let _ = loop { + break Foo { + f: if n < 5 { + n += 1; + continue; + }, + }; + }; +} + fn main() { test1(); test2();