Skip to content

Commit

Permalink
Merge imports fix (#3753)
Browse files Browse the repository at this point in the history
  • Loading branch information
valff authored and topecongiro committed Aug 27, 2019
1 parent c26c0e5 commit ef00f74
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 36 deletions.
69 changes: 33 additions & 36 deletions src/imports.rs
Expand Up @@ -573,56 +573,53 @@ impl UseTree {
}

fn merge(&mut self, other: &UseTree) {
let mut new_path = vec![];
for (a, b) in self
.path
.clone()
.iter_mut()
.zip(other.path.clone().into_iter())
{
if *a == b {
new_path.push(b);
let mut prefix = 0;
for (a, b) in self.path.iter().zip(other.path.iter()) {
if *a == *b {
prefix += 1;
} else {
break;
}
}
if let Some(merged) = merge_rest(&self.path, &other.path, new_path.len()) {
new_path.push(merged);
if let Some(new_path) = merge_rest(&self.path, &other.path, prefix) {
self.path = new_path;
self.span = self.span.to(other.span);
}
self.path = new_path;
}
}

fn merge_rest(a: &[UseSegment], b: &[UseSegment], len: usize) -> Option<UseSegment> {
let a_rest = &a[len..];
let b_rest = &b[len..];
if a_rest.is_empty() && b_rest.is_empty() {
fn merge_rest(a: &[UseSegment], b: &[UseSegment], mut len: usize) -> Option<Vec<UseSegment>> {
if a.len() == len && b.len() == len {
return None;
}
if a_rest.is_empty() {
return Some(UseSegment::List(vec![
UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP),
UseTree::from_path(b_rest.to_vec(), DUMMY_SP),
]));
}
if b_rest.is_empty() {
return Some(UseSegment::List(vec![
UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP),
UseTree::from_path(a_rest.to_vec(), DUMMY_SP),
]));
}
if let UseSegment::List(mut list) = a_rest[0].clone() {
merge_use_trees_inner(&mut list, UseTree::from_path(b_rest.to_vec(), DUMMY_SP));
list.sort();
return Some(UseSegment::List(list));
if a.len() != len && b.len() != len {
if let UseSegment::List(mut list) = a[len].clone() {
merge_use_trees_inner(&mut list, UseTree::from_path(b[len..].to_vec(), DUMMY_SP));
list.sort();
let mut new_path = b[..len].to_vec();
new_path.push(UseSegment::List(list));
return Some(new_path);
}
} else if len == 1 {
let rest = if a.len() == len { &b[1..] } else { &a[1..] };
return Some(vec![
b[0].clone(),
UseSegment::List(vec![
UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP),
UseTree::from_path(rest.to_vec(), DUMMY_SP),
]),
]);
} else {
len -= 1;
}
let mut list = vec![
UseTree::from_path(a_rest.to_vec(), DUMMY_SP),
UseTree::from_path(b_rest.to_vec(), DUMMY_SP),
UseTree::from_path(a[len..].to_vec(), DUMMY_SP),
UseTree::from_path(b[len..].to_vec(), DUMMY_SP),
];
list.sort();
Some(UseSegment::List(list))
let mut new_path = b[..len].to_vec();
new_path.push(UseSegment::List(list));
Some(new_path)
}

impl PartialOrd for UseSegment {
Expand Down Expand Up @@ -989,7 +986,7 @@ mod test {
}

test_merge!(["a::b::{c, d}", "a::b::{e, f}"], ["a::b::{c, d, e, f}"]);
test_merge!(["a::b::c", "a::b"], ["a::b::{self, c}"]);
test_merge!(["a::b::c", "a::b"], ["a::{b, b::c}"]);
test_merge!(["a::b", "a::b"], ["a::b"]);
test_merge!(["a", "a::b", "a::b::c"], ["a::{self, b::{self, c}}"]);
test_merge!(
Expand Down
16 changes: 16 additions & 0 deletions tests/source/issue-3750.rs
@@ -0,0 +1,16 @@
// rustfmt-merge_imports: true

pub mod foo {
pub mod bar {
pub struct Bar;
}

pub fn bar() {}
}

use foo::bar;
use foo::bar::Bar;

fn main() {
bar();
}
15 changes: 15 additions & 0 deletions tests/target/issue-3750.rs
@@ -0,0 +1,15 @@
// rustfmt-merge_imports: true

pub mod foo {
pub mod bar {
pub struct Bar;
}

pub fn bar() {}
}

use foo::{bar, bar::Bar};

fn main() {
bar();
}

0 comments on commit ef00f74

Please sign in to comment.