Merge imports fix (#3753)
This commit is contained in:
parent
c26c0e5abf
commit
ef00f74ce3
3 changed files with 64 additions and 36 deletions
|
|
@ -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 {
|
||||
|
|
@ -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!(
|
||||
|
|
|
|||
16
tests/source/issue-3750.rs
Normal file
16
tests/source/issue-3750.rs
Normal file
|
|
@ -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
tests/target/issue-3750.rs
Normal file
15
tests/target/issue-3750.rs
Normal file
|
|
@ -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();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue