From 924eecf4af4d57c597c2e77c5e58c22b2a37bdb6 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 14 Nov 2020 19:11:09 +0100 Subject: [PATCH] Properly handle shorthands in destructure patterns when renaming --- crates/ide/src/references.rs | 19 +++++++--- crates/ide/src/references/rename.rs | 54 +++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index e05465b32e..10cd42032a 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -110,14 +110,23 @@ pub(crate) fn find_all_refs( .filter(|r| search_kind == ReferenceKind::Other || search_kind == r.kind) .collect(); - let decl_range = def.try_to_nav(sema.db)?.focus_or_full_range(); + let nav = def.try_to_nav(sema.db)?; + let decl_range = nav.focus_or_full_range(); - let declaration = Declaration { - nav: def.try_to_nav(sema.db)?, - kind: ReferenceKind::Other, - access: decl_access(&def, &syntax, decl_range), + let mut kind = ReferenceKind::Other; + if let Definition::Local(local) = def { + if let either::Either::Left(pat) = local.source(sema.db).value { + if matches!( + pat.syntax().parent().and_then(ast::RecordPatField::cast), + Some(pat_field) if pat_field.name_ref().is_none() + ) { + kind = ReferenceKind::FieldShorthandForLocal; + } + } }; + let declaration = Declaration { nav, kind, access: decl_access(&def, &syntax, decl_range) }; + Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references })) } diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index b3ade20ef0..bc4aa25bf8 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs @@ -1135,6 +1135,60 @@ struct Foo { bar: i32 } fn foo(bar: i32) -> Foo { Foo { bar } } +"#, + ); + } + + #[test] + fn test_rename_binding_in_destructure_pat_shorthand() { + check( + "bar", + r#" +struct Foo { + i: i32, +} + +fn foo(foo: Foo) { + let Foo { i } = foo; + let _ = i<|>; +} +"#, + r#" +struct Foo { + i: i32, +} + +fn foo(foo: Foo) { + let Foo { i: bar } = foo; + let _ = bar; +} +"#, + ); + } + + #[test] + fn test_rename_binding_in_destructure_pat() { + check( + "bar", + r#" +struct Foo { + i: i32, +} + +fn foo(foo: Foo) { + let Foo { i: b } = foo; + let _ = b<|>; +} +"#, + r#" +struct Foo { + i: i32, +} + +fn foo(foo: Foo) { + let Foo { i: bar } = foo; + let _ = bar; +} "#, ); }