about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-03-25 18:37:18 +0100
committerLukas Wirth <lukastw97@gmail.com>2023-03-25 18:37:18 +0100
commit0daf069b0efb7690bcd3436318e806b8b4d983a4 (patch)
tree391e7d67d2c30e4723e73e64e7fae5590f815bae
parent71b23360e781a00e51ed702a96e181261e92c6c5 (diff)
downloadrust-0daf069b0efb7690bcd3436318e806b8b4d983a4.tar.gz
rust-0daf069b0efb7690bcd3436318e806b8b4d983a4.zip
fix: Fix renames of locals being broken in macro calls
-rw-r--r--crates/hir-expand/src/lib.rs1
-rw-r--r--crates/ide-db/src/rename.rs26
2 files changed, 20 insertions, 7 deletions
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index 5e99eacc1b6..980de3c2685 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -977,6 +977,7 @@ impl<N: AstNode> InFile<N> {
         self.value.syntax().descendants().filter_map(T::cast).map(move |n| self.with_value(n))
     }
 
+    // FIXME: this should return `Option<InFileNotHirFile<N>>`
     pub fn original_ast_node(self, db: &dyn db::ExpandDatabase) -> Option<InFile<N>> {
         // This kind of upmapping can only be achieved in attribute expanded files,
         // as we don't have node inputs otherwise and therefore can't find an `N` node in the input
diff --git a/crates/ide-db/src/rename.rs b/crates/ide-db/src/rename.rs
index f710211c8cb..9aadf403638 100644
--- a/crates/ide-db/src/rename.rs
+++ b/crates/ide-db/src/rename.rs
@@ -207,7 +207,7 @@ fn rename_mod(
             }
             // The anchor is on the same level as target dir
             (false, true, Some(mod_name)) => {
-                Some((mod_name.unescaped().to_string(), new_name.to_string()))
+                Some((mod_name.unescaped().to_string(), new_name.to_owned()))
             }
             _ => None,
         };
@@ -232,7 +232,7 @@ fn rename_mod(
                 {
                     source_change.insert_source_edit(
                         file_id,
-                        TextEdit::replace(file_range.range, new_name.to_string()),
+                        TextEdit::replace(file_range.range, new_name.to_owned()),
                     )
                 };
             }
@@ -442,7 +442,7 @@ fn source_edit_from_name_ref(
                         let s = field_name.syntax().text_range().start();
                         let e = pat.syntax().text_range().start();
                         edit.delete(TextRange::new(s, e));
-                        edit.replace(name.syntax().text_range(), new_name.to_string());
+                        edit.replace(name.syntax().text_range(), new_name.to_owned());
                         return true;
                     }
                 }
@@ -462,7 +462,19 @@ fn source_edit_from_def(
     if let Definition::Local(local) = def {
         let mut file_id = None;
         for source in local.sources(sema.db) {
-            let source = source.source;
+            let source = match source.source.clone().original_ast_node(sema.db) {
+                Some(source) => source,
+                None => match source.source.syntax().original_file_range_opt(sema.db) {
+                    Some(FileRange { file_id: file_id2, range }) => {
+                        file_id = Some(file_id2);
+                        edit.replace(range, new_name.to_owned());
+                        continue;
+                    }
+                    None => {
+                        bail!("Can't rename local that is defined in a macro declaration")
+                    }
+                },
+            };
             file_id = source.file_id.file_id();
             if let Either::Left(pat) = source.value {
                 let name_range = pat.name().unwrap().syntax().text_range();
@@ -485,7 +497,7 @@ fn source_edit_from_def(
                             // Foo { field: ref mut local @ local 2} -> Foo { field: ref mut new_name @ local2 }
                             // Foo { field: ref mut local } -> Foo { field: ref mut new_name }
                             //                      ^^^^^ replace this with `new_name`
-                            edit.replace(name_range, new_name.to_string());
+                            edit.replace(name_range, new_name.to_owned());
                         }
                     } else {
                         // Foo { ref mut field } -> Foo { field: ref mut new_name }
@@ -495,10 +507,10 @@ fn source_edit_from_def(
                             pat.syntax().text_range().start(),
                             format!("{}: ", pat_field.field_name().unwrap()),
                         );
-                        edit.replace(name_range, new_name.to_string());
+                        edit.replace(name_range, new_name.to_owned());
                     }
                 } else {
-                    edit.replace(name_range, new_name.to_string());
+                    edit.replace(name_range, new_name.to_owned());
                 }
             }
         }