Skip to content

Commit 1bc57ce

Browse files
Allow formatting of use behind #[cfg*]
Fix #6666 We would like to allow formatting items with attributes that conceptually allows outer styling as well. Signed-off-by: Xiangfei Ding <dingxiangfei2009@protonmail.ch>
1 parent d21c8f3 commit 1bc57ce

13 files changed

Lines changed: 139 additions & 10 deletions

src/imports.rs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use std::borrow::Cow;
21
use std::cmp::Ordering;
32
use std::fmt;
3+
use std::{borrow::Cow, vec};
44

55
use core::hash::{Hash, Hasher};
66

@@ -130,7 +130,7 @@ pub(crate) struct UseTree {
130130

131131
impl PartialEq for UseTree {
132132
fn eq(&self, other: &UseTree) -> bool {
133-
self.path == other.path
133+
self.path == other.path && !self.has_attrs() && !other.has_attrs()
134134
}
135135
}
136136
impl Eq for UseTree {}
@@ -233,13 +233,19 @@ pub(crate) fn normalize_use_trees_with_granularity(
233233

234234
let mut result = Vec::with_capacity(use_trees.len());
235235
for use_tree in use_trees {
236-
if use_tree.contains_comment() || use_tree.attrs.is_some() {
236+
if use_tree.contains_comment() || use_tree.has_attrs_disallow_outer_style() {
237237
result.push(use_tree);
238238
continue;
239239
}
240+
let attrs = use_tree.attrs.clone();
241+
let result_buf = if attrs.is_some() {
242+
&mut vec![]
243+
} else {
244+
&mut result
245+
};
240246

241247
for mut flattened in use_tree.flatten(import_granularity) {
242-
if let Some(tree) = result
248+
if let Some(tree) = result_buf
243249
.iter_mut()
244250
.find(|tree| tree.share_prefix(&flattened, merge_by))
245251
{
@@ -249,9 +255,19 @@ pub(crate) fn normalize_use_trees_with_granularity(
249255
if merge_by == SharedPrefix::Module {
250256
flattened = flattened.nest_trailing_self();
251257
}
252-
result.push(flattened);
258+
result_buf.push(flattened);
253259
}
254260
}
261+
if let Some(attrs) = attrs {
262+
let result_buf: Vec<_> = result_buf
263+
.drain(..)
264+
.map(|mut use_tree| {
265+
use_tree.attrs = Some(attrs.clone());
266+
use_tree
267+
})
268+
.collect();
269+
result.extend(result_buf);
270+
}
255271
}
256272
result
257273
}
@@ -559,7 +575,7 @@ impl UseTree {
559575

560576
// Remove foo::{} or self without attributes.
561577
match last.kind {
562-
_ if self.attrs.is_some() => (),
578+
_ if self.has_attrs() => (),
563579
UseSegmentKind::List(ref list) if list.is_empty() => {
564580
self.path = vec![];
565581
return self;
@@ -657,6 +673,17 @@ impl UseTree {
657673
self.has_comment() || self.path.iter().any(|path| path.contains_comment())
658674
}
659675

676+
fn has_attrs(&self) -> bool {
677+
self.attrs.is_some()
678+
}
679+
680+
fn has_attrs_disallow_outer_style(&self) -> bool {
681+
!self.attrs.iter().flatten().all(|attr| match &attr.kind {
682+
ast::AttrKind::Normal(attr) => attr.item.is_valid_for_outer_style(),
683+
ast::AttrKind::DocComment(..) => false,
684+
})
685+
}
686+
660687
fn same_visibility(&self, other: &UseTree) -> bool {
661688
match (&self.visibility, &other.visibility) {
662689
(
@@ -682,7 +709,8 @@ impl UseTree {
682709
fn share_prefix(&self, other: &UseTree, shared_prefix: SharedPrefix) -> bool {
683710
if self.path.is_empty()
684711
|| other.path.is_empty()
685-
|| self.attrs.is_some()
712+
|| self.has_attrs()
713+
|| other.has_attrs()
686714
|| self.contains_comment()
687715
|| !self.same_visibility(other)
688716
{
@@ -697,7 +725,8 @@ impl UseTree {
697725
}
698726

699727
fn flatten(self, import_granularity: ImportGranularity) -> Vec<UseTree> {
700-
if self.path.is_empty() || self.contains_comment() {
728+
if self.path.is_empty() || self.contains_comment() || self.has_attrs_disallow_outer_style()
729+
{
701730
return vec![self];
702731
}
703732
match &self.path.clone().last().unwrap().kind {

tests/source/imports/imports_granularity_crate.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,13 @@ use b::v::{
6363
};
6464
use b::t::{/* Before b::t::self */ self};
6565
use b::c;
66+
67+
// https://github.com/rust-lang/rustfmt/issues/6666
68+
#[cfg(true)]
69+
use a::{b::c, d::e, d::f};
70+
71+
#[my_attribute]
72+
use a::{b::c,d::e,d::f};
73+
74+
/// Some doc comment
75+
use a::{b::c,d::e,d::f};

tests/source/imports/imports_granularity_default-with-dups.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ use crate::lexer::{tokens::TokenData};
44
use crate::lexer::self;
55
use crate::lexer::{self};
66
use crate::lexer::{self, tokens::TokenData};
7+
8+
use a::{b::c, d::e, d::f};
9+
#[cfg(unix)]
10+
use a::{b::c, d::e, d::f};

tests/source/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,11 @@ use crate::lexer;
1111
use crate::lexer;
1212
use crate::lexer::{self};
1313
use crate::lexer::{self, tokens::TokenData};
14+
15+
use crate::{b::c, d::e, d::f};
16+
#[cfg(unix)]
17+
use crate::{b::c, d::e, d::f};
18+
#[cfg(windows)]
19+
use crate::{b::c, d::e, d::f};
20+
// my comment
21+
use crate::b;

tests/source/imports/imports_granularity_item-with-dups.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ use crate::lexer;
99
use crate::lexer;
1010
use crate::lexer::{self};
1111
use crate::lexer::{self, tokens::TokenData};
12+
#[cfg(unix)]
13+
use crate::lexer;

tests/source/imports/imports_granularity_item.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,11 @@ use b::v::{
3232
};
3333
use b::t::{/* Before b::t::self */ self};
3434
use b::c;
35+
36+
use c::{a::b, c::d, c::e};
37+
#[cfg(unix)]
38+
use c::{a::b, c::d, c::e};
39+
#[cfg(windows)]
40+
use c::{a::b, c::d, c::e};
41+
// my comment
42+
use c::a::b;

tests/source/imports/imports_granularity_module.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,9 @@ use c;
5050
use d;
5151

5252
use {library1, library2 as lib2, library3};
53+
54+
#[my_attribute]
55+
use a::{b::c,d::e,d::f};
56+
57+
/// Some doc comment
58+
use a::{b::c,d::e,d::f};

tests/target/imports/imports_granularity_crate.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,16 @@ use b::{
5757
/* Before b::l group */ l::{self, m, n::o, p::*},
5858
q,
5959
};
60+
61+
// https://github.com/rust-lang/rustfmt/issues/6666
62+
#[cfg(true)]
63+
use a::{
64+
b::c,
65+
d::{e, f},
66+
};
67+
68+
#[my_attribute]
69+
use a::{b::c, d::e, d::f};
70+
71+
/// Some doc comment
72+
use a::{b::c, d::e, d::f};

tests/target/imports/imports_granularity_default-with-dups.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ use crate::lexer::tokens::TokenData;
44
use crate::lexer::tokens::TokenData;
55
use crate::lexer::{self};
66
use crate::lexer::{self, tokens::TokenData};
7+
8+
use a::{b::c, d::e, d::f};
9+
#[cfg(unix)]
10+
use a::{b::c, d::e, d::f};

tests/target/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,20 @@
55
use crate::lexer;
66
use crate::lexer::tokens::TokenData;
77
use crate::lexer::{self};
8+
use crate::b::c;
9+
use crate::d::e;
10+
use crate::d::f;
11+
#[cfg(unix)]
12+
use crate::b::c;
13+
#[cfg(unix)]
14+
use crate::d::e;
15+
#[cfg(unix)]
16+
use crate::d::f;
17+
#[cfg(windows)]
18+
use crate::b::c;
19+
#[cfg(windows)]
20+
use crate::d::e;
21+
#[cfg(windows)]
22+
use crate::d::f;
23+
// my comment
24+
use crate::b;

0 commit comments

Comments
 (0)