about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-10-13 14:59:37 +0000
committerGitHub <noreply@github.com>2020-10-13 14:59:37 +0000
commit5091b5e9739a283329b475cab84a83117eb5814a (patch)
treef8e3bc969b502075cf1157fe33fc044d204cb022
parent2d79bb9413b3e30d15d70b49ca19fcf47a97e592 (diff)
parent2620b8d42f2d9c41ead1af518158691840141583 (diff)
downloadrust-5091b5e9739a283329b475cab84a83117eb5814a.tar.gz
rust-5091b5e9739a283329b475cab84a83117eb5814a.zip
Merge #6209
6209: Fix MergeBehaviour::Full/Last not working when merging nested long paths r=matklad a=Veykril

Prior to this inserting `std::foo::bar::Baz` with a nested import containing a multi segment path like `use std::{foo::bar::Qux};` present would result in `use std::{foo::bar::Baz, foo::bar::Qux};` with Full/Last Mergebehaviour.

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
-rw-r--r--crates/assists/src/handlers/replace_qualified_name_with_use.rs2
-rw-r--r--crates/assists/src/utils/insert_use.rs35
2 files changed, 33 insertions, 4 deletions
diff --git a/crates/assists/src/handlers/replace_qualified_name_with_use.rs b/crates/assists/src/handlers/replace_qualified_name_with_use.rs
index 74afc123b9b..e95b971a448 100644
--- a/crates/assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/assists/src/handlers/replace_qualified_name_with_use.rs
@@ -393,7 +393,7 @@ impl std::fmt::Display<|> for Foo {
 }
 ",
             r"
-use std::fmt::{Display, nested::Debug};
+use std::fmt::{nested::Debug, Display};
 
 impl Display for Foo {
 }
diff --git a/crates/assists/src/utils/insert_use.rs b/crates/assists/src/utils/insert_use.rs
index f6025c99a14..bfd457d18f7 100644
--- a/crates/assists/src/utils/insert_use.rs
+++ b/crates/assists/src/utils/insert_use.rs
@@ -200,7 +200,18 @@ fn recursive_merge(
             return None;
         }
         let rhs_path = rhs_t.path();
-        match use_trees.binary_search_by(|p| path_cmp_bin_search(p.path(), rhs_path.clone())) {
+        match use_trees.binary_search_by(|lhs_t| {
+            let (lhs_t, rhs_t) = match lhs_t
+                .path()
+                .zip(rhs_path.clone())
+                .and_then(|(lhs, rhs)| common_prefix(&lhs, &rhs))
+            {
+                Some((lhs_p, rhs_p)) => (lhs_t.split_prefix(&lhs_p), rhs_t.split_prefix(&rhs_p)),
+                None => (lhs_t.clone(), rhs_t.clone()),
+            };
+
+            path_cmp_bin_search(lhs_t.path(), rhs_t.path())
+        }) {
             Ok(idx) => {
                 let lhs_t = &mut use_trees[idx];
                 let lhs_path = lhs_t.path()?;
@@ -327,11 +338,11 @@ fn path_cmp_for_sort(a: Option<ast::Path>, b: Option<ast::Path>) -> Ordering {
 
 /// Path comparison func for binary searching for merging.
 fn path_cmp_bin_search(lhs: Option<ast::Path>, rhs: Option<ast::Path>) -> Ordering {
-    match (lhs, rhs) {
+    match (lhs.and_then(|path| path.segment()), rhs.and_then(|path| path.segment())) {
         (None, None) => Ordering::Equal,
         (None, Some(_)) => Ordering::Less,
         (Some(_), None) => Ordering::Greater,
-        (Some(ref a), Some(ref b)) => path_cmp_short(a, b),
+        (Some(ref a), Some(ref b)) => path_segment_cmp(a, b),
     }
 }
 
@@ -802,6 +813,24 @@ use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
     }
 
     #[test]
+    fn merge_groups_full_nested_long() {
+        check_full(
+            "std::foo::bar::Baz",
+            r"use std::{foo::bar::Qux};",
+            r"use std::{foo::bar::{Baz, Qux}};",
+        );
+    }
+
+    #[test]
+    fn merge_groups_last_nested_long() {
+        check_full(
+            "std::foo::bar::Baz",
+            r"use std::{foo::bar::Qux};",
+            r"use std::{foo::bar::{Baz, Qux}};",
+        );
+    }
+
+    #[test]
     fn merge_groups_skip_pub() {
         check_full(
             "std::io",