aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/completion
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/completion')
-rw-r--r--crates/ra_ide/src/completion/complete_record_pattern.rs63
1 files changed, 62 insertions, 1 deletions
diff --git a/crates/ra_ide/src/completion/complete_record_pattern.rs b/crates/ra_ide/src/completion/complete_record_pattern.rs
index 962376428..78315eeb8 100644
--- a/crates/ra_ide/src/completion/complete_record_pattern.rs
+++ b/crates/ra_ide/src/completion/complete_record_pattern.rs
@@ -1,6 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use crate::completion::{CompletionContext, Completions}; 3use crate::completion::{CompletionContext, Completions};
4use ra_syntax::{ast::NameOwner, SmolStr};
4 5
5pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionContext) { 6pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionContext) {
6 let (ty, variant) = match ctx.record_lit_pat.as_ref().and_then(|it| { 7 let (ty, variant) = match ctx.record_lit_pat.as_ref().and_then(|it| {
@@ -10,8 +11,24 @@ pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionCon
10 _ => return, 11 _ => return,
11 }; 12 };
12 13
14 let already_present_names: Vec<SmolStr> = ctx
15 .record_lit_pat
16 .as_ref()
17 .and_then(|record_pat| record_pat.record_field_pat_list())
18 .map(|pat_list| pat_list.bind_pats())
19 .map(|bind_pats| {
20 bind_pats
21 .into_iter()
22 .filter_map(|pat| pat.name())
23 .map(|name| name.text().clone())
24 .collect()
25 })
26 .unwrap_or_default();
27
13 for (field, field_ty) in ty.variant_fields(ctx.db, variant) { 28 for (field, field_ty) in ty.variant_fields(ctx.db, variant) {
14 acc.add_field(ctx, field, &field_ty); 29 if !already_present_names.contains(&SmolStr::from(field.name(ctx.db).to_string())) {
30 acc.add_field(ctx, field, &field_ty);
31 }
15 } 32 }
16} 33}
17 34
@@ -115,4 +132,48 @@ mod tests {
115 ] 132 ]
116 "###); 133 "###);
117 } 134 }
135
136 #[test]
137 fn only_missing_fields_are_completed_in_destruct_pats() {
138 let completions = complete(
139 r"
140 struct S {
141 foo1: u32,
142 foo2: u32,
143 bar: u32,
144 baz: u32,
145 }
146
147 fn main() {
148 let s = S {
149 foo1: 1,
150 foo2: 2,
151 bar: 3,
152 baz: 4,
153 };
154 if let S { foo1, foo2, <|> } = s {}
155 }
156 ",
157 );
158 assert_debug_snapshot!(completions, @r###"
159 [
160 CompletionItem {
161 label: "bar",
162 source_range: [369; 369),
163 delete: [369; 369),
164 insert: "bar",
165 kind: Field,
166 detail: "u32",
167 },
168 CompletionItem {
169 label: "baz",
170 source_range: [369; 369),
171 delete: [369; 369),
172 insert: "baz",
173 kind: Field,
174 detail: "u32",
175 },
176 ]
177 "###);
178 }
118} 179}