Skip to content

Commit ef00f74

Browse files
valfftopecongiro
authored andcommitted
Merge imports fix (#3753)
1 parent c26c0e5 commit ef00f74

File tree

3 files changed

+64
-36
lines changed

3 files changed

+64
-36
lines changed

src/imports.rs

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -573,56 +573,53 @@ impl UseTree {
573573
}
574574

575575
fn merge(&mut self, other: &UseTree) {
576-
let mut new_path = vec![];
577-
for (a, b) in self
578-
.path
579-
.clone()
580-
.iter_mut()
581-
.zip(other.path.clone().into_iter())
582-
{
583-
if *a == b {
584-
new_path.push(b);
576+
let mut prefix = 0;
577+
for (a, b) in self.path.iter().zip(other.path.iter()) {
578+
if *a == *b {
579+
prefix += 1;
585580
} else {
586581
break;
587582
}
588583
}
589-
if let Some(merged) = merge_rest(&self.path, &other.path, new_path.len()) {
590-
new_path.push(merged);
584+
if let Some(new_path) = merge_rest(&self.path, &other.path, prefix) {
585+
self.path = new_path;
591586
self.span = self.span.to(other.span);
592587
}
593-
self.path = new_path;
594588
}
595589
}
596590

597-
fn merge_rest(a: &[UseSegment], b: &[UseSegment], len: usize) -> Option<UseSegment> {
598-
let a_rest = &a[len..];
599-
let b_rest = &b[len..];
600-
if a_rest.is_empty() && b_rest.is_empty() {
591+
fn merge_rest(a: &[UseSegment], b: &[UseSegment], mut len: usize) -> Option<Vec<UseSegment>> {
592+
if a.len() == len && b.len() == len {
601593
return None;
602594
}
603-
if a_rest.is_empty() {
604-
return Some(UseSegment::List(vec![
605-
UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP),
606-
UseTree::from_path(b_rest.to_vec(), DUMMY_SP),
607-
]));
608-
}
609-
if b_rest.is_empty() {
610-
return Some(UseSegment::List(vec![
611-
UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP),
612-
UseTree::from_path(a_rest.to_vec(), DUMMY_SP),
613-
]));
614-
}
615-
if let UseSegment::List(mut list) = a_rest[0].clone() {
616-
merge_use_trees_inner(&mut list, UseTree::from_path(b_rest.to_vec(), DUMMY_SP));
617-
list.sort();
618-
return Some(UseSegment::List(list));
595+
if a.len() != len && b.len() != len {
596+
if let UseSegment::List(mut list) = a[len].clone() {
597+
merge_use_trees_inner(&mut list, UseTree::from_path(b[len..].to_vec(), DUMMY_SP));
598+
list.sort();
599+
let mut new_path = b[..len].to_vec();
600+
new_path.push(UseSegment::List(list));
601+
return Some(new_path);
602+
}
603+
} else if len == 1 {
604+
let rest = if a.len() == len { &b[1..] } else { &a[1..] };
605+
return Some(vec![
606+
b[0].clone(),
607+
UseSegment::List(vec![
608+
UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP),
609+
UseTree::from_path(rest.to_vec(), DUMMY_SP),
610+
]),
611+
]);
612+
} else {
613+
len -= 1;
619614
}
620615
let mut list = vec![
621-
UseTree::from_path(a_rest.to_vec(), DUMMY_SP),
622-
UseTree::from_path(b_rest.to_vec(), DUMMY_SP),
616+
UseTree::from_path(a[len..].to_vec(), DUMMY_SP),
617+
UseTree::from_path(b[len..].to_vec(), DUMMY_SP),
623618
];
624619
list.sort();
625-
Some(UseSegment::List(list))
620+
let mut new_path = b[..len].to_vec();
621+
new_path.push(UseSegment::List(list));
622+
Some(new_path)
626623
}
627624

628625
impl PartialOrd for UseSegment {
@@ -989,7 +986,7 @@ mod test {
989986
}
990987

991988
test_merge!(["a::b::{c, d}", "a::b::{e, f}"], ["a::b::{c, d, e, f}"]);
992-
test_merge!(["a::b::c", "a::b"], ["a::b::{self, c}"]);
989+
test_merge!(["a::b::c", "a::b"], ["a::{b, b::c}"]);
993990
test_merge!(["a::b", "a::b"], ["a::b"]);
994991
test_merge!(["a", "a::b", "a::b::c"], ["a::{self, b::{self, c}}"]);
995992
test_merge!(

tests/source/issue-3750.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// rustfmt-merge_imports: true
2+
3+
pub mod foo {
4+
pub mod bar {
5+
pub struct Bar;
6+
}
7+
8+
pub fn bar() {}
9+
}
10+
11+
use foo::bar;
12+
use foo::bar::Bar;
13+
14+
fn main() {
15+
bar();
16+
}

tests/target/issue-3750.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// rustfmt-merge_imports: true
2+
3+
pub mod foo {
4+
pub mod bar {
5+
pub struct Bar;
6+
}
7+
8+
pub fn bar() {}
9+
}
10+
11+
use foo::{bar, bar::Bar};
12+
13+
fn main() {
14+
bar();
15+
}

0 commit comments

Comments
 (0)