Skip to content

Commit 86e5406

Browse files
committed
Fix rename trying to edit the same range multiple times
1 parent 745fd99 commit 86e5406

File tree

2 files changed

+55
-7
lines changed

2 files changed

+55
-7
lines changed

crates/ide/src/rename.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,51 @@ fn func$0() {
18991899
fn function() {
19001900
function();
19011901
}
1902+
"#,
1903+
)
1904+
}
1905+
1906+
#[test]
1907+
fn in_macro_multi_mapping() {
1908+
check(
1909+
"a",
1910+
r#"
1911+
fn foo() {
1912+
macro_rules! match_ast2 {
1913+
($node:ident {
1914+
$( $res:expr, )*
1915+
}) => {{
1916+
$( if $node { $res } else )*
1917+
{ loop {} }
1918+
}};
1919+
}
1920+
let $0d = 3;
1921+
match_ast2! {
1922+
d {
1923+
d,
1924+
d,
1925+
}
1926+
};
1927+
}
1928+
"#,
1929+
r#"
1930+
fn foo() {
1931+
macro_rules! match_ast2 {
1932+
($node:ident {
1933+
$( $res:expr, )*
1934+
}) => {{
1935+
$( if $node { $res } else )*
1936+
{ loop {} }
1937+
}};
1938+
}
1939+
let a = 3;
1940+
match_ast2! {
1941+
a {
1942+
a,
1943+
a,
1944+
}
1945+
};
1946+
}
19021947
"#,
19031948
)
19041949
}

crates/ide_db/src/rename.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -291,23 +291,26 @@ pub fn source_edit_from_references(
291291
new_name: &str,
292292
) -> TextEdit {
293293
let mut edit = TextEdit::builder();
294-
for reference in references {
295-
let has_emitted_edit = match &reference.name {
294+
// macros can cause multiple refs to occur for the same text range, so keep track of what we have edited so far
295+
let mut edited_ranges = Vec::new();
296+
for &FileReference { range, ref name, .. } in references {
297+
let has_emitted_edit = match name {
296298
// if the ranges differ then the node is inside a macro call, we can't really attempt
297299
// to make special rewrites like shorthand syntax and such, so just rename the node in
298300
// the macro input
299-
ast::NameLike::NameRef(name_ref)
300-
if name_ref.syntax().text_range() == reference.range =>
301-
{
301+
ast::NameLike::NameRef(name_ref) if name_ref.syntax().text_range() == range => {
302302
source_edit_from_name_ref(&mut edit, name_ref, new_name, def)
303303
}
304-
ast::NameLike::Name(name) if name.syntax().text_range() == reference.range => {
304+
ast::NameLike::Name(name) if name.syntax().text_range() == range => {
305305
source_edit_from_name(&mut edit, name, new_name)
306306
}
307307
_ => false,
308308
};
309309
if !has_emitted_edit {
310-
edit.replace(reference.range, new_name.to_string());
310+
if !edited_ranges.contains(&range.start()) {
311+
edit.replace(range, new_name.to_string());
312+
edited_ranges.push(range.start());
313+
}
311314
}
312315
}
313316

0 commit comments

Comments
 (0)