From 1ce1faec2464f4e581a922540f39a9130a48fe12 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 28 Dec 2025 17:30:38 +0800 Subject: [PATCH] Fix duplicate record functional update Example --- ```rust fn main() { let thing = 1; let foo = Foo { foo1: 0, foo2: 0 }; let foo2 = Foo { thing, $0 ..Default::default() } } ``` **Before this PR** ```text fd ..Default::default() fd foo1 u32 fd foo2 u32 ``` **After this PR** ```text fd foo1 u32 fd foo2 u32 ``` --- .../ide-completion/src/completions/record.rs | 5 +++- .../crates/ide-completion/src/tests/record.rs | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs index bfa567009c01..c5bfdcb8b734 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs @@ -70,8 +70,11 @@ pub(crate) fn complete_record_expr_fields( } _ => { let missing_fields = ctx.sema.record_literal_missing_fields(record_expr); + let update_exists = record_expr + .record_expr_field_list() + .is_some_and(|list| list.dotdot_token().is_some()); - if !missing_fields.is_empty() { + if !missing_fields.is_empty() && !update_exists { cov_mark::hit!(functional_update_field); add_default_update(acc, ctx, ty); } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs index a1013b86548b..d9be6556fa5b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs @@ -263,6 +263,29 @@ fn main() { ); } +#[test] +fn functional_update_exist_update() { + check( + r#" +//- minicore:default +struct Foo { foo1: u32, foo2: u32 } +impl Default for Foo { + fn default() -> Self { loop {} } +} + +fn main() { + let thing = 1; + let foo = Foo { foo1: 0, foo2: 0 }; + let foo2 = Foo { thing, $0 ..Default::default() } +} +"#, + expect![[r#" + fd foo1 u32 + fd foo2 u32 + "#]], + ); +} + #[test] fn empty_union_literal() { check(