Skip to content

Commit 39ff560

Browse files
committed
Auto merge of rust-lang#17622 - roife:fix-issue-17602, r=Veykril
fix: handle synonymous imports with different renaming in 'merge imports' fix rust-lang#17602
2 parents 4667848 + be34840 commit 39ff560

File tree

2 files changed

+82
-5
lines changed

2 files changed

+82
-5
lines changed

src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ impl Merge for ast::UseTree {
164164
}
165165
}
166166

167+
#[derive(Debug)]
167168
enum Edit {
168169
Remove(Either<ast::Use, ast::UseTree>),
169170
Replace(SyntaxNode, SyntaxNode),
@@ -733,4 +734,72 @@ use std::{
733734
r"use std::fmt::{Debug, Display};",
734735
);
735736
}
737+
738+
#[test]
739+
fn test_merge_with_synonymous_imports_1() {
740+
check_assist(
741+
merge_imports,
742+
r"
743+
mod top {
744+
pub(crate) mod a {
745+
pub(crate) struct A;
746+
}
747+
pub(crate) mod b {
748+
pub(crate) struct B;
749+
pub(crate) struct D;
750+
}
751+
}
752+
753+
use top::a::A;
754+
use $0top::b::{B, B as C};
755+
",
756+
r"
757+
mod top {
758+
pub(crate) mod a {
759+
pub(crate) struct A;
760+
}
761+
pub(crate) mod b {
762+
pub(crate) struct B;
763+
pub(crate) struct D;
764+
}
765+
}
766+
767+
use top::{a::A, b::{B, B as C}};
768+
",
769+
);
770+
}
771+
772+
#[test]
773+
fn test_merge_with_synonymous_imports_2() {
774+
check_assist(
775+
merge_imports,
776+
r"
777+
mod top {
778+
pub(crate) mod a {
779+
pub(crate) struct A;
780+
}
781+
pub(crate) mod b {
782+
pub(crate) struct B;
783+
pub(crate) struct D;
784+
}
785+
}
786+
787+
use top::a::A;
788+
use $0top::b::{B as D, B as C};
789+
",
790+
r"
791+
mod top {
792+
pub(crate) mod a {
793+
pub(crate) struct A;
794+
}
795+
pub(crate) mod b {
796+
pub(crate) struct B;
797+
pub(crate) struct D;
798+
}
799+
}
800+
801+
use top::{a::A, b::{B as D, B as C}};
802+
",
803+
);
804+
}
736805
}

src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,25 @@ fn try_merge_trees_mut(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehav
9393
let rhs_path = rhs.path()?;
9494

9595
let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?;
96-
if !(lhs.is_simple_path()
96+
if lhs.is_simple_path()
9797
&& rhs.is_simple_path()
9898
&& lhs_path == lhs_prefix
99-
&& rhs_path == rhs_prefix)
99+
&& rhs_path == rhs_prefix
100100
{
101-
lhs.split_prefix(&lhs_prefix);
102-
rhs.split_prefix(&rhs_prefix);
103-
} else {
101+
// we can't merge if the renames are different (`A as a` and `A as b`),
102+
// and we can safely return here
103+
let lhs_name = lhs.rename().and_then(|lhs_name| lhs_name.name());
104+
let rhs_name = rhs.rename().and_then(|rhs_name| rhs_name.name());
105+
if lhs_name != rhs_name {
106+
return None;
107+
}
108+
104109
ted::replace(lhs.syntax(), rhs.syntax());
105110
// we can safely return here, in this case `recursive_merge` doesn't do anything
106111
return Some(());
112+
} else {
113+
lhs.split_prefix(&lhs_prefix);
114+
rhs.split_prefix(&rhs_prefix);
107115
}
108116
}
109117
recursive_merge(lhs, rhs, merge)

0 commit comments

Comments
 (0)