@@ -112,7 +112,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
112
112
mk_sp ( self . last_pos , hi)
113
113
}
114
114
115
- fn visit_stmt ( & mut self , stmt : & Stmt < ' _ > ) {
115
+ fn visit_stmt ( & mut self , stmt : & Stmt < ' _ > , include_empty_semi : bool ) {
116
116
debug ! (
117
117
"visit_stmt: {}" ,
118
118
self . parse_sess. span_to_debug_info( stmt. span( ) )
@@ -127,22 +127,31 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
127
127
. map_or ( false , |i| starts_with_newline ( & snippet[ i..] ) ) ;
128
128
let snippet = snippet. trim ( ) ;
129
129
if !snippet. is_empty ( ) {
130
- if original_starts_with_newline {
131
- self . push_str ( "\n " ) ;
130
+ // FIXME(calebcartwright 2021-01-03) - This exists strictly to maintain legacy
131
+ // formatting where rustfmt would preserve redundant semicolons on Items in a
132
+ // statement position.
133
+ // See comment within `walk_stmts` for more info
134
+ if include_empty_semi {
135
+ self . format_missing ( stmt. span ( ) . hi ( ) ) ;
136
+ } else {
137
+ if original_starts_with_newline {
138
+ self . push_str ( "\n " ) ;
139
+ }
140
+
141
+ self . push_str ( & self . block_indent . to_string ( self . config ) ) ;
142
+ self . push_str ( snippet) ;
132
143
}
133
- self . push_str ( & self . block_indent . to_string ( self . config ) ) ;
134
- self . push_str ( snippet ) ;
144
+ } else if include_empty_semi {
145
+ self . push_str ( ";" ) ;
135
146
}
136
-
137
147
self . last_pos = stmt. span ( ) . hi ( ) ;
138
148
return ;
139
149
}
140
150
141
151
match stmt. as_ast_node ( ) . kind {
142
152
ast:: StmtKind :: Item ( ref item) => {
143
153
self . visit_item ( item) ;
144
- // Handle potential `;` after the item.
145
- self . format_missing ( stmt. span ( ) . hi ( ) ) ;
154
+ self . last_pos = stmt. span ( ) . hi ( ) ;
146
155
}
147
156
ast:: StmtKind :: Local ( ..) | ast:: StmtKind :: Expr ( ..) | ast:: StmtKind :: Semi ( ..) => {
148
157
let attrs = get_attrs_from_stmt ( stmt. as_ast_node ( ) ) ;
@@ -899,7 +908,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
899
908
self . visit_items_with_reordering ( & ptr_vec_to_ref_vec ( & m. items ) ) ;
900
909
}
901
910
902
- fn walk_stmts ( & mut self , stmts : & [ Stmt < ' _ > ] ) {
911
+ fn walk_stmts ( & mut self , stmts : & [ Stmt < ' _ > ] , include_current_empty_semi : bool ) {
903
912
if stmts. is_empty ( ) {
904
913
return ;
905
914
}
@@ -912,16 +921,38 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
912
921
. collect ( ) ;
913
922
914
923
if items. is_empty ( ) {
915
- self . visit_stmt ( & stmts[ 0 ] ) ;
916
- self . walk_stmts ( & stmts[ 1 ..] ) ;
924
+ self . visit_stmt ( & stmts[ 0 ] , include_current_empty_semi) ;
925
+
926
+ // FIXME(calebcartwright 2021-01-03) - This exists strictly to maintain legacy
927
+ // formatting where rustfmt would preserve redundant semicolons on Items in a
928
+ // statement position.
929
+ //
930
+ // Starting in rustc-ap-* v692 (~2020-12-01) the rustc parser now parses this as
931
+ // two separate statements (Item and Empty kinds), whereas before it was parsed as
932
+ // a single statement with the statement's span including the redundant semicolon.
933
+ //
934
+ // rustfmt typically tosses unnecessary/redundant semicolons, and eventually we
935
+ // should toss these as well, but doing so at this time would
936
+ // break the Stability Guarantee
937
+ // N.B. This could be updated to utilize the version gates.
938
+ let include_next_empty = if stmts. len ( ) > 1 {
939
+ match ( & stmts[ 0 ] . as_ast_node ( ) . kind , & stmts[ 1 ] . as_ast_node ( ) . kind ) {
940
+ ( ast:: StmtKind :: Item ( _) , ast:: StmtKind :: Empty ) => true ,
941
+ _ => false ,
942
+ }
943
+ } else {
944
+ false
945
+ } ;
946
+
947
+ self . walk_stmts ( & stmts[ 1 ..] , include_next_empty) ;
917
948
} else {
918
949
self . visit_items_with_reordering ( & items) ;
919
- self . walk_stmts ( & stmts[ items. len ( ) ..] ) ;
950
+ self . walk_stmts ( & stmts[ items. len ( ) ..] , false ) ;
920
951
}
921
952
}
922
953
923
954
fn walk_block_stmts ( & mut self , b : & ast:: Block ) {
924
- self . walk_stmts ( & Stmt :: from_ast_nodes ( b. stmts . iter ( ) ) )
955
+ self . walk_stmts ( & Stmt :: from_ast_nodes ( b. stmts . iter ( ) ) , false )
925
956
}
926
957
927
958
fn format_mod (
0 commit comments