From 8e906b05121a42518f0319950f507653e0913824 Mon Sep 17 00:00:00 2001 From: Valentine Valyaeff Date: Sun, 25 Aug 2019 15:56:16 +0300 Subject: [PATCH 1/2] Refactor imports::merge_rest --- src/imports.rs | 56 +++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/imports.rs b/src/imports.rs index a85889884ca..2782e788d2b 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -573,56 +573,56 @@ 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 { - 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], len: usize) -> Option> { + if a.len() == len && b.len() == len { return None; } - if a_rest.is_empty() { - return Some(UseSegment::List(vec![ + if a.len() == len { + let mut new_path = b[..len].to_vec(); + new_path.push(UseSegment::List(vec![ UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP), - UseTree::from_path(b_rest.to_vec(), DUMMY_SP), + UseTree::from_path(b[len..].to_vec(), DUMMY_SP), ])); + return Some(new_path); } - if b_rest.is_empty() { - return Some(UseSegment::List(vec![ + if b.len() == len { + let mut new_path = b[..len].to_vec(); + new_path.push(UseSegment::List(vec![ UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP), - UseTree::from_path(a_rest.to_vec(), DUMMY_SP), + UseTree::from_path(a[len..].to_vec(), DUMMY_SP), ])); + return Some(new_path); } - 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)); + if let UseSegment::List(mut list) = a[len].clone() { + let mut new_path = b[..len].to_vec(); + merge_use_trees_inner(&mut list, UseTree::from_path(b[len..].to_vec(), DUMMY_SP)); list.sort(); - return Some(UseSegment::List(list)); + new_path.push(UseSegment::List(list)); + return Some(new_path); } + let mut new_path = b[..len].to_vec(); 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)) + new_path.push(UseSegment::List(list)); + Some(new_path) } impl PartialOrd for UseSegment { From 693856922897bee76b44fab6370a7375a18a0581 Mon Sep 17 00:00:00 2001 From: Valentine Valyaeff Date: Sun, 25 Aug 2019 16:32:50 +0300 Subject: [PATCH 2/2] Fix #3750 --- src/imports.rs | 47 ++++++++++++++++++-------------------- tests/source/issue-3750.rs | 16 +++++++++++++ tests/target/issue-3750.rs | 15 ++++++++++++ 3 files changed, 53 insertions(+), 25 deletions(-) create mode 100644 tests/source/issue-3750.rs create mode 100644 tests/target/issue-3750.rs diff --git a/src/imports.rs b/src/imports.rs index 2782e788d2b..9fd541c61d8 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -588,39 +588,36 @@ impl UseTree { } } -fn merge_rest(a: &[UseSegment], b: &[UseSegment], len: usize) -> Option> { +fn merge_rest(a: &[UseSegment], b: &[UseSegment], mut len: usize) -> Option> { if a.len() == len && b.len() == len { return None; } - if a.len() == len { - let mut new_path = b[..len].to_vec(); - new_path.push(UseSegment::List(vec![ - UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP), - UseTree::from_path(b[len..].to_vec(), DUMMY_SP), - ])); - return Some(new_path); - } - if b.len() == len { - let mut new_path = b[..len].to_vec(); - new_path.push(UseSegment::List(vec![ - UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP), - UseTree::from_path(a[len..].to_vec(), DUMMY_SP), - ])); - return Some(new_path); - } - if let UseSegment::List(mut list) = a[len].clone() { - let mut new_path = b[..len].to_vec(); - merge_use_trees_inner(&mut list, UseTree::from_path(b[len..].to_vec(), DUMMY_SP)); - list.sort(); - new_path.push(UseSegment::List(list)); - return Some(new_path); + 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 new_path = b[..len].to_vec(); let mut list = vec![ UseTree::from_path(a[len..].to_vec(), DUMMY_SP), 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)); Some(new_path) } @@ -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!( diff --git a/tests/source/issue-3750.rs b/tests/source/issue-3750.rs new file mode 100644 index 00000000000..e11d9ab062a --- /dev/null +++ b/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(); +} diff --git a/tests/target/issue-3750.rs b/tests/target/issue-3750.rs new file mode 100644 index 00000000000..93d4dc6df25 --- /dev/null +++ b/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(); +}