@@ -203,7 +203,7 @@ impl ExprCollector<'_> {
203203 self . maybe_collect_expr ( expr) . unwrap_or_else ( || self . missing_expr ( ) )
204204 }
205205
206- /// Returns `None` if the expression is `#[cfg]`d out.
206+ /// Returns `None` if and only if the expression is `#[cfg]`d out.
207207 fn maybe_collect_expr ( & mut self , expr : ast:: Expr ) -> Option < ExprId > {
208208 let syntax_ptr = AstPtr :: new ( & expr) ;
209209 self . check_cfg ( & expr) ?;
@@ -665,7 +665,7 @@ impl ExprCollector<'_> {
665665 if self . check_cfg ( & stmt) . is_none ( ) {
666666 return ;
667667 }
668-
668+ let has_semi = stmt . semicolon_token ( ) . is_some ( ) ;
669669 // Note that macro could be expended to multiple statements
670670 if let Some ( ast:: Expr :: MacroCall ( m) ) = stmt. expr ( ) {
671671 let macro_ptr = AstPtr :: new ( & m) ;
@@ -682,18 +682,19 @@ impl ExprCollector<'_> {
682682 statements. statements ( ) . for_each ( |stmt| this. collect_stmt ( stmt) ) ;
683683 if let Some ( expr) = statements. expr ( ) {
684684 let expr = this. collect_expr ( expr) ;
685- this. statements_in_scope . push ( Statement :: Expr ( expr) ) ;
685+ this. statements_in_scope
686+ . push ( Statement :: Expr { expr, has_semi } ) ;
686687 }
687688 }
688689 None => {
689690 let expr = this. alloc_expr ( Expr :: Missing , syntax_ptr. clone ( ) ) ;
690- this. statements_in_scope . push ( Statement :: Expr ( expr) ) ;
691+ this. statements_in_scope . push ( Statement :: Expr { expr, has_semi } ) ;
691692 }
692693 } ,
693694 ) ;
694695 } else {
695696 let expr = self . collect_expr_opt ( stmt. expr ( ) ) ;
696- self . statements_in_scope . push ( Statement :: Expr ( expr) ) ;
697+ self . statements_in_scope . push ( Statement :: Expr { expr, has_semi } ) ;
697698 }
698699 }
699700 ast:: Stmt :: Item ( item) => {
@@ -722,8 +723,17 @@ impl ExprCollector<'_> {
722723 let prev_statements = std:: mem:: take ( & mut self . statements_in_scope ) ;
723724
724725 block. statements ( ) . for_each ( |s| self . collect_stmt ( s) ) ;
725-
726- let tail = block. tail_expr ( ) . map ( |e| self . collect_expr ( e) ) ;
726+ block. tail_expr ( ) . and_then ( |e| {
727+ let expr = self . maybe_collect_expr ( e) ?;
728+ Some ( self . statements_in_scope . push ( Statement :: Expr { expr, has_semi : false } ) )
729+ } ) ;
730+
731+ let mut tail = None ;
732+ if let Some ( Statement :: Expr { expr, has_semi : false } ) = self . statements_in_scope . last ( ) {
733+ tail = Some ( * expr) ;
734+ self . statements_in_scope . pop ( ) ;
735+ }
736+ let tail = tail;
727737 let statements = std:: mem:: replace ( & mut self . statements_in_scope , prev_statements) ;
728738 let syntax_node_ptr = AstPtr :: new ( & block. into ( ) ) ;
729739 let expr_id = self . alloc_expr (
0 commit comments