@@ -10,19 +10,19 @@ use rustc_hir::{Block, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind, Path,
1010use rustc_lint:: LateContext ;
1111
1212pub ( super ) fn check < ' tcx > ( cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > , loop_block : & ' tcx Block < ' _ > ) {
13- let ( init, let_info) = match ( loop_block. stmts , loop_block. expr ) {
13+ let ( init, let_info, els ) = match ( loop_block. stmts , loop_block. expr ) {
1414 ( [ stmt, ..] , _) => match stmt. kind {
1515 StmtKind :: Let ( LetStmt {
1616 init : Some ( e) ,
17- els : None ,
17+ els,
1818 pat,
1919 ty,
2020 ..
21- } ) => ( * e, Some ( ( * pat, * ty) ) ) ,
22- StmtKind :: Semi ( e) | StmtKind :: Expr ( e) => ( e, None ) ,
21+ } ) => ( * e, Some ( ( * pat, * ty) ) , * els ) ,
22+ StmtKind :: Semi ( e) | StmtKind :: Expr ( e) => ( e, None , None ) ,
2323 _ => return ,
2424 } ,
25- ( [ ] , Some ( e) ) => ( e, None ) ,
25+ ( [ ] , Some ( e) ) => ( e, None , None ) ,
2626 _ => return ,
2727 } ;
2828 let has_trailing_exprs = loop_block. stmts . len ( ) + usize:: from ( loop_block. expr . is_some ( ) ) > 1 ;
@@ -38,14 +38,26 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_blo
3838 if_let. let_expr ,
3939 has_trailing_exprs,
4040 let_info,
41- if_let. if_then ,
41+ Some ( if_let. if_then ) ,
4242 ) ;
43+ } else if els. and_then ( |x| x. expr ) . is_some_and ( is_simple_break_expr)
44+ && let Some ( ( pat, _) ) = let_info
45+ {
46+ could_be_while_let ( cx, expr, pat, init, has_trailing_exprs, let_info, None ) ;
4347 } else if let ExprKind :: Match ( scrutinee, [ arm1, arm2] , MatchSource :: Normal ) = init. kind
4448 && arm1. guard . is_none ( )
4549 && arm2. guard . is_none ( )
4650 && is_simple_break_expr ( arm2. body )
4751 {
48- could_be_while_let ( cx, expr, arm1. pat , scrutinee, has_trailing_exprs, let_info, arm1. body ) ;
52+ could_be_while_let (
53+ cx,
54+ expr,
55+ arm1. pat ,
56+ scrutinee,
57+ has_trailing_exprs,
58+ let_info,
59+ Some ( arm1. body ) ,
60+ ) ;
4961 }
5062}
5163
@@ -70,7 +82,7 @@ fn could_be_while_let<'tcx>(
7082 let_expr : & ' tcx Expr < ' _ > ,
7183 has_trailing_exprs : bool ,
7284 let_info : Option < ( & Pat < ' _ > , Option < & Ty < ' _ > > ) > ,
73- inner_expr : & Expr < ' _ > ,
85+ inner_expr : Option < & Expr < ' _ > > ,
7486) {
7587 if has_trailing_exprs
7688 && ( needs_ordered_drop ( cx, cx. typeck_results ( ) . expr_ty ( let_expr) )
@@ -85,7 +97,7 @@ fn could_be_while_let<'tcx>(
8597 // 1) it was ugly with big bodies;
8698 // 2) it was not indented properly;
8799 // 3) it wasn’t very smart (see #675).
88- let inner_content = if let Some ( ( pat, ty) ) = let_info
100+ let inner_content = if let Some ( ( ( pat, ty) , inner_expr ) ) = let_info. zip ( inner_expr )
89101 // Prevent trivial reassignments such as `let x = x;` or `let _ = …;`, but
90102 // keep them if the type has been explicitly specified.
91103 && ( !is_trivial_assignment ( pat, peel_blocks ( inner_expr) ) || ty. is_some ( ) )
0 commit comments