Skip to content

Commit f34e9ca

Browse files
committed
Fix panic !self.data().mutable for destructure_struct_binding
When the reference type does not require adding a dereference or parentheses, it will panic Example --- ```rust struct Foo { bar: i32, baz: i32 } fn main() { let $0foo = &Foo { bar: 1, baz: 2 }; let _ = &foo.bar; } ``` **Before this PR**: Panic: ``` assertion failed: !self.data().mutable ``` **After this PR**: ```rust struct Foo { bar: i32, baz: i32 } fn main() { let Foo { bar, baz } = &Foo { bar: 1, baz: 2 }; let _ = bar; } ```
1 parent b12a129 commit f34e9ca

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

crates/ide-assists/src/handlers/destructure_struct_binding.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ fn build_usage_edit(
288288
Some(field_expr) => Some({
289289
let field_name: SmolStr = field_expr.name_ref()?.to_string().into();
290290
let new_field_name = field_names.get(&field_name)?;
291-
let new_expr = make.expr_path(ast::make::ext::ident_path(new_field_name));
291+
let new_expr = ast::make::expr_path(ast::make::ext::ident_path(new_field_name));
292292

293293
// If struct binding is a reference, we might need to deref field usages
294294
if data.is_ref {
@@ -298,7 +298,7 @@ fn build_usage_edit(
298298
ref_data.wrap_expr(new_expr).syntax().clone_for_update(),
299299
)
300300
} else {
301-
(field_expr.syntax().clone(), new_expr.syntax().clone())
301+
(field_expr.syntax().clone(), new_expr.syntax().clone_for_update())
302302
}
303303
}),
304304
None => Some((
@@ -610,6 +610,52 @@ mod tests {
610610
)
611611
}
612612

613+
#[test]
614+
fn ref_not_add_parenthesis_and_deref_record() {
615+
check_assist(
616+
destructure_struct_binding,
617+
r#"
618+
struct Foo { bar: i32, baz: i32 }
619+
620+
fn main() {
621+
let $0foo = &Foo { bar: 1, baz: 2 };
622+
let _ = &foo.bar;
623+
}
624+
"#,
625+
r#"
626+
struct Foo { bar: i32, baz: i32 }
627+
628+
fn main() {
629+
let Foo { bar, baz } = &Foo { bar: 1, baz: 2 };
630+
let _ = bar;
631+
}
632+
"#,
633+
)
634+
}
635+
636+
#[test]
637+
fn ref_not_add_parenthesis_and_deref_tuple() {
638+
check_assist(
639+
destructure_struct_binding,
640+
r#"
641+
struct Foo(i32, i32);
642+
643+
fn main() {
644+
let $0foo = &Foo(1, 2);
645+
let _ = &foo.0;
646+
}
647+
"#,
648+
r#"
649+
struct Foo(i32, i32);
650+
651+
fn main() {
652+
let Foo(_0, _1) = &Foo(1, 2);
653+
let _ = _0;
654+
}
655+
"#,
656+
)
657+
}
658+
613659
#[test]
614660
fn record_struct_name_collision() {
615661
check_assist(

0 commit comments

Comments
 (0)