1 //! Complete fields in record literals and patterns.
2 use ide_db::{helpers::FamousDefs, SymbolKind};
6 item::CompletionKind, patterns::ImmediateLocation, CompletionContext, CompletionItem,
10 pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
11 let missing_fields = match &ctx.completion_location {
12 Some(ImmediateLocation::RecordExpr(record_expr)) => {
13 let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));
14 let default_trait = FamousDefs(&ctx.sema, ctx.krate).core_default_Default();
15 let impl_default_trait = default_trait
17 .map_or(false, |(default_trait, ty)| ty.impls_trait(ctx.db, default_trait, &[]));
19 let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
20 if impl_default_trait && !missing_fields.is_empty() {
21 let completion_text = "..Default::default()";
22 let mut item = CompletionItem::new(
23 CompletionKind::Snippet,
28 completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text);
29 item.insert_text(completion_text).kind(SymbolKind::Field);
35 Some(ImmediateLocation::RecordPat(record_pat)) => {
36 ctx.sema.record_pattern_missing_fields(record_pat)
41 for (field, ty) in missing_fields {
42 acc.add_field(ctx, field, &ty);
50 use expect_test::{expect, Expect};
51 use ide_db::helpers::FamousDefs;
54 test_utils::{self, completion_list},
58 fn check(ra_fixture: &str, expect: Expect) {
59 let actual = completion_list(ra_fixture, CompletionKind::Reference);
60 expect.assert_eq(&actual);
63 fn check_snippet(ra_fixture: &str, expect: Expect) {
64 let actual = completion_list(
65 &format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE),
66 CompletionKind::Snippet,
68 expect.assert_eq(&actual);
71 fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
72 test_utils::check_edit(
75 "//- /main.rs crate:main deps:core{}\n{}",
79 &(ra_fixture_after.to_owned() + "\n"),
84 fn test_record_literal_field_default() {
86 struct S { foo: u32, bar: usize }
88 impl core::default::Default for S {
89 fn default() -> Self {
114 fd ..Default::default()
120 fn test_record_literal_field_default_completion() {
122 "..Default::default()",
124 struct S { foo: u32, bar: usize }
126 impl core::default::Default for S {
127 fn default() -> Self {
143 struct S { foo: u32, bar: usize }
145 impl core::default::Default for S {
146 fn default() -> Self {
165 fn test_record_literal_field_without_default() {
167 struct S { foo: u32, bar: usize }
183 check_snippet(test_code, expect![[r#""#]]);
187 fn test_record_pattern_field() {
190 struct S { foo: u32 }
205 fn test_record_pattern_enum_variant() {
208 enum E { S { foo: u32, bar: () } }
224 fn test_record_pattern_field_in_simple_macro() {
227 macro_rules! m { ($e:expr) => { $e } }
228 struct S { foo: u32 }
243 fn only_missing_fields_are_completed_in_destruct_pats() {
247 foo1: u32, foo2: u32,
256 if let S { foo1, foo2: a, $0 } = s {}
267 fn test_record_literal_field() {
270 struct A { the_field: u32 }
282 fn test_record_literal_enum_variant() {
285 enum E { A { a: u32 } }
297 fn test_record_literal_two_structs() {
314 fn test_record_literal_generic_struct() {
320 let _: A<u32> = A { $0 }
330 fn test_record_literal_field_in_simple_macro() {
333 macro_rules! m { ($e:expr) => { $e } }
334 struct A { the_field: u32 }
346 fn only_missing_fields_are_completed() {
350 foo1: u32, foo2: u32,
356 let s = S { foo1, foo2: 5, $0 }
367 fn completes_functional_update() {
370 struct S { foo1: u32, foo2: u32 }
374 let s = S { foo1, $0 .. loop {} }