@@ -550,20 +550,6 @@ impl ExprCollector<'_> {
550550 None => self . alloc_expr ( Expr :: Missing , syntax_ptr) ,
551551 }
552552 }
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- }
567553 ast:: Expr :: UnderscoreExpr ( _) => self . alloc_expr ( Expr :: Underscore , syntax_ptr) ,
568554 } )
569555 }
@@ -640,11 +626,46 @@ impl ExprCollector<'_> {
640626 }
641627 }
642628
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 ) {
644665 match s {
645666 ast:: Stmt :: LetStmt ( stmt) => {
646667 if self . check_cfg ( & stmt) . is_none ( ) {
647- return None ;
668+ return ;
648669 }
649670 let pat = self . collect_pat_opt ( stmt. pat ( ) ) ;
650671 let type_ref =
@@ -654,61 +675,26 @@ impl ExprCollector<'_> {
654675 . let_else ( )
655676 . and_then ( |let_else| let_else. block_expr ( ) )
656677 . 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 } ) ;
658679 }
659680 ast:: Stmt :: ExprStmt ( stmt) => {
660681 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+ _ => ( ) ,
665685 }
666686 let has_semi = stmt. semicolon_token ( ) . is_some ( ) ;
667687 // 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+ }
706692 } else {
707693 let expr = self . collect_expr_opt ( expr) ;
708- Some ( Statement :: Expr { expr, has_semi } )
694+ statements . push ( Statement :: Expr { expr, has_semi } ) ;
709695 }
710696 }
711- ast:: Stmt :: Item ( _item) => None ,
697+ ast:: Stmt :: Item ( _item) => ( ) ,
712698 }
713699 }
714700
@@ -729,9 +715,12 @@ impl ExprCollector<'_> {
729715 let prev_def_map = mem:: replace ( & mut self . expander . def_map , def_map) ;
730716 let prev_local_module = mem:: replace ( & mut self . expander . module , module) ;
731717
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+ } ) ;
735724 let tail = tail. or_else ( || {
736725 let stmt = statements. pop ( ) ?;
737726 if let Statement :: Expr { expr, has_semi : false } = stmt {
0 commit comments