@@ -533,174 +533,184 @@ impl LoweringContext<'_> {
533
533
// Desugar `ExprForLoop`
534
534
// from: `[opt_ident]: for <pat> in <head> <body>`
535
535
ExprKind :: ForLoop ( ref pat, ref head, ref body, opt_label) => {
536
- // to:
537
- //
538
- // {
539
- // let result = match ::std::iter::IntoIterator::into_iter(<head>) {
540
- // mut iter => {
541
- // [opt_ident]: loop {
542
- // let mut __next;
543
- // match ::std::iter::Iterator::next(&mut iter) {
544
- // ::std::option::Option::Some(val) => __next = val,
545
- // ::std::option::Option::None => break
546
- // };
547
- // let <pat> = __next;
548
- // StmtKind::Expr(<body>);
549
- // }
550
- // }
551
- // };
552
- // result
553
- // }
554
-
555
- // expand <head>
556
- let mut head = self . lower_expr ( head) ;
557
- let head_sp = head. span ;
558
- let desugared_span = self . mark_span_with_reason (
559
- DesugaringKind :: ForLoop ,
560
- head_sp,
561
- None ,
562
- ) ;
563
- head. span = desugared_span;
564
-
565
- let iter = Ident :: with_empty_ctxt ( sym:: iter) ;
566
-
567
- let next_ident = Ident :: with_empty_ctxt ( sym:: __next) ;
568
- let ( next_pat, next_pat_hid) = self . pat_ident_binding_mode (
569
- desugared_span,
570
- next_ident,
571
- hir:: BindingAnnotation :: Mutable ,
572
- ) ;
573
-
574
- // `::std::option::Option::Some(val) => __next = val`
575
- let pat_arm = {
576
- let val_ident = Ident :: with_empty_ctxt ( sym:: val) ;
577
- let ( val_pat, val_pat_hid) = self . pat_ident ( pat. span , val_ident) ;
578
- let val_expr = P ( self . expr_ident ( pat. span , val_ident, val_pat_hid) ) ;
579
- let next_expr = P ( self . expr_ident ( pat. span , next_ident, next_pat_hid) ) ;
580
- let assign = P ( self . expr (
581
- pat. span ,
582
- hir:: ExprKind :: Assign ( next_expr, val_expr) ,
583
- ThinVec :: new ( ) ,
584
- ) ) ;
585
- let some_pat = self . pat_some ( pat. span , val_pat) ;
586
- self . arm ( hir_vec ! [ some_pat] , assign)
587
- } ;
536
+ return self . lower_expr_for ( e, pat, head, body, opt_label) ;
537
+ }
538
+ ExprKind :: Try ( ref sub_expr) => self . lower_expr_try ( e. span , sub_expr) ,
539
+ ExprKind :: Mac ( _) => panic ! ( "Shouldn't exist here" ) ,
540
+ } ;
588
541
589
- // `::std::option::Option::None => break`
590
- let break_arm = {
591
- let break_expr =
592
- self . with_loop_scope ( e . id , |this| this . expr_break ( e . span , ThinVec :: new ( ) ) ) ;
593
- let pat = self . pat_none ( e . span ) ;
594
- self . arm ( hir_vec ! [ pat ] , break_expr )
595
- } ;
542
+ hir :: Expr {
543
+ hir_id : self . lower_node_id ( e . id ) ,
544
+ node : kind ,
545
+ span : e . span ,
546
+ attrs : e . attrs . clone ( ) ,
547
+ }
548
+ }
596
549
597
- // `mut iter`
598
- let ( iter_pat, iter_pat_nid) = self . pat_ident_binding_mode (
599
- desugared_span,
600
- iter,
601
- hir:: BindingAnnotation :: Mutable
602
- ) ;
550
+ /// Desugar `ExprForLoop` from: `[opt_ident]: for <pat> in <head> <body>` into:
551
+ /// ```rust
552
+ /// {
553
+ /// let result = match ::std::iter::IntoIterator::into_iter(<head>) {
554
+ /// mut iter => {
555
+ /// [opt_ident]: loop {
556
+ /// let mut __next;
557
+ /// match ::std::iter::Iterator::next(&mut iter) {
558
+ /// ::std::option::Option::Some(val) => __next = val,
559
+ /// ::std::option::Option::None => break
560
+ /// };
561
+ /// let <pat> = __next;
562
+ /// StmtKind::Expr(<body>);
563
+ /// }
564
+ /// }
565
+ /// };
566
+ /// result
567
+ /// }
568
+ /// ```
569
+ fn lower_expr_for (
570
+ & mut self ,
571
+ e : & Expr ,
572
+ pat : & Pat ,
573
+ head : & Expr ,
574
+ body : & Block ,
575
+ opt_label : Option < Label > ,
576
+ ) -> hir:: Expr {
577
+ // expand <head>
578
+ let mut head = self . lower_expr ( head) ;
579
+ let head_sp = head. span ;
580
+ let desugared_span = self . mark_span_with_reason (
581
+ DesugaringKind :: ForLoop ,
582
+ head_sp,
583
+ None ,
584
+ ) ;
585
+ head. span = desugared_span;
603
586
604
- // `match ::std::iter::Iterator::next(&mut iter) { ... }`
605
- let match_expr = {
606
- let iter = P ( self . expr_ident ( head_sp, iter, iter_pat_nid) ) ;
607
- let ref_mut_iter = self . expr_mut_addr_of ( head_sp, iter) ;
608
- let next_path = & [ sym:: iter, sym:: Iterator , sym:: next] ;
609
- let next_expr = P ( self . expr_call_std_path (
610
- head_sp,
611
- next_path,
612
- hir_vec ! [ ref_mut_iter] ,
613
- ) ) ;
614
- let arms = hir_vec ! [ pat_arm, break_arm] ;
615
-
616
- self . expr_match ( head_sp, next_expr, arms, hir:: MatchSource :: ForLoopDesugar )
617
- } ;
618
- let match_stmt = self . stmt_expr ( head_sp, match_expr) ;
587
+ let iter = Ident :: with_empty_ctxt ( sym:: iter) ;
619
588
620
- let next_expr = P ( self . expr_ident ( head_sp, next_ident, next_pat_hid) ) ;
589
+ let next_ident = Ident :: with_empty_ctxt ( sym:: __next) ;
590
+ let ( next_pat, next_pat_hid) = self . pat_ident_binding_mode (
591
+ desugared_span,
592
+ next_ident,
593
+ hir:: BindingAnnotation :: Mutable ,
594
+ ) ;
621
595
622
- // `let mut __next`
623
- let next_let = self . stmt_let_pat (
624
- ThinVec :: new ( ) ,
625
- desugared_span,
626
- None ,
627
- next_pat,
628
- hir:: LocalSource :: ForLoopDesugar ,
629
- ) ;
596
+ // `::std::option::Option::Some(val) => __next = val`
597
+ let pat_arm = {
598
+ let val_ident = Ident :: with_empty_ctxt ( sym:: val) ;
599
+ let ( val_pat, val_pat_hid) = self . pat_ident ( pat. span , val_ident) ;
600
+ let val_expr = P ( self . expr_ident ( pat. span , val_ident, val_pat_hid) ) ;
601
+ let next_expr = P ( self . expr_ident ( pat. span , next_ident, next_pat_hid) ) ;
602
+ let assign = P ( self . expr (
603
+ pat. span ,
604
+ hir:: ExprKind :: Assign ( next_expr, val_expr) ,
605
+ ThinVec :: new ( ) ,
606
+ ) ) ;
607
+ let some_pat = self . pat_some ( pat. span , val_pat) ;
608
+ self . arm ( hir_vec ! [ some_pat] , assign)
609
+ } ;
630
610
631
- // `let <pat> = __next`
632
- let pat = self . lower_pat ( pat) ;
633
- let pat_let = self . stmt_let_pat (
634
- ThinVec :: new ( ) ,
635
- head_sp,
636
- Some ( next_expr) ,
637
- pat,
638
- hir:: LocalSource :: ForLoopDesugar ,
639
- ) ;
611
+ // `::std::option::Option::None => break`
612
+ let break_arm = {
613
+ let break_expr =
614
+ self . with_loop_scope ( e. id , |this| this. expr_break ( e. span , ThinVec :: new ( ) ) ) ;
615
+ let pat = self . pat_none ( e. span ) ;
616
+ self . arm ( hir_vec ! [ pat] , break_expr)
617
+ } ;
640
618
641
- let body_block = self . with_loop_scope ( e. id , |this| this. lower_block ( body, false ) ) ;
642
- let body_expr = self . expr_block ( body_block, ThinVec :: new ( ) ) ;
643
- let body_stmt = self . stmt_expr ( body. span , body_expr) ;
619
+ // `mut iter`
620
+ let ( iter_pat, iter_pat_nid) = self . pat_ident_binding_mode (
621
+ desugared_span,
622
+ iter,
623
+ hir:: BindingAnnotation :: Mutable
624
+ ) ;
644
625
645
- let loop_block = P ( self . block_all (
646
- e. span ,
647
- hir_vec ! [ next_let, match_stmt, pat_let, body_stmt] ,
648
- None ,
649
- ) ) ;
626
+ // `match ::std::iter::Iterator::next(&mut iter) { ... }`
627
+ let match_expr = {
628
+ let iter = P ( self . expr_ident ( head_sp, iter, iter_pat_nid) ) ;
629
+ let ref_mut_iter = self . expr_mut_addr_of ( head_sp, iter) ;
630
+ let next_path = & [ sym:: iter, sym:: Iterator , sym:: next] ;
631
+ let next_expr = P ( self . expr_call_std_path (
632
+ head_sp,
633
+ next_path,
634
+ hir_vec ! [ ref_mut_iter] ,
635
+ ) ) ;
636
+ let arms = hir_vec ! [ pat_arm, break_arm] ;
650
637
651
- // `[opt_ident]: loop { ... }`
652
- let loop_expr = hir:: ExprKind :: Loop (
653
- loop_block,
654
- self . lower_label ( opt_label) ,
655
- hir:: LoopSource :: ForLoop ,
656
- ) ;
657
- let loop_expr = P ( hir:: Expr {
658
- hir_id : self . lower_node_id ( e. id ) ,
659
- node : loop_expr,
660
- span : e. span ,
661
- attrs : ThinVec :: new ( ) ,
662
- } ) ;
663
-
664
- // `mut iter => { ... }`
665
- let iter_arm = self . arm ( hir_vec ! [ iter_pat] , loop_expr) ;
666
-
667
- // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
668
- let into_iter_expr = {
669
- let into_iter_path =
670
- & [ sym:: iter, sym:: IntoIterator , sym:: into_iter] ;
671
- P ( self . expr_call_std_path (
672
- head_sp,
673
- into_iter_path,
674
- hir_vec ! [ head] ,
675
- ) )
676
- } ;
638
+ self . expr_match ( head_sp, next_expr, arms, hir:: MatchSource :: ForLoopDesugar )
639
+ } ;
640
+ let match_stmt = self . stmt_expr ( head_sp, match_expr) ;
677
641
678
- let match_expr = P ( self . expr_match (
679
- head_sp,
680
- into_iter_expr,
681
- hir_vec ! [ iter_arm] ,
682
- hir:: MatchSource :: ForLoopDesugar ,
683
- ) ) ;
642
+ let next_expr = P ( self . expr_ident ( head_sp, next_ident, next_pat_hid) ) ;
684
643
685
- // This is effectively `{ let _result = ...; _result }`.
686
- // The construct was introduced in #21984 and is necessary to make sure that
687
- // temporaries in the `head` expression are dropped and do not leak to the
688
- // surrounding scope of the `match` since the `match` is not a terminating scope.
689
- //
690
- // Also, add the attributes to the outer returned expr node.
691
- return self . expr_drop_temps ( head_sp , match_expr , e . attrs . clone ( ) )
692
- }
644
+ // ` let mut __next`
645
+ let next_let = self . stmt_let_pat (
646
+ ThinVec :: new ( ) ,
647
+ desugared_span ,
648
+ None ,
649
+ next_pat ,
650
+ hir :: LocalSource :: ForLoopDesugar ,
651
+ ) ;
693
652
694
- ExprKind :: Try ( ref sub_expr) => self . lower_expr_try ( e. span , sub_expr) ,
695
- ExprKind :: Mac ( _) => panic ! ( "Shouldn't exist here" ) ,
696
- } ;
653
+ // `let <pat> = __next`
654
+ let pat = self . lower_pat ( pat) ;
655
+ let pat_let = self . stmt_let_pat (
656
+ ThinVec :: new ( ) ,
657
+ head_sp,
658
+ Some ( next_expr) ,
659
+ pat,
660
+ hir:: LocalSource :: ForLoopDesugar ,
661
+ ) ;
697
662
698
- hir:: Expr {
663
+ let body_block = self . with_loop_scope ( e. id , |this| this. lower_block ( body, false ) ) ;
664
+ let body_expr = self . expr_block ( body_block, ThinVec :: new ( ) ) ;
665
+ let body_stmt = self . stmt_expr ( body. span , body_expr) ;
666
+
667
+ let loop_block = P ( self . block_all (
668
+ e. span ,
669
+ hir_vec ! [ next_let, match_stmt, pat_let, body_stmt] ,
670
+ None ,
671
+ ) ) ;
672
+
673
+ // `[opt_ident]: loop { ... }`
674
+ let loop_expr = hir:: ExprKind :: Loop (
675
+ loop_block,
676
+ self . lower_label ( opt_label) ,
677
+ hir:: LoopSource :: ForLoop ,
678
+ ) ;
679
+ let loop_expr = P ( hir:: Expr {
699
680
hir_id : self . lower_node_id ( e. id ) ,
700
- node : kind ,
681
+ node : loop_expr ,
701
682
span : e. span ,
702
- attrs : e. attrs . clone ( ) ,
703
- }
683
+ attrs : ThinVec :: new ( ) ,
684
+ } ) ;
685
+
686
+ // `mut iter => { ... }`
687
+ let iter_arm = self . arm ( hir_vec ! [ iter_pat] , loop_expr) ;
688
+
689
+ // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
690
+ let into_iter_expr = {
691
+ let into_iter_path =
692
+ & [ sym:: iter, sym:: IntoIterator , sym:: into_iter] ;
693
+ P ( self . expr_call_std_path (
694
+ head_sp,
695
+ into_iter_path,
696
+ hir_vec ! [ head] ,
697
+ ) )
698
+ } ;
699
+
700
+ let match_expr = P ( self . expr_match (
701
+ head_sp,
702
+ into_iter_expr,
703
+ hir_vec ! [ iter_arm] ,
704
+ hir:: MatchSource :: ForLoopDesugar ,
705
+ ) ) ;
706
+
707
+ // This is effectively `{ let _result = ...; _result }`.
708
+ // The construct was introduced in #21984 and is necessary to make sure that
709
+ // temporaries in the `head` expression are dropped and do not leak to the
710
+ // surrounding scope of the `match` since the `match` is not a terminating scope.
711
+ //
712
+ // Also, add the attributes to the outer returned expr node.
713
+ self . expr_drop_temps ( head_sp, match_expr, e. attrs . clone ( ) )
704
714
}
705
715
706
716
/// Desugar `ExprKind::Try` from: `<expr>?` into:
0 commit comments