Skip to content

Commit a13b236

Browse files
committed
Merge import.rs changes from latest master
1 parent a5b3328 commit a13b236

File tree

3 files changed

+139
-29
lines changed

3 files changed

+139
-29
lines changed

src/formatting/imports.rs

Lines changed: 120 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ impl UseSegment {
160160
}
161161
}
162162

163-
pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
163+
pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>, merge_by: SharedPrefix) -> Vec<UseTree> {
164164
let mut result = Vec::with_capacity(use_trees.len());
165165
for use_tree in use_trees {
166166
if use_tree.has_comment() || use_tree.attrs.is_some() {
@@ -169,8 +169,11 @@ pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
169169
}
170170

171171
for flattened in use_tree.flatten() {
172-
if let Some(tree) = result.iter_mut().find(|tree| tree.share_prefix(&flattened)) {
173-
tree.merge(&flattened);
172+
if let Some(tree) = result
173+
.iter_mut()
174+
.find(|tree| tree.share_prefix(&flattened, merge_by))
175+
{
176+
tree.merge(&flattened, merge_by);
174177
} else {
175178
result.push(flattened);
176179
}
@@ -179,6 +182,24 @@ pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
179182
result
180183
}
181184

185+
pub(crate) fn flatten_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
186+
use_trees
187+
.into_iter()
188+
.flat_map(UseTree::flatten)
189+
.map(|mut tree| {
190+
// If a path ends in `::self`, rewrite it to `::{self}`.
191+
if let Some(UseSegment::Slf(..)) = tree.path.last() {
192+
let self_segment = tree.path.pop().unwrap();
193+
tree.path.push(UseSegment::List(vec![UseTree::from_path(
194+
vec![self_segment],
195+
DUMMY_SP,
196+
)]));
197+
}
198+
tree
199+
})
200+
.collect()
201+
}
202+
182203
impl fmt::Debug for UseTree {
183204
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184205
fmt::Display::fmt(self, f)
@@ -333,7 +354,7 @@ impl UseTree {
333354
};
334355

335356
let leading_modsep =
336-
context.config.edition() == Edition::Edition2018 && a.prefix.is_global();
357+
context.config.edition() >= Edition::Edition2018 && a.prefix.is_global();
337358

338359
let mut modsep = leading_modsep;
339360

@@ -564,15 +585,20 @@ impl UseTree {
564585
}
565586
}
566587

567-
fn share_prefix(&self, other: &UseTree) -> bool {
588+
fn share_prefix(&self, other: &UseTree, shared_prefix: SharedPrefix) -> bool {
568589
if self.path.is_empty()
569590
|| other.path.is_empty()
570591
|| self.attrs.is_some()
571592
|| !self.same_visibility(other)
572593
{
573594
false
574595
} else {
575-
self.path[0] == other.path[0]
596+
match shared_prefix {
597+
SharedPrefix::Crate => self.path[0] == other.path[0],
598+
SharedPrefix::Module => {
599+
self.path[..self.path.len() - 1] == other.path[..other.path.len() - 1]
600+
}
601+
}
576602
}
577603
}
578604

@@ -606,7 +632,7 @@ impl UseTree {
606632
}
607633
}
608634

609-
fn merge(&mut self, other: &UseTree) {
635+
fn merge(&mut self, other: &UseTree, merge_by: SharedPrefix) {
610636
let mut prefix = 0;
611637
for (a, b) in self.path.iter().zip(other.path.iter()) {
612638
if *a == *b {
@@ -615,20 +641,30 @@ impl UseTree {
615641
break;
616642
}
617643
}
618-
if let Some(new_path) = merge_rest(&self.path, &other.path, prefix) {
644+
if let Some(new_path) = merge_rest(&self.path, &other.path, prefix, merge_by) {
619645
self.path = new_path;
620646
self.span = self.span.to(other.span);
621647
}
622648
}
623649
}
624650

625-
fn merge_rest(a: &[UseSegment], b: &[UseSegment], mut len: usize) -> Option<Vec<UseSegment>> {
651+
fn merge_rest(
652+
a: &[UseSegment],
653+
b: &[UseSegment],
654+
mut len: usize,
655+
merge_by: SharedPrefix,
656+
) -> Option<Vec<UseSegment>> {
626657
if a.len() == len && b.len() == len {
627658
return None;
628659
}
629660
if a.len() != len && b.len() != len {
630-
if let UseSegment::List(mut list) = a[len].clone() {
631-
merge_use_trees_inner(&mut list, UseTree::from_path(b[len..].to_vec(), DUMMY_SP));
661+
if let UseSegment::List(ref list) = a[len] {
662+
let mut list = list.clone();
663+
merge_use_trees_inner(
664+
&mut list,
665+
UseTree::from_path(b[len..].to_vec(), DUMMY_SP),
666+
merge_by,
667+
);
632668
let mut new_path = b[..len].to_vec();
633669
new_path.push(UseSegment::List(list));
634670
return Some(new_path);
@@ -655,17 +691,19 @@ fn merge_rest(a: &[UseSegment], b: &[UseSegment], mut len: usize) -> Option<Vec<
655691
Some(new_path)
656692
}
657693

658-
fn merge_use_trees_inner(trees: &mut Vec<UseTree>, use_tree: UseTree) {
659-
let similar_trees = trees.iter_mut().filter(|tree| tree.share_prefix(&use_tree));
660-
if use_tree.path.len() == 1 {
694+
fn merge_use_trees_inner(trees: &mut Vec<UseTree>, use_tree: UseTree, merge_by: SharedPrefix) {
695+
let similar_trees = trees
696+
.iter_mut()
697+
.filter(|tree| tree.share_prefix(&use_tree, merge_by));
698+
if use_tree.path.len() == 1 && merge_by == SharedPrefix::Crate {
661699
if let Some(tree) = similar_trees.min_by_key(|tree| tree.path.len()) {
662700
if tree.path.len() == 1 {
663701
return;
664702
}
665703
}
666704
} else if let Some(tree) = similar_trees.max_by_key(|tree| tree.path.len()) {
667705
if tree.path.len() > 1 {
668-
tree.merge(&use_tree);
706+
tree.merge(&use_tree, merge_by);
669707
return;
670708
}
671709
}
@@ -868,6 +906,12 @@ impl Rewrite for UseTree {
868906
}
869907
}
870908

909+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
910+
pub(crate) enum SharedPrefix {
911+
Crate,
912+
Module,
913+
}
914+
871915
#[cfg(test)]
872916
mod test {
873917
use super::*;
@@ -1014,44 +1058,91 @@ mod test {
10141058
}
10151059
}
10161060

1017-
#[test]
1018-
fn test_use_tree_merge() {
1019-
macro_rules! test_merge {
1020-
([$($input:expr),* $(,)*], [$($output:expr),* $(,)*]) => {
1021-
assert_eq!(
1022-
merge_use_trees(parse_use_trees!($($input,)*)),
1023-
parse_use_trees!($($output,)*),
1024-
);
1025-
}
1061+
macro_rules! test_merge {
1062+
($by:ident, [$($input:expr),* $(,)*], [$($output:expr),* $(,)*]) => {
1063+
assert_eq!(
1064+
merge_use_trees(parse_use_trees!($($input,)*), SharedPrefix::$by),
1065+
parse_use_trees!($($output,)*),
1066+
);
10261067
}
1068+
}
10271069

1028-
test_merge!(["a::b::{c, d}", "a::b::{e, f}"], ["a::b::{c, d, e, f}"]);
1029-
test_merge!(["a::b::c", "a::b"], ["a::{b, b::c}"]);
1030-
test_merge!(["a::b", "a::b"], ["a::b"]);
1031-
test_merge!(["a", "a::b", "a::b::c"], ["a::{self, b, b::c}"]);
1070+
#[test]
1071+
fn test_use_tree_merge_crate() {
1072+
test_merge!(
1073+
Crate,
1074+
["a::b::{c, d}", "a::b::{e, f}"],
1075+
["a::b::{c, d, e, f}"]
1076+
);
1077+
test_merge!(Crate, ["a::b::c", "a::b"], ["a::{b, b::c}"]);
1078+
test_merge!(Crate, ["a::b", "a::b"], ["a::b"]);
1079+
test_merge!(Crate, ["a", "a::b", "a::b::c"], ["a::{self, b, b::c}"]);
10321080
test_merge!(
1081+
Crate,
10331082
["a", "a::b", "a::b::c", "a::b::c::d"],
10341083
["a::{self, b, b::{c, c::d}}"]
10351084
);
1036-
test_merge!(["a", "a::b", "a::b::c", "a::b"], ["a::{self, b, b::c}"]);
10371085
test_merge!(
1086+
Crate,
1087+
["a", "a::b", "a::b::c", "a::b"],
1088+
["a::{self, b, b::c}"]
1089+
);
1090+
test_merge!(
1091+
Crate,
10381092
["a::{b::{self, c}, d::e}", "a::d::f"],
10391093
["a::{b::{self, c}, d::{e, f}}"]
10401094
);
10411095
test_merge!(
1096+
Crate,
10421097
["a::d::f", "a::{b::{self, c}, d::e}"],
10431098
["a::{b::{self, c}, d::{e, f}}"]
10441099
);
10451100
test_merge!(
1101+
Crate,
10461102
["a::{c, d, b}", "a::{d, e, b, a, f}", "a::{f, g, c}"],
10471103
["a::{a, b, c, d, e, f, g}"]
10481104
);
10491105
test_merge!(
1106+
Crate,
10501107
["a::{self}", "b::{self as foo}"],
10511108
["a::{self}", "b::{self as foo}"]
10521109
);
10531110
}
10541111

1112+
#[test]
1113+
fn test_use_tree_merge_module() {
1114+
test_merge!(
1115+
Module,
1116+
["foo::b", "foo::{a, c, d::e}"],
1117+
["foo::{a, b, c}", "foo::d::e"]
1118+
);
1119+
1120+
test_merge!(
1121+
Module,
1122+
["foo::{a::b, a::c, d::e, d::f}"],
1123+
["foo::a::{b, c}", "foo::d::{e, f}"]
1124+
);
1125+
}
1126+
1127+
#[test]
1128+
fn test_flatten_use_trees() {
1129+
assert_eq!(
1130+
flatten_use_trees(parse_use_trees!["foo::{a::{b, c}, d::e}"]),
1131+
parse_use_trees!["foo::a::b", "foo::a::c", "foo::d::e"]
1132+
);
1133+
1134+
assert_eq!(
1135+
flatten_use_trees(parse_use_trees!["foo::{self, a, b::{c, d}, e::*}"]),
1136+
parse_use_trees![
1137+
"foo::{self}",
1138+
"foo::a",
1139+
"foo::b::c",
1140+
"foo::b::d",
1141+
"foo::e::*"
1142+
]
1143+
);
1144+
}
1145+
10551146
#[test]
10561147
fn test_use_tree_flatten() {
10571148
assert_eq!(
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// rustfmt-imports_granularity: Item
2+
3+
use a::{b, c, d};
4+
use a::{f::g, h::{i, j}};
5+
use a::{l::{self, m, n::o, p::*}};
6+
use a::q::{self};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// rustfmt-imports_granularity: Item
2+
3+
use a::b;
4+
use a::c;
5+
use a::d;
6+
use a::f::g;
7+
use a::h::i;
8+
use a::h::j;
9+
use a::l::m;
10+
use a::l::n::o;
11+
use a::l::p::*;
12+
use a::l::{self};
13+
use a::q::{self};

0 commit comments

Comments
 (0)