Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/destructure_struct_binding.rs')
-rw-r--r--crates/ide-assists/src/handlers/destructure_struct_binding.rs36
1 files changed, 34 insertions, 2 deletions
diff --git a/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/crates/ide-assists/src/handlers/destructure_struct_binding.rs
index 0f5ef0548c..ec4a83b642 100644
--- a/crates/ide-assists/src/handlers/destructure_struct_binding.rs
+++ b/crates/ide-assists/src/handlers/destructure_struct_binding.rs
@@ -17,7 +17,7 @@ use syntax::{
use crate::{
assist_context::{AssistContext, Assists, SourceChangeBuilder},
- utils::ref_field_expr::determine_ref_and_parens,
+ utils::{cover_edit_range, ref_field_expr::determine_ref_and_parens},
};
// Assist: destructure_struct_binding
@@ -358,6 +358,7 @@ fn update_usages(
data: &StructEditData,
field_names: &FxHashMap<SmolStr, SmolStr>,
) {
+ let source = ctx.source_file().syntax();
let make = SyntaxFactory::with_mappings();
let edits = data
.usages
@@ -366,7 +367,9 @@ fn update_usages(
.collect_vec();
editor.add_mappings(make.finish_with_mappings());
for (old, new) in edits {
- editor.replace(old, new);
+ if let Some(range) = ctx.sema.original_range_opt(&old) {
+ editor.replace_all(cover_edit_range(source, range.range), vec![new.into()]);
+ }
}
}
@@ -1006,4 +1009,33 @@ mod tests {
"#,
)
}
+
+ #[test]
+ fn record_struct_usage_in_macro_call() {
+ // exact repro from #20716: struct field access inside write! must not panic
+ check_assist(
+ destructure_struct_binding,
+ r#"
+//- minicore: write, fmt
+use core::fmt::Write;
+struct Foo { y: i8 }
+
+fn main() {
+ let mut s = String::new();
+ let $0x = Foo { y: 8 };
+ write!(s, "{}", x.y).unwrap();
+}
+"#,
+ r#"
+use core::fmt::Write;
+struct Foo { y: i8 }
+
+fn main() {
+ let mut s = String::new();
+ let Foo { y } = Foo { y: 8 };
+ write!(s, "{}", y).unwrap();
+}
+"#,
+ )
+ }
}