@@ -12,14 +12,13 @@ mod needless_collect;
12
12
mod never_loop;
13
13
mod same_item_push;
14
14
mod utils;
15
+ mod while_let_loop;
15
16
mod while_let_on_iterator;
16
17
17
18
use crate :: utils:: sugg:: Sugg ;
18
- use crate :: utils:: { higher, snippet_with_applicability, span_lint_and_sugg, sugg} ;
19
- use rustc_errors:: Applicability ;
20
- use rustc_hir:: { Block , Expr , ExprKind , LoopSource , MatchSource , Pat , StmtKind } ;
21
- use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
22
- use rustc_middle:: lint:: in_external_macro;
19
+ use crate :: utils:: { higher, sugg} ;
20
+ use rustc_hir:: { Expr , ExprKind , LoopSource , Pat } ;
21
+ use rustc_lint:: { LateContext , LateLintPass } ;
23
22
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
24
23
use rustc_span:: source_map:: Span ;
25
24
use utils:: { get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor , InitializeVisitor } ;
@@ -564,49 +563,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
564
563
if let ExprKind :: Loop ( ref block, _, LoopSource :: Loop , _) = expr. kind {
565
564
// also check for empty `loop {}` statements, skipping those in #[panic_handler]
566
565
empty_loop:: check_empty_loop ( cx, expr, block) ;
567
-
568
- // extract the expression from the first statement (if any) in a block
569
- let inner_stmt_expr = extract_expr_from_first_stmt ( block) ;
570
- // or extract the first expression (if any) from the block
571
- if let Some ( inner) = inner_stmt_expr. or_else ( || extract_first_expr ( block) ) {
572
- if let ExprKind :: Match ( ref matchexpr, ref arms, ref source) = inner. kind {
573
- // ensure "if let" compatible match structure
574
- match * source {
575
- MatchSource :: Normal | MatchSource :: IfLetDesugar { .. } => {
576
- if arms. len ( ) == 2
577
- && arms[ 0 ] . guard . is_none ( )
578
- && arms[ 1 ] . guard . is_none ( )
579
- && is_simple_break_expr ( & arms[ 1 ] . body )
580
- {
581
- if in_external_macro ( cx. sess ( ) , expr. span ) {
582
- return ;
583
- }
584
-
585
- // NOTE: we used to build a body here instead of using
586
- // ellipsis, this was removed because:
587
- // 1) it was ugly with big bodies;
588
- // 2) it was not indented properly;
589
- // 3) it wasn’t very smart (see #675).
590
- let mut applicability = Applicability :: HasPlaceholders ;
591
- span_lint_and_sugg (
592
- cx,
593
- WHILE_LET_LOOP ,
594
- expr. span ,
595
- "this loop could be written as a `while let` loop" ,
596
- "try" ,
597
- format ! (
598
- "while let {} = {} {{ .. }}" ,
599
- snippet_with_applicability( cx, arms[ 0 ] . pat. span, ".." , & mut applicability) ,
600
- snippet_with_applicability( cx, matchexpr. span, ".." , & mut applicability) ,
601
- ) ,
602
- applicability,
603
- ) ;
604
- }
605
- } ,
606
- _ => ( ) ,
607
- }
608
- }
609
- }
566
+ while_let_loop:: check_while_let_loop ( cx, expr, block) ;
610
567
}
611
568
612
569
while_let_on_iterator:: check_while_let_on_iterator ( cx, expr) ;
@@ -709,39 +666,3 @@ impl std::ops::Sub<&MinifyingSugg<'static>> for MinifyingSugg<'static> {
709
666
}
710
667
}
711
668
}
712
-
713
- /// If a block begins with a statement (possibly a `let` binding) and has an
714
- /// expression, return it.
715
- fn extract_expr_from_first_stmt < ' tcx > ( block : & Block < ' tcx > ) -> Option < & ' tcx Expr < ' tcx > > {
716
- if block. stmts . is_empty ( ) {
717
- return None ;
718
- }
719
- if let StmtKind :: Local ( ref local) = block. stmts [ 0 ] . kind {
720
- local. init //.map(|expr| expr)
721
- } else {
722
- None
723
- }
724
- }
725
-
726
- /// If a block begins with an expression (with or without semicolon), return it.
727
- fn extract_first_expr < ' tcx > ( block : & Block < ' tcx > ) -> Option < & ' tcx Expr < ' tcx > > {
728
- match block. expr {
729
- Some ( ref expr) if block. stmts . is_empty ( ) => Some ( expr) ,
730
- None if !block. stmts . is_empty ( ) => match block. stmts [ 0 ] . kind {
731
- StmtKind :: Expr ( ref expr) | StmtKind :: Semi ( ref expr) => Some ( expr) ,
732
- StmtKind :: Local ( ..) | StmtKind :: Item ( ..) => None ,
733
- } ,
734
- _ => None ,
735
- }
736
- }
737
-
738
- /// Returns `true` if expr contains a single break expr without destination label
739
- /// and
740
- /// passed expression. The expression may be within a block.
741
- fn is_simple_break_expr ( expr : & Expr < ' _ > ) -> bool {
742
- match expr. kind {
743
- ExprKind :: Break ( dest, ref passed_expr) if dest. label . is_none ( ) && passed_expr. is_none ( ) => true ,
744
- ExprKind :: Block ( ref b, _) => extract_first_expr ( b) . map_or ( false , |subexpr| is_simple_break_expr ( subexpr) ) ,
745
- _ => false ,
746
- }
747
- }
0 commit comments