@@ -550,20 +550,6 @@ impl ExprCollector<'_> {
550
550
None => self . alloc_expr ( Expr :: Missing , syntax_ptr) ,
551
551
}
552
552
}
553
- ast:: Expr :: MacroStmts ( e) => {
554
- let statements: Box < [ _ ] > =
555
- e. statements ( ) . filter_map ( |s| self . collect_stmt ( s) ) . collect ( ) ;
556
- let tail = e. expr ( ) . map ( |e| self . collect_expr ( e) ) ;
557
-
558
- if e. syntax ( ) . children ( ) . next ( ) . is_none ( ) {
559
- // HACK: make sure that macros that expand to nothing aren't treated as a `()`
560
- // expression when used in block tail position.
561
- cov_mark:: hit!( empty_macro_in_trailing_position_is_removed) ;
562
- return None ;
563
- }
564
-
565
- self . alloc_expr ( Expr :: MacroStmts { tail, statements } , syntax_ptr)
566
- }
567
553
ast:: Expr :: UnderscoreExpr ( _) => self . alloc_expr ( Expr :: Underscore , syntax_ptr) ,
568
554
} )
569
555
}
@@ -640,11 +626,46 @@ impl ExprCollector<'_> {
640
626
}
641
627
}
642
628
643
- fn collect_stmt ( & mut self , s : ast:: Stmt ) -> Option < Statement > {
629
+ fn collect_macro_as_stmt (
630
+ & mut self ,
631
+ statements : & mut Vec < Statement > ,
632
+ mac : ast:: MacroExpr ,
633
+ ) -> Option < ExprId > {
634
+ let mac_call = mac. macro_call ( ) ?;
635
+ let syntax_ptr = AstPtr :: new ( & ast:: Expr :: from ( mac) ) ;
636
+ let macro_ptr = AstPtr :: new ( & mac_call) ;
637
+ let expansion = self . collect_macro_call (
638
+ mac_call,
639
+ macro_ptr,
640
+ false ,
641
+ |this, expansion : Option < ast:: MacroStmts > | match expansion {
642
+ Some ( expansion) => {
643
+ expansion. statements ( ) . for_each ( |stmt| this. collect_stmt ( statements, stmt) ) ;
644
+ expansion. expr ( ) . and_then ( |expr| match expr {
645
+ ast:: Expr :: MacroExpr ( mac) => this. collect_macro_as_stmt ( statements, mac) ,
646
+ expr => Some ( this. collect_expr ( expr) ) ,
647
+ } )
648
+ }
649
+ None => None ,
650
+ } ,
651
+ ) ;
652
+ match expansion {
653
+ Some ( tail) => {
654
+ // Make the macro-call point to its expanded expression so we can query
655
+ // semantics on syntax pointers to the macro
656
+ let src = self . expander . to_source ( syntax_ptr) ;
657
+ self . source_map . expr_map . insert ( src, tail) ;
658
+ Some ( tail)
659
+ }
660
+ None => None ,
661
+ }
662
+ }
663
+
664
+ fn collect_stmt ( & mut self , statements : & mut Vec < Statement > , s : ast:: Stmt ) {
644
665
match s {
645
666
ast:: Stmt :: LetStmt ( stmt) => {
646
667
if self . check_cfg ( & stmt) . is_none ( ) {
647
- return None ;
668
+ return ;
648
669
}
649
670
let pat = self . collect_pat_opt ( stmt. pat ( ) ) ;
650
671
let type_ref =
@@ -654,61 +675,26 @@ impl ExprCollector<'_> {
654
675
. let_else ( )
655
676
. and_then ( |let_else| let_else. block_expr ( ) )
656
677
. map ( |block| self . collect_block ( block) ) ;
657
- Some ( Statement :: Let { pat, type_ref, initializer, else_branch } )
678
+ statements . push ( Statement :: Let { pat, type_ref, initializer, else_branch } ) ;
658
679
}
659
680
ast:: Stmt :: ExprStmt ( stmt) => {
660
681
let expr = stmt. expr ( ) ;
661
- if let Some ( expr) = & expr {
662
- if self . check_cfg ( expr) . is_none ( ) {
663
- return None ;
664
- }
682
+ match & expr {
683
+ Some ( expr) if self . check_cfg ( expr) . is_none ( ) => return ,
684
+ _ => ( ) ,
665
685
}
666
686
let has_semi = stmt. semicolon_token ( ) . is_some ( ) ;
667
687
// Note that macro could be expanded to multiple statements
668
- if let Some ( expr @ ast:: Expr :: MacroExpr ( mac) ) = & expr {
669
- let mac_call = mac. macro_call ( ) ?;
670
- let syntax_ptr = AstPtr :: new ( expr) ;
671
- let macro_ptr = AstPtr :: new ( & mac_call) ;
672
- let stmt = self . collect_macro_call (
673
- mac_call,
674
- macro_ptr,
675
- false ,
676
- |this, expansion : Option < ast:: MacroStmts > | match expansion {
677
- Some ( expansion) => {
678
- let statements = expansion
679
- . statements ( )
680
- . filter_map ( |stmt| this. collect_stmt ( stmt) )
681
- . collect ( ) ;
682
- let tail = expansion. expr ( ) . map ( |expr| this. collect_expr ( expr) ) ;
683
-
684
- let mac_stmts = this. alloc_expr (
685
- Expr :: MacroStmts { tail, statements } ,
686
- AstPtr :: new ( & ast:: Expr :: MacroStmts ( expansion) ) ,
687
- ) ;
688
-
689
- Some ( mac_stmts)
690
- }
691
- None => None ,
692
- } ,
693
- ) ;
694
-
695
- let expr = match stmt {
696
- Some ( expr) => {
697
- // Make the macro-call point to its expanded expression so we can query
698
- // semantics on syntax pointers to the macro
699
- let src = self . expander . to_source ( syntax_ptr) ;
700
- self . source_map . expr_map . insert ( src, expr) ;
701
- expr
702
- }
703
- None => self . alloc_expr ( Expr :: Missing , syntax_ptr) ,
704
- } ;
705
- Some ( Statement :: Expr { expr, has_semi } )
688
+ if let Some ( ast:: Expr :: MacroExpr ( mac) ) = expr {
689
+ if let Some ( expr) = self . collect_macro_as_stmt ( statements, mac) {
690
+ statements. push ( Statement :: Expr { expr, has_semi } )
691
+ }
706
692
} else {
707
693
let expr = self . collect_expr_opt ( expr) ;
708
- Some ( Statement :: Expr { expr, has_semi } )
694
+ statements . push ( Statement :: Expr { expr, has_semi } ) ;
709
695
}
710
696
}
711
- ast:: Stmt :: Item ( _item) => None ,
697
+ ast:: Stmt :: Item ( _item) => ( ) ,
712
698
}
713
699
}
714
700
@@ -729,9 +715,12 @@ impl ExprCollector<'_> {
729
715
let prev_def_map = mem:: replace ( & mut self . expander . def_map , def_map) ;
730
716
let prev_local_module = mem:: replace ( & mut self . expander . module , module) ;
731
717
732
- let mut statements: Vec < _ > =
733
- block. statements ( ) . filter_map ( |s| self . collect_stmt ( s) ) . collect ( ) ;
734
- let tail = block. tail_expr ( ) . and_then ( |e| self . maybe_collect_expr ( e) ) ;
718
+ let mut statements = Vec :: new ( ) ;
719
+ block. statements ( ) . for_each ( |s| self . collect_stmt ( & mut statements, s) ) ;
720
+ let tail = block. tail_expr ( ) . and_then ( |e| match e {
721
+ ast:: Expr :: MacroExpr ( mac) => self . collect_macro_as_stmt ( & mut statements, mac) ,
722
+ expr => self . maybe_collect_expr ( expr) ,
723
+ } ) ;
735
724
let tail = tail. or_else ( || {
736
725
let stmt = statements. pop ( ) ?;
737
726
if let Statement :: Expr { expr, has_semi : false } = stmt {
0 commit comments