diff options
Diffstat (limited to 'crates/ra_ide')
-rw-r--r-- | crates/ra_ide/src/completion/complete_record_pattern.rs | 63 |
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 | ||
3 | use crate::completion::{CompletionContext, Completions}; | 3 | use crate::completion::{CompletionContext, Completions}; |
4 | use ra_syntax::{ast::NameOwner, SmolStr}; | ||
4 | 5 | ||
5 | pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionContext) { | 6 | pub(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 | } |