Skip to content

Commit ba0351a

Browse files
narpfelcalebcartwright
authored andcommitted
Preserve attributes for imports_granularity=Item
Fixes #5030
1 parent 4f3f87f commit ba0351a

File tree

4 files changed

+56
-24
lines changed

4 files changed

+56
-24
lines changed

Diff for: src/imports.rs

+39-13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_span::{
1010

1111
use crate::comment::combine_strs_with_missing_comments;
1212
use crate::config::lists::*;
13+
use crate::config::ImportGranularity;
1314
use crate::config::{Edition, IndentStyle};
1415
use crate::lists::{
1516
definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
@@ -182,15 +183,26 @@ impl UseSegment {
182183
}
183184
}
184185

185-
pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>, merge_by: SharedPrefix) -> Vec<UseTree> {
186+
pub(crate) fn regroup_use_trees(
187+
use_trees: Vec<UseTree>,
188+
import_granularity: ImportGranularity,
189+
) -> Vec<UseTree> {
190+
let merge_by = match import_granularity {
191+
ImportGranularity::Item => return flatten_use_trees(use_trees, ImportGranularity::Item),
192+
ImportGranularity::Preserve => return use_trees,
193+
ImportGranularity::Crate => SharedPrefix::Crate,
194+
ImportGranularity::Module => SharedPrefix::Module,
195+
ImportGranularity::One => SharedPrefix::One,
196+
};
197+
186198
let mut result = Vec::with_capacity(use_trees.len());
187199
for use_tree in use_trees {
188200
if use_tree.has_comment() || use_tree.attrs.is_some() {
189201
result.push(use_tree);
190202
continue;
191203
}
192204

193-
for mut flattened in use_tree.flatten() {
205+
for mut flattened in use_tree.flatten(import_granularity) {
194206
if let Some(tree) = result
195207
.iter_mut()
196208
.find(|tree| tree.share_prefix(&flattened, merge_by))
@@ -208,10 +220,13 @@ pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>, merge_by: SharedPrefix) -
208220
result
209221
}
210222

211-
pub(crate) fn flatten_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
223+
fn flatten_use_trees(
224+
use_trees: Vec<UseTree>,
225+
import_granularity: ImportGranularity,
226+
) -> Vec<UseTree> {
212227
use_trees
213228
.into_iter()
214-
.flat_map(UseTree::flatten)
229+
.flat_map(|tree| tree.flatten(import_granularity))
215230
.map(UseTree::nest_trailing_self)
216231
.collect()
217232
}
@@ -581,7 +596,7 @@ impl UseTree {
581596
}
582597
}
583598

584-
fn flatten(self) -> Vec<UseTree> {
599+
fn flatten(self, import_granularity: ImportGranularity) -> Vec<UseTree> {
585600
if self.path.is_empty() {
586601
return vec![self];
587602
}
@@ -595,15 +610,19 @@ impl UseTree {
595610
let prefix = &self.path[..self.path.len() - 1];
596611
let mut result = vec![];
597612
for nested_use_tree in list {
598-
for flattend in &mut nested_use_tree.clone().flatten() {
613+
for flattend in &mut nested_use_tree.clone().flatten(import_granularity) {
599614
let mut new_path = prefix.to_vec();
600615
new_path.append(&mut flattend.path);
601616
result.push(UseTree {
602617
path: new_path,
603618
span: self.span,
604619
list_item: None,
605620
visibility: self.visibility.clone(),
606-
attrs: None,
621+
// only retain attributes for `ImportGranularity::Item`
622+
attrs: match import_granularity {
623+
ImportGranularity::Item => self.attrs.clone(),
624+
_ => None,
625+
},
607626
});
608627
}
609628
}
@@ -951,7 +970,7 @@ impl Rewrite for UseTree {
951970
}
952971

953972
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
954-
pub(crate) enum SharedPrefix {
973+
enum SharedPrefix {
955974
Crate,
956975
Module,
957976
One,
@@ -1106,7 +1125,7 @@ mod test {
11061125
macro_rules! test_merge {
11071126
($by:ident, [$($input:expr),* $(,)*], [$($output:expr),* $(,)*]) => {
11081127
assert_eq!(
1109-
merge_use_trees(parse_use_trees!($($input,)*), SharedPrefix::$by),
1128+
regroup_use_trees(parse_use_trees!($($input,)*), ImportGranularity::$by),
11101129
parse_use_trees!($($output,)*),
11111130
);
11121131
}
@@ -1215,12 +1234,18 @@ mod test {
12151234
#[test]
12161235
fn test_flatten_use_trees() {
12171236
assert_eq!(
1218-
flatten_use_trees(parse_use_trees!["foo::{a::{b, c}, d::e}"]),
1237+
flatten_use_trees(
1238+
parse_use_trees!["foo::{a::{b, c}, d::e}"],
1239+
ImportGranularity::Item
1240+
),
12191241
parse_use_trees!["foo::a::b", "foo::a::c", "foo::d::e"]
12201242
);
12211243

12221244
assert_eq!(
1223-
flatten_use_trees(parse_use_trees!["foo::{self, a, b::{c, d}, e::*}"]),
1245+
flatten_use_trees(
1246+
parse_use_trees!["foo::{self, a, b::{c, d}, e::*}"],
1247+
ImportGranularity::Item
1248+
),
12241249
parse_use_trees![
12251250
"foo::{self}",
12261251
"foo::a",
@@ -1234,12 +1259,13 @@ mod test {
12341259
#[test]
12351260
fn test_use_tree_flatten() {
12361261
assert_eq!(
1237-
parse_use_tree("a::b::{c, d, e, f}").flatten(),
1262+
parse_use_tree("a::b::{c, d, e, f}").flatten(ImportGranularity::Item),
12381263
parse_use_trees!("a::b::c", "a::b::d", "a::b::e", "a::b::f",)
12391264
);
12401265

12411266
assert_eq!(
1242-
parse_use_tree("a::b::{c::{d, e, f}, g, h::{i, j, k}}").flatten(),
1267+
parse_use_tree("a::b::{c::{d, e, f}, g, h::{i, j, k}}")
1268+
.flatten(ImportGranularity::Item),
12431269
parse_use_trees![
12441270
"a::b::c::d",
12451271
"a::b::c::e",

Diff for: src/reorder.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use std::cmp::{Ord, Ordering};
1111
use rustc_ast::ast;
1212
use rustc_span::{symbol::sym, Span};
1313

14-
use crate::config::{Config, GroupImportsTactic, ImportGranularity};
15-
use crate::imports::{flatten_use_trees, merge_use_trees, SharedPrefix, UseSegment, UseTree};
14+
use crate::config::{Config, GroupImportsTactic};
15+
use crate::imports::{regroup_use_trees, UseSegment, UseTree};
1616
use crate::items::{is_mod_decl, rewrite_extern_crate, rewrite_mod};
1717
use crate::lists::{itemize_list, write_list, ListFormatting, ListItem};
1818
use crate::rewrite::RewriteContext;
@@ -107,15 +107,8 @@ fn rewrite_reorderable_or_regroupable_items(
107107
for (item, list_item) in normalized_items.iter_mut().zip(list_items) {
108108
item.list_item = Some(list_item.clone());
109109
}
110-
normalized_items = match context.config.imports_granularity() {
111-
ImportGranularity::Crate => merge_use_trees(normalized_items, SharedPrefix::Crate),
112-
ImportGranularity::Module => {
113-
merge_use_trees(normalized_items, SharedPrefix::Module)
114-
}
115-
ImportGranularity::Item => flatten_use_trees(normalized_items),
116-
ImportGranularity::One => merge_use_trees(normalized_items, SharedPrefix::One),
117-
ImportGranularity::Preserve => normalized_items,
118-
};
110+
normalized_items =
111+
regroup_use_trees(normalized_items, context.config.imports_granularity());
119112

120113
let mut regrouped_items = match context.config.group_imports() {
121114
GroupImportsTactic::Preserve | GroupImportsTactic::One => {

Diff for: tests/source/issue-5030.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// rustfmt-imports_granularity: Item
2+
3+
#[cfg(feature = "foo")]
4+
use std::collections::{
5+
HashMap,
6+
HashSet,
7+
};

Diff for: tests/target/issue-5030.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// rustfmt-imports_granularity: Item
2+
3+
#[cfg(feature = "foo")]
4+
use std::collections::HashMap;
5+
#[cfg(feature = "foo")]
6+
use std::collections::HashSet;

0 commit comments

Comments
 (0)