From: Lukas Wirth Date: Sat, 2 Oct 2021 16:50:21 +0000 (+0200) Subject: Fix rename trying to edit the same range multiple times X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=86e5406539d5eac8583a9442a1f5faca49d1094e;p=rust.git Fix rename trying to edit the same range multiple times --- diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index a495e6c5432..cce342272f7 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -1899,6 +1899,51 @@ fn func$0() { fn function() { function(); } +"#, + ) + } + + #[test] + fn in_macro_multi_mapping() { + check( + "a", + r#" +fn foo() { + macro_rules! match_ast2 { + ($node:ident { + $( $res:expr, )* + }) => {{ + $( if $node { $res } else )* + { loop {} } + }}; + } + let $0d = 3; + match_ast2! { + d { + d, + d, + } + }; +} +"#, + r#" +fn foo() { + macro_rules! match_ast2 { + ($node:ident { + $( $res:expr, )* + }) => {{ + $( if $node { $res } else )* + { loop {} } + }}; + } + let a = 3; + match_ast2! { + a { + a, + a, + } + }; +} "#, ) } diff --git a/crates/ide_db/src/rename.rs b/crates/ide_db/src/rename.rs index 0ca0dc8c6b1..fcf1a654b04 100644 --- a/crates/ide_db/src/rename.rs +++ b/crates/ide_db/src/rename.rs @@ -291,23 +291,26 @@ pub fn source_edit_from_references( new_name: &str, ) -> TextEdit { let mut edit = TextEdit::builder(); - for reference in references { - let has_emitted_edit = match &reference.name { + // macros can cause multiple refs to occur for the same text range, so keep track of what we have edited so far + let mut edited_ranges = Vec::new(); + for &FileReference { range, ref name, .. } in references { + let has_emitted_edit = match name { // if the ranges differ then the node is inside a macro call, we can't really attempt // to make special rewrites like shorthand syntax and such, so just rename the node in // the macro input - ast::NameLike::NameRef(name_ref) - if name_ref.syntax().text_range() == reference.range => - { + ast::NameLike::NameRef(name_ref) if name_ref.syntax().text_range() == range => { source_edit_from_name_ref(&mut edit, name_ref, new_name, def) } - ast::NameLike::Name(name) if name.syntax().text_range() == reference.range => { + ast::NameLike::Name(name) if name.syntax().text_range() == range => { source_edit_from_name(&mut edit, name, new_name) } _ => false, }; if !has_emitted_edit { - edit.replace(reference.range, new_name.to_string()); + if !edited_ranges.contains(&range.start()) { + edit.replace(range, new_name.to_string()); + edited_ranges.push(range.start()); + } } }