diff --git a/rustfmt-core/rustfmt-lib/src/formatting/stmt.rs b/rustfmt-core/rustfmt-lib/src/formatting/stmt.rs index 7e788581bc9..91d0e012c45 100644 --- a/rustfmt-core/rustfmt-lib/src/formatting/stmt.rs +++ b/rustfmt-core/rustfmt-lib/src/formatting/stmt.rs @@ -53,6 +53,10 @@ impl<'a> Stmt<'a> { result } + pub(crate) fn is_empty(&self) -> bool { + matches!(self.inner.kind, ast::StmtKind::Empty) + } + fn is_last_expr(&self) -> bool { if !self.is_last { return false; diff --git a/rustfmt-core/rustfmt-lib/src/formatting/visitor.rs b/rustfmt-core/rustfmt-lib/src/formatting/visitor.rs index e63ab4f6724..439ae081ec5 100644 --- a/rustfmt-core/rustfmt-lib/src/formatting/visitor.rs +++ b/rustfmt-core/rustfmt-lib/src/formatting/visitor.rs @@ -25,7 +25,7 @@ use crate::formatting::{ utils::{ self, contains_skip, count_newlines, depr_skip_annotation, inner_attributes, last_line_contains_single_line_comment, last_line_width, mk_sp, ptr_vec_to_ref_vec, - rewrite_ident, stmt_expr, + rewrite_ident, starts_with_newline, stmt_expr, }, }; use crate::result::{ErrorKind, FormatError}; @@ -120,10 +120,22 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { self.parse_sess.span_to_debug_info(stmt.span()) ); - // https://github.com/rust-lang/rust/issues/63679. - let is_all_semicolons = - |snippet: &str| snippet.chars().all(|c| c.is_whitespace() || c == ';'); - if is_all_semicolons(&self.snippet(stmt.span())) { + if stmt.is_empty() { + // If the statement is empty, just skip over it. Before that, make sure any comment + // snippet preceding the semicolon is picked up. + let snippet = self.snippet(mk_sp(self.last_pos, stmt.span().lo())); + let original_starts_with_newline = snippet + .find(|c| c != ' ') + .map_or(false, |i| starts_with_newline(&snippet[i..])); + let snippet = snippet.trim(); + if !snippet.is_empty() { + if original_starts_with_newline { + self.push_str("\n"); + } + self.push_str(&self.block_indent.to_string(self.config)); + self.push_str(snippet); + } + self.last_pos = stmt.span().hi(); return; } diff --git a/rustfmt-core/rustfmt-lib/tests/source/issue-4018.rs b/rustfmt-core/rustfmt-lib/tests/source/issue-4018.rs new file mode 100644 index 00000000000..9a91dd9a306 --- /dev/null +++ b/rustfmt-core/rustfmt-lib/tests/source/issue-4018.rs @@ -0,0 +1,13 @@ +fn main() { + ; + /* extra comment */ ; +} + +fn main() { + println!(""); + // comment 1 + // comment 2 + // comment 3 + // comment 4 + ; +} diff --git a/rustfmt-core/rustfmt-lib/tests/target/issue-4018.rs b/rustfmt-core/rustfmt-lib/tests/target/issue-4018.rs new file mode 100644 index 00000000000..cef3be06148 --- /dev/null +++ b/rustfmt-core/rustfmt-lib/tests/target/issue-4018.rs @@ -0,0 +1,11 @@ +fn main() { + /* extra comment */ +} + +fn main() { + println!(""); + // comment 1 + // comment 2 + // comment 3 + // comment 4 +}