Skip to content

Commit 9fd2c27

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 ced5993 commit 9fd2c27

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

@@ -123,7 +123,7 @@ pub(crate) struct UseTree {
123123

124124
impl PartialEq for UseTree {
125125
fn eq(&self, other: &UseTree) -> bool {
126-
self.path == other.path
126+
self.path == other.path && !self.has_attrs() && !other.has_attrs()
127127
}
128128
}
129129
impl Eq for UseTree {}
@@ -226,13 +226,19 @@ pub(crate) fn normalize_use_trees_with_granularity(
226226

227227
let mut result = Vec::with_capacity(use_trees.len());
228228
for use_tree in use_trees {
229-
if use_tree.contains_comment() || use_tree.attrs.is_some() {
229+
if use_tree.contains_comment() || use_tree.has_attrs_disallow_outer_style() {
230230
result.push(use_tree);
231231
continue;
232232
}
233+
let attrs = use_tree.attrs.clone();
234+
let result_buf = if attrs.is_some() {
235+
&mut vec![]
236+
} else {
237+
&mut result
238+
};
233239

234240
for mut flattened in use_tree.flatten(import_granularity) {
235-
if let Some(tree) = result
241+
if let Some(tree) = result_buf
236242
.iter_mut()
237243
.find(|tree| tree.share_prefix(&flattened, merge_by))
238244
{
@@ -242,9 +248,19 @@ pub(crate) fn normalize_use_trees_with_granularity(
242248
if merge_by == SharedPrefix::Module {
243249
flattened = flattened.nest_trailing_self();
244250
}
245-
result.push(flattened);
251+
result_buf.push(flattened);
246252
}
247253
}
254+
if let Some(attrs) = attrs {
255+
let result_buf: Vec<_> = result_buf
256+
.drain(..)
257+
.map(|mut use_tree| {
258+
use_tree.attrs = Some(attrs.clone());
259+
use_tree
260+
})
261+
.collect();
262+
result.extend(result_buf);
263+
}
248264
}
249265
result
250266
}
@@ -552,7 +568,7 @@ impl UseTree {
552568

553569
// Remove foo::{} or self without attributes.
554570
match last.kind {
555-
_ if self.attrs.is_some() => (),
571+
_ if self.has_attrs() => (),
556572
UseSegmentKind::List(ref list) if list.is_empty() => {
557573
self.path = vec![];
558574
return self;
@@ -650,6 +666,17 @@ impl UseTree {
650666
self.has_comment() || self.path.iter().any(|path| path.contains_comment())
651667
}
652668

669+
fn has_attrs(&self) -> bool {
670+
self.attrs.is_some()
671+
}
672+
673+
fn has_attrs_disallow_outer_style(&self) -> bool {
674+
!self.attrs.iter().flatten().all(|attr| match &attr.kind {
675+
ast::AttrKind::Normal(attr) => attr.item.is_valid_for_outer_style(),
676+
ast::AttrKind::DocComment(..) => false,
677+
})
678+
}
679+
653680
fn same_visibility(&self, other: &UseTree) -> bool {
654681
match (&self.visibility, &other.visibility) {
655682
(
@@ -675,7 +702,8 @@ impl UseTree {
675702
fn share_prefix(&self, other: &UseTree, shared_prefix: SharedPrefix) -> bool {
676703
if self.path.is_empty()
677704
|| other.path.is_empty()
678-
|| self.attrs.is_some()
705+
|| self.has_attrs()
706+
|| other.has_attrs()
679707
|| self.contains_comment()
680708
|| !self.same_visibility(other)
681709
{
@@ -692,7 +720,8 @@ impl UseTree {
692720
}
693721

694722
fn flatten(self, import_granularity: ImportGranularity) -> Vec<UseTree> {
695-
if self.path.is_empty() || self.contains_comment() {
723+
if self.path.is_empty() || self.contains_comment() || self.has_attrs_disallow_outer_style()
724+
{
696725
return vec![self];
697726
}
698727
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
@@ -45,3 +45,9 @@ use b::v::{
4545
};
4646
use b::t::{/* Before b::t::self */ self};
4747
use b::c;
48+
49+
#[my_attribute]
50+
use a::{b::c,d::e,d::f};
51+
52+
/// Some doc comment
53+
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)