@@ -183,7 +183,7 @@ impl ExprCollector<'_> {
183183 self . maybe_collect_expr ( expr) . unwrap_or_else ( || self . missing_expr ( ) )
184184 }
185185
186- /// Returns `None` if the expression is `#[cfg]`d out.
186+ /// Returns `None` if and only if the expression is `#[cfg]`d out.
187187 fn maybe_collect_expr ( & mut self , expr : ast:: Expr ) -> Option < ExprId > {
188188 let syntax_ptr = AstPtr :: new ( & expr) ;
189189 self . check_cfg ( & expr) ?;
@@ -641,7 +641,7 @@ impl ExprCollector<'_> {
641641 if self . check_cfg ( & stmt) . is_none ( ) {
642642 return ;
643643 }
644-
644+ let has_semi = stmt . semicolon_token ( ) . is_some ( ) ;
645645 // Note that macro could be expended to multiple statements
646646 if let Some ( ast:: Expr :: MacroCall ( m) ) = stmt. expr ( ) {
647647 let macro_ptr = AstPtr :: new ( & m) ;
@@ -658,18 +658,19 @@ impl ExprCollector<'_> {
658658 statements. statements ( ) . for_each ( |stmt| this. collect_stmt ( stmt) ) ;
659659 if let Some ( expr) = statements. expr ( ) {
660660 let expr = this. collect_expr ( expr) ;
661- this. statements_in_scope . push ( Statement :: Expr ( expr) ) ;
661+ this. statements_in_scope
662+ . push ( Statement :: Expr { expr, has_semi } ) ;
662663 }
663664 }
664665 None => {
665666 let expr = this. alloc_expr ( Expr :: Missing , syntax_ptr. clone ( ) ) ;
666- this. statements_in_scope . push ( Statement :: Expr ( expr) ) ;
667+ this. statements_in_scope . push ( Statement :: Expr { expr, has_semi } ) ;
667668 }
668669 } ,
669670 ) ;
670671 } else {
671672 let expr = self . collect_expr_opt ( stmt. expr ( ) ) ;
672- self . statements_in_scope . push ( Statement :: Expr ( expr) ) ;
673+ self . statements_in_scope . push ( Statement :: Expr { expr, has_semi } ) ;
673674 }
674675 }
675676 ast:: Stmt :: Item ( item) => {
@@ -698,8 +699,17 @@ impl ExprCollector<'_> {
698699 let prev_statements = std:: mem:: take ( & mut self . statements_in_scope ) ;
699700
700701 block. statements ( ) . for_each ( |s| self . collect_stmt ( s) ) ;
701-
702- let tail = block. tail_expr ( ) . map ( |e| self . collect_expr ( e) ) ;
702+ block. tail_expr ( ) . and_then ( |e| {
703+ let expr = self . maybe_collect_expr ( e) ?;
704+ Some ( self . statements_in_scope . push ( Statement :: Expr { expr, has_semi : false } ) )
705+ } ) ;
706+
707+ let mut tail = None ;
708+ if let Some ( Statement :: Expr { expr, has_semi : false } ) = self . statements_in_scope . last ( ) {
709+ tail = Some ( * expr) ;
710+ self . statements_in_scope . pop ( ) ;
711+ }
712+ let tail = tail;
703713 let statements = std:: mem:: replace ( & mut self . statements_in_scope , prev_statements) ;
704714 let syntax_node_ptr = AstPtr :: new ( & block. into ( ) ) ;
705715 let expr_id = self . alloc_expr (
0 commit comments