From b4a4bf0bf8a16913b9f16f2aee7030065ff00931 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Szymon=20Giba=C5=82a?= <szymongib@gmail.com>
Date: Sat, 29 Jan 2022 05:55:47 +0100
Subject: [PATCH] Fix formatting of comments in empty structs (#5171)

* Fix formatting of comments in empty structs

* Add tests

* Add single line tests

* Fix block comments

* Revert changes of test source files
---
 src/items.rs                                  |  10 +-
 tests/source/issue_4854.rs                    | 113 +++++++++++++++++
 .../comments-in-lists/format-doc-comments.rs  |  10 +-
 .../comments-in-lists/wrap-comments-false.rs  |  10 +-
 .../wrap-comments-not-normalized.rs           |   8 +-
 .../comments-in-lists/wrap-comments-true.rs   |   8 +-
 tests/target/issue_4854.rs                    | 115 ++++++++++++++++++
 7 files changed, 251 insertions(+), 23 deletions(-)
 create mode 100644 tests/source/issue_4854.rs
 create mode 100644 tests/target/issue_4854.rs

diff --git a/src/items.rs b/src/items.rs
index babc56f86ed..4c7a33c86d2 100644
--- a/src/items.rs
+++ b/src/items.rs
@@ -1374,17 +1374,21 @@ fn format_empty_struct_or_tuple(
         result.push_str(&offset.to_string_with_newline(context.config))
     }
     result.push_str(opener);
-    match rewrite_missing_comment(span, Shape::indented(offset, context.config), context) {
+
+    // indented shape for proper indenting of multi-line comments
+    let shape = Shape::indented(offset.block_indent(context.config), context.config);
+    match rewrite_missing_comment(span, shape, context) {
         Some(ref s) if s.is_empty() => (),
         Some(ref s) => {
-            if !is_single_line(s) || first_line_contains_single_line_comment(s) {
+            let is_multi_line = !is_single_line(s);
+            if is_multi_line || first_line_contains_single_line_comment(s) {
                 let nested_indent_str = offset
                     .block_indent(context.config)
                     .to_string_with_newline(context.config);
                 result.push_str(&nested_indent_str);
             }
             result.push_str(s);
-            if last_line_contains_single_line_comment(s) {
+            if is_multi_line || last_line_contains_single_line_comment(s) {
                 result.push_str(&offset.to_string_with_newline(context.config));
             }
         }
diff --git a/tests/source/issue_4854.rs b/tests/source/issue_4854.rs
new file mode 100644
index 00000000000..35d6e21affe
--- /dev/null
+++ b/tests/source/issue_4854.rs
@@ -0,0 +1,113 @@
+struct Struct {
+    // Multiline comment
+    // should be formatted
+    // properly.
+}
+
+struct Struct2 {
+    // This formatting
+// Should be changed
+}
+
+struct Struct3(
+    // This
+    // is
+    // correct
+);
+
+struct Struct4(
+    // This
+// is
+// not
+// correct
+);
+
+struct Struct5 {
+    /*
+    Comment block
+    with many lines.
+    */
+}
+
+struct Struct6(
+    /*
+    Comment block
+    with many lines.
+    */
+);
+
+struct Struct7 {
+    /*
+Invalid
+format
+*/
+}
+
+struct Struct8(
+    /*
+Invalid
+format
+*/
+);
+
+struct Struct9 { /* bar */ }
+
+struct Struct10 { /* bar
+baz
+*/ }
+
+mod module {
+    struct Struct {
+        // Multiline comment
+        // should be formatted
+        // properly.
+    }
+
+    struct Struct2 {
+        // This formatting
+// Should be changed
+    }
+
+    struct Struct3(
+        // This
+        // is
+        // correct
+    );
+
+    struct Struct4(
+        // This
+    // is
+    // not
+// correct
+    );
+
+    struct Struct5 {
+        /*
+        Comment block
+        with many lines.
+         */
+    }
+
+    struct Struct6(
+        /*
+        Comment block
+        with many lines.
+        */
+    );
+
+    struct Struct7 {
+        /*
+Invalid
+format
+*/
+    }
+
+    struct Struct8(
+        /*
+Invalid
+format
+*/
+    );
+
+    struct Struct9 { /* bar */ }
+}
diff --git a/tests/target/comments-in-lists/format-doc-comments.rs b/tests/target/comments-in-lists/format-doc-comments.rs
index be31bf0a331..be4b7a8c42e 100644
--- a/tests/target/comments-in-lists/format-doc-comments.rs
+++ b/tests/target/comments-in-lists/format-doc-comments.rs
@@ -25,9 +25,8 @@ pub enum E {
 }
 
 pub enum E2 {
-    // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed
-// Expand as needed, numbers should be ascending according to the stage
-// through the inclusion pipeline, or according to the descriptions
+    // Expand as needed, numbers should be ascending according to the stage
+    // through the inclusion pipeline, or according to the descriptions
 }
 
 pub struct S {
@@ -42,9 +41,8 @@ pub struct S {
 }
 
 pub struct S2 {
-    // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed
-// Expand as needed, numbers should be ascending according to the stage
-// through the inclusion pipeline, or according to the descriptions
+    // Expand as needed, numbers should be ascending according to the stage
+    // through the inclusion pipeline, or according to the descriptions
 }
 
 fn foo(
diff --git a/tests/target/comments-in-lists/wrap-comments-false.rs b/tests/target/comments-in-lists/wrap-comments-false.rs
index 80aea59d1b5..db4da622372 100644
--- a/tests/target/comments-in-lists/wrap-comments-false.rs
+++ b/tests/target/comments-in-lists/wrap-comments-false.rs
@@ -13,9 +13,8 @@ pub enum E {
 }
 
 pub enum E2 {
-    // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed
-// Expand as needed, numbers should be ascending according to the stage
-// through the inclusion pipeline, or according to the descriptions
+    // Expand as needed, numbers should be ascending according to the stage
+    // through the inclusion pipeline, or according to the descriptions
 }
 
 pub struct S {
@@ -30,9 +29,8 @@ pub struct S {
 }
 
 pub struct S2 {
-    // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed
-// Expand as needed, numbers should be ascending according to the stage
-// through the inclusion pipeline, or according to the descriptions
+    // Expand as needed, numbers should be ascending according to the stage
+    // through the inclusion pipeline, or according to the descriptions
 }
 
 fn foo(
diff --git a/tests/target/comments-in-lists/wrap-comments-not-normalized.rs b/tests/target/comments-in-lists/wrap-comments-not-normalized.rs
index 52315f470e4..9b9147eb124 100644
--- a/tests/target/comments-in-lists/wrap-comments-not-normalized.rs
+++ b/tests/target/comments-in-lists/wrap-comments-not-normalized.rs
@@ -14,8 +14,8 @@ pub enum E {
 
 pub enum E2 {
     // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed
-// Expand as needed, numbers should be ascending according to the stage
-// through the inclusion pipeline, or according to the descriptions
+    // Expand as needed, numbers should be ascending according to the stage
+    // through the inclusion pipeline, or according to the descriptions
 }
 
 pub enum E3 {
@@ -42,8 +42,8 @@ pub struct S {
 
 pub struct S2 {
     // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed
-// Expand as needed, numbers should be ascending according to the stage
-// through the inclusion pipeline, or according to the descriptions
+    // Expand as needed, numbers should be ascending according to the stage
+    // through the inclusion pipeline, or according to the descriptions
 }
 
 pub struct S3 {
diff --git a/tests/target/comments-in-lists/wrap-comments-true.rs b/tests/target/comments-in-lists/wrap-comments-true.rs
index e0bfcf0b500..c1531d22a4a 100644
--- a/tests/target/comments-in-lists/wrap-comments-true.rs
+++ b/tests/target/comments-in-lists/wrap-comments-true.rs
@@ -15,8 +15,8 @@ pub enum E {
 
 pub enum E2 {
     // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed
-// Expand as needed, numbers should be ascending according to the stage
-// through the inclusion pipeline, or according to the descriptions
+    // Expand as needed, numbers should be ascending according to the stage
+    // through the inclusion pipeline, or according to the descriptions
 }
 
 pub enum E3 {
@@ -43,8 +43,8 @@ pub struct S {
 
 pub struct S2 {
     // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed
-// Expand as needed, numbers should be ascending according to the stage
-// through the inclusion pipeline, or according to the descriptions
+    // Expand as needed, numbers should be ascending according to the stage
+    // through the inclusion pipeline, or according to the descriptions
 }
 
 pub struct S3 {
diff --git a/tests/target/issue_4854.rs b/tests/target/issue_4854.rs
new file mode 100644
index 00000000000..a81c5a5171f
--- /dev/null
+++ b/tests/target/issue_4854.rs
@@ -0,0 +1,115 @@
+struct Struct {
+    // Multiline comment
+    // should be formatted
+    // properly.
+}
+
+struct Struct2 {
+    // This formatting
+    // Should be changed
+}
+
+struct Struct3(
+    // This
+    // is
+    // correct
+);
+
+struct Struct4(
+    // This
+    // is
+    // not
+    // correct
+);
+
+struct Struct5 {
+    /*
+    Comment block
+    with many lines.
+    */
+}
+
+struct Struct6(
+    /*
+    Comment block
+    with many lines.
+    */
+);
+
+struct Struct7 {
+    /*
+    Invalid
+    format
+    */
+}
+
+struct Struct8(
+    /*
+    Invalid
+    format
+    */
+);
+
+struct Struct9 {/* bar */}
+
+struct Struct10 {
+    /* bar
+    baz
+    */
+}
+
+mod module {
+    struct Struct {
+        // Multiline comment
+        // should be formatted
+        // properly.
+    }
+
+    struct Struct2 {
+        // This formatting
+        // Should be changed
+    }
+
+    struct Struct3(
+        // This
+        // is
+        // correct
+    );
+
+    struct Struct4(
+        // This
+        // is
+        // not
+        // correct
+    );
+
+    struct Struct5 {
+        /*
+        Comment block
+        with many lines.
+         */
+    }
+
+    struct Struct6(
+        /*
+        Comment block
+        with many lines.
+        */
+    );
+
+    struct Struct7 {
+        /*
+        Invalid
+        format
+        */
+    }
+
+    struct Struct8(
+        /*
+        Invalid
+        format
+        */
+    );
+
+    struct Struct9 {/* bar */}
+}