Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #17622 - roife:fix-issue-17602, r=Veykril
fix: handle synonymous imports with different renaming in 'merge imports' fix #17602
bors 2024-07-19
parent fa3dd33 · parent 87a3ab4 · commit aa4768f
-rw-r--r--crates/ide-assists/src/handlers/merge_imports.rs69
-rw-r--r--crates/ide-db/src/imports/merge_imports.rs18
2 files changed, 82 insertions, 5 deletions
diff --git a/crates/ide-assists/src/handlers/merge_imports.rs b/crates/ide-assists/src/handlers/merge_imports.rs
index 7f751c93e4..4171230836 100644
--- a/crates/ide-assists/src/handlers/merge_imports.rs
+++ b/crates/ide-assists/src/handlers/merge_imports.rs
@@ -164,6 +164,7 @@ impl Merge for ast::UseTree {
}
}
+#[derive(Debug)]
enum Edit {
Remove(Either<ast::Use, ast::UseTree>),
Replace(SyntaxNode, SyntaxNode),
@@ -733,4 +734,72 @@ use std::{
r"use std::fmt::{Debug, Display};",
);
}
+
+ #[test]
+ fn test_merge_with_synonymous_imports_1() {
+ check_assist(
+ merge_imports,
+ r"
+mod top {
+ pub(crate) mod a {
+ pub(crate) struct A;
+ }
+ pub(crate) mod b {
+ pub(crate) struct B;
+ pub(crate) struct D;
+ }
+}
+
+use top::a::A;
+use $0top::b::{B, B as C};
+",
+ r"
+mod top {
+ pub(crate) mod a {
+ pub(crate) struct A;
+ }
+ pub(crate) mod b {
+ pub(crate) struct B;
+ pub(crate) struct D;
+ }
+}
+
+use top::{a::A, b::{B, B as C}};
+",
+ );
+ }
+
+ #[test]
+ fn test_merge_with_synonymous_imports_2() {
+ check_assist(
+ merge_imports,
+ r"
+mod top {
+ pub(crate) mod a {
+ pub(crate) struct A;
+ }
+ pub(crate) mod b {
+ pub(crate) struct B;
+ pub(crate) struct D;
+ }
+}
+
+use top::a::A;
+use $0top::b::{B as D, B as C};
+",
+ r"
+mod top {
+ pub(crate) mod a {
+ pub(crate) struct A;
+ }
+ pub(crate) mod b {
+ pub(crate) struct B;
+ pub(crate) struct D;
+ }
+}
+
+use top::{a::A, b::{B as D, B as C}};
+",
+ );
+ }
}
diff --git a/crates/ide-db/src/imports/merge_imports.rs b/crates/ide-db/src/imports/merge_imports.rs
index 9cacb6b1a6..926fae0d31 100644
--- a/crates/ide-db/src/imports/merge_imports.rs
+++ b/crates/ide-db/src/imports/merge_imports.rs
@@ -93,17 +93,25 @@ fn try_merge_trees_mut(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehav
let rhs_path = rhs.path()?;
let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?;
- if !(lhs.is_simple_path()
+ if lhs.is_simple_path()
&& rhs.is_simple_path()
&& lhs_path == lhs_prefix
- && rhs_path == rhs_prefix)
+ && rhs_path == rhs_prefix
{
- lhs.split_prefix(&lhs_prefix);
- rhs.split_prefix(&rhs_prefix);
- } else {
+ // we can't merge if the renames are different (`A as a` and `A as b`),
+ // and we can safely return here
+ let lhs_name = lhs.rename().and_then(|lhs_name| lhs_name.name());
+ let rhs_name = rhs.rename().and_then(|rhs_name| rhs_name.name());
+ if lhs_name != rhs_name {
+ return None;
+ }
+
ted::replace(lhs.syntax(), rhs.syntax());
// we can safely return here, in this case `recursive_merge` doesn't do anything
return Some(());
+ } else {
+ lhs.split_prefix(&lhs_prefix);
+ rhs.split_prefix(&rhs_prefix);
}
}
recursive_merge(lhs, rhs, merge)