@@ -205,7 +205,7 @@ impl ExprCollector<'_> {
205205 self . maybe_collect_expr ( expr) . unwrap_or_else ( || self . missing_expr ( ) )
206206 }
207207
208- /// Returns `None` if the expression is `#[cfg]`d out.
208+ /// Returns `None` if and only if the expression is `#[cfg]`d out.
209209 fn maybe_collect_expr ( & mut self , expr : ast:: Expr ) -> Option < ExprId > {
210210 let syntax_ptr = AstPtr :: new ( & expr) ;
211211 self . check_cfg ( & expr) ?;
@@ -668,7 +668,7 @@ impl ExprCollector<'_> {
668668 if self . check_cfg ( & stmt) . is_none ( ) {
669669 return ;
670670 }
671-
671+ let has_semi = stmt . semicolon_token ( ) . is_some ( ) ;
672672 // Note that macro could be expended to multiple statements
673673 if let Some ( ast:: Expr :: MacroCall ( m) ) = stmt. expr ( ) {
674674 let macro_ptr = AstPtr :: new ( & m) ;
@@ -685,18 +685,19 @@ impl ExprCollector<'_> {
685685 statements. statements ( ) . for_each ( |stmt| this. collect_stmt ( stmt) ) ;
686686 if let Some ( expr) = statements. expr ( ) {
687687 let expr = this. collect_expr ( expr) ;
688- this. statements_in_scope . push ( Statement :: Expr ( expr) ) ;
688+ this. statements_in_scope
689+ . push ( Statement :: Expr { expr, has_semi } ) ;
689690 }
690691 }
691692 None => {
692693 let expr = this. alloc_expr ( Expr :: Missing , syntax_ptr. clone ( ) ) ;
693- this. statements_in_scope . push ( Statement :: Expr ( expr) ) ;
694+ this. statements_in_scope . push ( Statement :: Expr { expr, has_semi } ) ;
694695 }
695696 } ,
696697 ) ;
697698 } else {
698699 let expr = self . collect_expr_opt ( stmt. expr ( ) ) ;
699- self . statements_in_scope . push ( Statement :: Expr ( expr) ) ;
700+ self . statements_in_scope . push ( Statement :: Expr { expr, has_semi } ) ;
700701 }
701702 }
702703 ast:: Stmt :: Item ( item) => {
@@ -725,8 +726,17 @@ impl ExprCollector<'_> {
725726 let prev_statements = std:: mem:: take ( & mut self . statements_in_scope ) ;
726727
727728 block. statements ( ) . for_each ( |s| self . collect_stmt ( s) ) ;
728-
729- let tail = block. tail_expr ( ) . map ( |e| self . collect_expr ( e) ) ;
729+ block. tail_expr ( ) . and_then ( |e| {
730+ let expr = self . maybe_collect_expr ( e) ?;
731+ Some ( self . statements_in_scope . push ( Statement :: Expr { expr, has_semi : false } ) )
732+ } ) ;
733+
734+ let mut tail = None ;
735+ if let Some ( Statement :: Expr { expr, has_semi : false } ) = self . statements_in_scope . last ( ) {
736+ tail = Some ( * expr) ;
737+ self . statements_in_scope . pop ( ) ;
738+ }
739+ let tail = tail;
730740 let statements = std:: mem:: replace ( & mut self . statements_in_scope , prev_statements) ;
731741 let syntax_node_ptr = AstPtr :: new ( & block. into ( ) ) ;
732742 let expr_id = self . alloc_expr (
0 commit comments