Repository: rust-lang/rustfmt (rust)

Issue:
Comments in imports are formatted incorrectly
Examples:
```rs
use std::{
    fs,
    // (temporarily commented, we'll need this again in a second) io,
};

use foo::{
    self // this is important
};
```

Becomes:
```rs
use std::fs;

use foo::{self, // this is important};
```

Which now has syntax errors.

Pull request:
Fix issues with formatting imports with comments
Fixes #5852

Patch:
diff --git a/src/imports.rs b/src/imports.rs
index 6f005064..f8e7fa62 100644
--- a/src/imports.rs
+++ b/src/imports.rs
@@ -589,7 +589,7 @@ impl UseTree {
 
         // Normalise foo::{bar} -> foo::bar
         if let UseSegmentKind::List(ref list) = last.kind {
-            if list.len() == 1 && list[0].to_string() != "self" {
+            if list.len() == 1 && list[0].to_string() != "self" && !list[0].has_comment() {
                 normalize_sole_list = true;
             }
         }
@@ -1032,7 +1032,9 @@ fn rewrite_nested_use_tree(
 
     let list_str = write_list(&list_items, &fmt)?;
 
-    let result = if (list_str.contains('\n') || list_str.len() > remaining_width)
+    let result = if (list_str.contains('\n')
+        || list_str.len() > remaining_width
+        || tactic == DefinitiveListTactic::Vertical)
         && context.config.imports_indent() == IndentStyle::Block
     {
         format!(
diff --git a/src/lists.rs b/src/lists.rs
index a878e6cf..41afef27 100644
--- a/src/lists.rs
+++ b/src/lists.rs
@@ -637,7 +637,7 @@ pub(crate) fn extract_post_comment(
         post_snippet.trim_matches(white_space)
     }
     // not comment or over two lines
-    else if post_snippet.ends_with(',')
+    else if post_snippet.ends_with(separator)
         && (!post_snippet.trim().starts_with("//") || post_snippet.trim().contains('\n'))
     {
         post_snippet[..(post_snippet.len() - 1)].trim_matches(white_space)


Test patch:
diff --git a/tests/source/issue-3984.rs b/tests/source/issue-3984.rs
new file mode 100644
index 00000000..c9bcfa40
--- /dev/null
+++ b/tests/source/issue-3984.rs
@@ -0,0 +1,12 @@
+use a::{item /* comment */};
+use b::{
+    a,
+    // comment
+    item,
+};
+use c::item /* comment */;
+use d::item; // really long comment (with `use` exactly 100 characters) ____________________________
+
+use std::e::{/* it's a comment! */ bar /* and another */};
+use std::f::{/* it's a comment! */ bar};
+use std::g::{bar /* and another */};
diff --git a/tests/source/issue-5852/default.rs b/tests/source/issue-5852/default.rs
new file mode 100644
index 00000000..df84f8f5
--- /dev/null
+++ b/tests/source/issue-5852/default.rs
@@ -0,0 +1,104 @@
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self // this is important
+};
+
+use foo :: bar
+;
+
+use foo::{bar};
+
+use foo::{
+    bar
+    // abc
+};
+
+use foo::{
+    bar,
+    // abc
+};
+
+use foo::{
+    // 345
+    bar
+};
+
+use foo::{
+    self
+    // abc
+};
+
+use foo::{
+    self,
+    // abc
+};
+
+use foo::{
+    // 345
+    self
+};
+
+use foo::{
+    self // a
+        ,
+};
+
+use foo::{ self /* a */ };
+
+use foo::{ self /* a */, };
+
+use foo::{
+    // abc
+    abc::{
+        xyz
+        // 123
+    }
+};
+
+use foo::{
+    // abc
+    bar,
+    abc
+};
+
+use foo::{
+    bar,
+    // abc
+    abc
+};
+
+use foo::{
+    bar,
+    abc
+    // abc
+};
+
+use foo::{
+    bar,
+    abc,
+    // abc
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        xyz
+        // 123
+    }
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        // 123
+        xyz
+    }
+};
+
+use path::{self /*comment*/,};
diff --git a/tests/source/issue-5852/horizontal.rs b/tests/source/issue-5852/horizontal.rs
new file mode 100644
index 00000000..63bfb7e5
--- /dev/null
+++ b/tests/source/issue-5852/horizontal.rs
@@ -0,0 +1,106 @@
+// rustfmt-imports_layout: Horizontal
+
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self // this is important
+};
+
+use foo :: bar
+;
+
+use foo::{bar};
+
+use foo::{
+    bar
+    // abc
+};
+
+use foo::{
+    bar,
+    // abc
+};
+
+use foo::{
+    // 345
+    bar
+};
+
+use foo::{
+    self
+    // abc
+};
+
+use foo::{
+    self,
+    // abc
+};
+
+use foo::{
+    // 345
+    self
+};
+
+use foo::{
+    self // a
+        ,
+};
+
+use foo::{ self /* a */ };
+
+use foo::{ self /* a */, };
+
+use foo::{
+    // abc
+    abc::{
+        xyz
+        // 123
+    }
+};
+
+use foo::{
+    // abc
+    bar,
+    abc
+};
+
+use foo::{
+    bar,
+    // abc
+    abc
+};
+
+use foo::{
+    bar,
+    abc
+    // abc
+};
+
+use foo::{
+    bar,
+    abc,
+    // abc
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        xyz
+        // 123
+    }
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        // 123
+        xyz
+    }
+};
+
+use path::{self /*comment*/,};
diff --git a/tests/source/issue-5852/horizontal_vertical.rs b/tests/source/issue-5852/horizontal_vertical.rs
new file mode 100644
index 00000000..3f3ce066
--- /dev/null
+++ b/tests/source/issue-5852/horizontal_vertical.rs
@@ -0,0 +1,106 @@
+// rustfmt-imports_layout: HorizontalVertical
+
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self // this is important
+};
+
+use foo :: bar
+;
+
+use foo::{bar};
+
+use foo::{
+    bar
+    // abc
+};
+
+use foo::{
+    bar,
+    // abc
+};
+
+use foo::{
+    // 345
+    bar
+};
+
+use foo::{
+    self
+    // abc
+};
+
+use foo::{
+    self,
+    // abc
+};
+
+use foo::{
+    // 345
+    self
+};
+
+use foo::{
+    self // a
+        ,
+};
+
+use foo::{ self /* a */ };
+
+use foo::{ self /* a */, };
+
+use foo::{
+    // abc
+    abc::{
+        xyz
+        // 123
+    }
+};
+
+use foo::{
+    // abc
+    bar,
+    abc
+};
+
+use foo::{
+    bar,
+    // abc
+    abc
+};
+
+use foo::{
+    bar,
+    abc
+    // abc
+};
+
+use foo::{
+    bar,
+    abc,
+    // abc
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        xyz
+        // 123
+    }
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        // 123
+        xyz
+    }
+};
+
+use path::{self /*comment*/,};
diff --git a/tests/source/issue-5852/issue_example.rs b/tests/source/issue-5852/issue_example.rs
new file mode 100644
index 00000000..20c2b764
--- /dev/null
+++ b/tests/source/issue-5852/issue_example.rs
@@ -0,0 +1,8 @@
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self // this is important
+};
diff --git a/tests/source/issue-5852/split.rs b/tests/source/issue-5852/split.rs
new file mode 100644
index 00000000..14e9ea1b
--- /dev/null
+++ b/tests/source/issue-5852/split.rs
@@ -0,0 +1,111 @@
+// rustfmt-imports_granularity: Item
+
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self // this is important
+};
+
+use foo :: bar
+;
+
+use foo::{bar};
+
+use foo::{
+    bar
+    // abc
+};
+
+use foo::{
+    bar,
+    // abc
+};
+
+use foo::{
+    // 345
+    bar
+};
+
+use foo::{
+    self
+    // abc
+};
+
+use foo::{
+    self,
+    // abc
+};
+
+use foo::{
+    // 345
+    self
+};
+
+use foo::{
+    self // a
+        ,
+};
+
+use foo::{ self /* a */ };
+
+use foo::{ self /* a */, };
+
+use foo::{
+    // abc
+    abc::{
+        xyz
+        // 123
+    }
+};
+
+use foo::{
+    bar,
+    abc
+};
+
+use foo::{
+    // abc
+    bar,
+    abc
+};
+
+use foo::{
+    bar,
+    // abc
+    abc
+};
+
+use foo::{
+    bar,
+    abc
+    // abc
+};
+
+use foo::{
+    bar,
+    abc,
+    // abc
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        xyz
+        // 123
+    }
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        // 123
+        xyz
+    }
+};
+
+use path::{self /*comment*/,};
diff --git a/tests/source/issue-5852/vertical.rs b/tests/source/issue-5852/vertical.rs
new file mode 100644
index 00000000..b9ba9988
--- /dev/null
+++ b/tests/source/issue-5852/vertical.rs
@@ -0,0 +1,106 @@
+// rustfmt-imports_layout: Vertical
+
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self // this is important
+};
+
+use foo :: bar
+;
+
+use foo::{bar};
+
+use foo::{
+    bar
+    // abc
+};
+
+use foo::{
+    bar,
+    // abc
+};
+
+use foo::{
+    // 345
+    bar
+};
+
+use foo::{
+    self
+    // abc
+};
+
+use foo::{
+    self,
+    // abc
+};
+
+use foo::{
+    // 345
+    self
+};
+
+use foo::{
+    self // a
+        ,
+};
+
+use foo::{ self /* a */ };
+
+use foo::{ self /* a */, };
+
+use foo::{
+    // abc
+    abc::{
+        xyz
+        // 123
+    }
+};
+
+use foo::{
+    // abc
+    bar,
+    abc
+};
+
+use foo::{
+    bar,
+    // abc
+    abc
+};
+
+use foo::{
+    bar,
+    abc
+    // abc
+};
+
+use foo::{
+    bar,
+    abc,
+    // abc
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        xyz
+        // 123
+    }
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        // 123
+        xyz
+    }
+};
+
+use path::{self /*comment*/,};
diff --git a/tests/target/issue-3984.rs b/tests/target/issue-3984.rs
new file mode 100644
index 00000000..9e700c0f
--- /dev/null
+++ b/tests/target/issue-3984.rs
@@ -0,0 +1,12 @@
+use a::{item /* comment */};
+use b::{
+    a,
+    // comment
+    item,
+};
+use c::item; /* comment */
+use d::item; // really long comment (with `use` exactly 100 characters) ____________________________
+
+use std::e::{/* it's a comment! */ bar /* and another */};
+use std::f::{/* it's a comment! */ bar};
+use std::g::{bar /* and another */};
diff --git a/tests/target/issue-5852/default.rs b/tests/target/issue-5852/default.rs
new file mode 100644
index 00000000..a86872a6
--- /dev/null
+++ b/tests/target/issue-5852/default.rs
@@ -0,0 +1,97 @@
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self, // this is important
+};
+
+use foo::bar;
+
+use foo::bar;
+
+use foo::{
+    bar, // abc
+};
+
+use foo::{
+    bar,
+    // abc
+};
+
+use foo::{
+    // 345
+    bar,
+};
+
+use foo::{
+    self, // abc
+};
+
+use foo::{
+    self,
+    // abc
+};
+
+use foo::{
+    // 345
+    self,
+};
+
+use foo::{
+    self, // a
+};
+
+use foo::{self /* a */};
+
+use foo::{self /* a */};
+
+use foo::{
+    // abc
+    abc::{
+        xyz, // 123
+    },
+};
+
+use foo::{
+    abc,
+    // abc
+    bar,
+};
+
+use foo::{
+    // abc
+    abc,
+    bar,
+};
+
+use foo::{
+    abc, // abc
+    bar,
+};
+
+use foo::{
+    abc,
+    // abc
+    bar,
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        xyz, // 123
+    },
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        // 123
+        xyz,
+    },
+};
+
+use path::{self /*comment*/};
diff --git a/tests/target/issue-5852/horizontal.rs b/tests/target/issue-5852/horizontal.rs
new file mode 100644
index 00000000..017d83c9
--- /dev/null
+++ b/tests/target/issue-5852/horizontal.rs
@@ -0,0 +1,99 @@
+// rustfmt-imports_layout: Horizontal
+
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self, // this is important
+};
+
+use foo::bar;
+
+use foo::bar;
+
+use foo::{
+    bar, // abc
+};
+
+use foo::{
+    bar,
+    // abc
+};
+
+use foo::{
+    // 345
+    bar,
+};
+
+use foo::{
+    self, // abc
+};
+
+use foo::{
+    self,
+    // abc
+};
+
+use foo::{
+    // 345
+    self,
+};
+
+use foo::{
+    self, // a
+};
+
+use foo::{self /* a */};
+
+use foo::{self /* a */};
+
+use foo::{
+    // abc
+    abc::{
+        xyz, // 123
+    },
+};
+
+use foo::{
+    abc,
+    // abc
+    bar,
+};
+
+use foo::{
+    // abc
+    abc,
+    bar,
+};
+
+use foo::{
+    abc, // abc
+    bar,
+};
+
+use foo::{
+    abc,
+    // abc
+    bar,
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        xyz, // 123
+    },
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        // 123
+        xyz,
+    },
+};
+
+use path::{self /*comment*/};
diff --git a/tests/target/issue-5852/horizontal_vertical.rs b/tests/target/issue-5852/horizontal_vertical.rs
new file mode 100644
index 00000000..35e2d0a2
--- /dev/null
+++ b/tests/target/issue-5852/horizontal_vertical.rs
@@ -0,0 +1,99 @@
+// rustfmt-imports_layout: HorizontalVertical
+
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self, // this is important
+};
+
+use foo::bar;
+
+use foo::bar;
+
+use foo::{
+    bar, // abc
+};
+
+use foo::{
+    bar,
+    // abc
+};
+
+use foo::{
+    // 345
+    bar,
+};
+
+use foo::{
+    self, // abc
+};
+
+use foo::{
+    self,
+    // abc
+};
+
+use foo::{
+    // 345
+    self,
+};
+
+use foo::{
+    self, // a
+};
+
+use foo::{self /* a */};
+
+use foo::{self /* a */};
+
+use foo::{
+    // abc
+    abc::{
+        xyz, // 123
+    },
+};
+
+use foo::{
+    abc,
+    // abc
+    bar,
+};
+
+use foo::{
+    // abc
+    abc,
+    bar,
+};
+
+use foo::{
+    abc, // abc
+    bar,
+};
+
+use foo::{
+    abc,
+    // abc
+    bar,
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        xyz, // 123
+    },
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        // 123
+        xyz,
+    },
+};
+
+use path::{self /*comment*/};
diff --git a/tests/target/issue-5852/issue_example.rs b/tests/target/issue-5852/issue_example.rs
new file mode 100644
index 00000000..46326291
--- /dev/null
+++ b/tests/target/issue-5852/issue_example.rs
@@ -0,0 +1,8 @@
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self, // this is important
+};
diff --git a/tests/target/issue-5852/split.rs b/tests/target/issue-5852/split.rs
new file mode 100644
index 00000000..e00086dd
--- /dev/null
+++ b/tests/target/issue-5852/split.rs
@@ -0,0 +1,102 @@
+// rustfmt-imports_granularity: Item
+
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self, // this is important
+};
+
+use foo::bar;
+
+use foo::bar;
+
+use foo::{
+    bar, // abc
+};
+
+use foo::{
+    bar,
+    // abc
+};
+
+use foo::{
+    // 345
+    bar,
+};
+
+use foo::{
+    self, // abc
+};
+
+use foo::{
+    self,
+    // abc
+};
+
+use foo::{
+    // 345
+    self,
+};
+
+use foo::{
+    self, // a
+};
+
+use foo::{self /* a */};
+
+use foo::{self /* a */};
+
+use foo::{
+    // abc
+    abc::{
+        xyz, // 123
+    },
+};
+
+use foo::abc;
+use foo::bar;
+
+use foo::{
+    abc,
+    // abc
+    bar,
+};
+
+use foo::{
+    // abc
+    abc,
+    bar,
+};
+
+use foo::{
+    abc, // abc
+    bar,
+};
+
+use foo::{
+    abc,
+    // abc
+    bar,
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        xyz, // 123
+    },
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        // 123
+        xyz,
+    },
+};
+
+use path::{self /*comment*/};
diff --git a/tests/target/issue-5852/vertical.rs b/tests/target/issue-5852/vertical.rs
new file mode 100644
index 00000000..f53a68c9
--- /dev/null
+++ b/tests/target/issue-5852/vertical.rs
@@ -0,0 +1,105 @@
+// rustfmt-imports_layout: Vertical
+
+use std::{
+    fs,
+    // (temporarily commented, we'll need this again in a second) io,
+};
+
+use foo::{
+    self, // this is important
+};
+
+use foo::bar;
+
+use foo::bar;
+
+use foo::{
+    bar, // abc
+};
+
+use foo::{
+    bar,
+    // abc
+};
+
+use foo::{
+    // 345
+    bar,
+};
+
+use foo::{
+    self, // abc
+};
+
+use foo::{
+    self,
+    // abc
+};
+
+use foo::{
+    // 345
+    self,
+};
+
+use foo::{
+    self, // a
+};
+
+use foo::{
+    self, /* a */
+};
+
+use foo::{
+    self, /* a */
+};
+
+use foo::{
+    // abc
+    abc::{
+        xyz, // 123
+    },
+};
+
+use foo::{
+    abc,
+    // abc
+    bar,
+};
+
+use foo::{
+    // abc
+    abc,
+    bar,
+};
+
+use foo::{
+    abc, // abc
+    bar,
+};
+
+use foo::{
+    abc,
+    // abc
+    bar,
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        xyz, // 123
+    },
+};
+
+use foo::{
+    self,
+    // abc
+    abc::{
+        // 123
+        xyz,
+    },
+};
+
+use path::{
+    self, /*comment*/
+};