aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/completions
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/completions')
-rw-r--r--crates/ide_completion/src/completions/attribute.rs37
-rw-r--r--crates/ide_completion/src/completions/fn_param.rs15
-rw-r--r--crates/ide_completion/src/completions/keyword.rs18
-rw-r--r--crates/ide_completion/src/completions/lifetime.rs7
-rw-r--r--crates/ide_completion/src/completions/macro_in_item_position.rs4
-rw-r--r--crates/ide_completion/src/completions/mod_.rs6
-rw-r--r--crates/ide_completion/src/completions/pattern.rs2
-rw-r--r--crates/ide_completion/src/completions/qualified_path.rs38
-rw-r--r--crates/ide_completion/src/completions/record.rs20
-rw-r--r--crates/ide_completion/src/completions/unqualified_path.rs8
10 files changed, 101 insertions, 54 deletions
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs
index 13d5b90c9..76d926157 100644
--- a/crates/ide_completion/src/completions/attribute.rs
+++ b/crates/ide_completion/src/completions/attribute.rs
@@ -219,8 +219,7 @@ const ATTRIBUTES: &[AttrCompletion] = &[
219 ), 219 ),
220 attr("feature(…)", Some("feature"), Some("feature(${0:flag})")).prefer_inner(), 220 attr("feature(…)", Some("feature"), Some("feature(${0:flag})")).prefer_inner(),
221 attr("forbid(…)", Some("forbid"), Some("forbid(${0:lint})")), 221 attr("forbid(…)", Some("forbid"), Some("forbid(${0:lint})")),
222 // FIXME: resolve through macro resolution? 222 attr("global_allocator", None, None),
223 attr("global_allocator", None, None).prefer_inner(),
224 attr(r#"ignore = "…""#, Some("ignore"), Some(r#"ignore = "${0:reason}""#)), 223 attr(r#"ignore = "…""#, Some("ignore"), Some(r#"ignore = "${0:reason}""#)),
225 attr("inline", Some("inline"), Some("inline")), 224 attr("inline", Some("inline"), Some("inline")),
226 attr("link", None, None), 225 attr("link", None, None),
@@ -239,7 +238,7 @@ const ATTRIBUTES: &[AttrCompletion] = &[
239 attr("no_mangle", None, None), 238 attr("no_mangle", None, None),
240 attr("no_std", None, None).prefer_inner(), 239 attr("no_std", None, None).prefer_inner(),
241 attr("non_exhaustive", None, None), 240 attr("non_exhaustive", None, None),
242 attr("panic_handler", None, None).prefer_inner(), 241 attr("panic_handler", None, None),
243 attr(r#"path = "…""#, Some("path"), Some(r#"path ="${0:path}""#)), 242 attr(r#"path = "…""#, Some("path"), Some(r#"path ="${0:path}""#)),
244 attr("proc_macro", None, None), 243 attr("proc_macro", None, None),
245 attr("proc_macro_attribute", None, None), 244 attr("proc_macro_attribute", None, None),
@@ -609,6 +608,7 @@ mod tests {
609 at export_name = "…" 608 at export_name = "…"
610 at link_name = "…" 609 at link_name = "…"
611 at link_section = "…" 610 at link_section = "…"
611 at global_allocator
612 at used 612 at used
613 "#]], 613 "#]],
614 ); 614 );
@@ -732,9 +732,9 @@ mod tests {
732 } 732 }
733 733
734 #[test] 734 #[test]
735 fn complete_attribute_on_expr() { 735 fn complete_attribute_on_fn() {
736 check( 736 check(
737 r#"fn main() { #[$0] foo() }"#, 737 r#"#[$0] fn main() {}"#,
738 expect![[r#" 738 expect![[r#"
739 at allow(…) 739 at allow(…)
740 at cfg(…) 740 at cfg(…)
@@ -742,10 +742,35 @@ mod tests {
742 at deny(…) 742 at deny(…)
743 at forbid(…) 743 at forbid(…)
744 at warn(…) 744 at warn(…)
745 at deprecated
746 at doc = "…"
747 at doc(hidden)
748 at doc(alias = "…")
749 at must_use
750 at no_mangle
751 at export_name = "…"
752 at link_name = "…"
753 at link_section = "…"
754 at cold
755 at ignore = "…"
756 at inline
757 at must_use
758 at panic_handler
759 at proc_macro
760 at proc_macro_derive(…)
761 at proc_macro_attribute
762 at should_panic
763 at target_feature = "…"
764 at test
765 at track_caller
745 "#]], 766 "#]],
746 ); 767 );
768 }
769
770 #[test]
771 fn complete_attribute_on_expr() {
747 check( 772 check(
748 r#"fn main() { #[$0] foo(); }"#, 773 r#"fn main() { #[$0] foo() }"#,
749 expect![[r#" 774 expect![[r#"
750 at allow(…) 775 at allow(…)
751 at cfg(…) 776 at cfg(…)
diff --git a/crates/ide_completion/src/completions/fn_param.rs b/crates/ide_completion/src/completions/fn_param.rs
index 0ea558489..cb90e8a3e 100644
--- a/crates/ide_completion/src/completions/fn_param.rs
+++ b/crates/ide_completion/src/completions/fn_param.rs
@@ -128,4 +128,19 @@ fn outer(text: String) {
128 "#]], 128 "#]],
129 ) 129 )
130 } 130 }
131
132 #[test]
133 fn completes_non_ident_pat_param() {
134 check(
135 r#"
136struct Bar { bar: u32 }
137
138fn foo(Bar { bar }: Bar) {}
139fn foo2($0) {}
140"#,
141 expect![[r#"
142 bn Bar { bar }: Bar
143 "#]],
144 )
145 }
131} 146}
diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs
index e71a04b6e..0d035c611 100644
--- a/crates/ide_completion/src/completions/keyword.rs
+++ b/crates/ide_completion/src/completions/keyword.rs
@@ -4,7 +4,10 @@ use std::iter;
4 4
5use syntax::{SyntaxKind, T}; 5use syntax::{SyntaxKind, T};
6 6
7use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions}; 7use crate::{
8 patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind,
9 CompletionKind, Completions,
10};
8 11
9pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) { 12pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
10 // complete keyword "crate" in use stmt 13 // complete keyword "crate" in use stmt
@@ -44,7 +47,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
44 cov_mark::hit!(no_keyword_completion_in_comments); 47 cov_mark::hit!(no_keyword_completion_in_comments);
45 return; 48 return;
46 } 49 }
47 if ctx.record_lit_syntax.is_some() { 50 if matches!(ctx.completion_location, Some(ImmediateLocation::RecordExpr(_))) {
48 cov_mark::hit!(no_keyword_completion_in_record_lit); 51 cov_mark::hit!(no_keyword_completion_in_record_lit);
49 return; 52 return;
50 } 53 }
@@ -55,7 +58,6 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
55 let expects_item = ctx.expects_item(); 58 let expects_item = ctx.expects_item();
56 59
57 if ctx.has_impl_or_trait_prev_sibling() { 60 if ctx.has_impl_or_trait_prev_sibling() {
58 // FIXME this also incorrectly shows up after a complete trait/impl
59 add_keyword("where", "where "); 61 add_keyword("where", "where ");
60 return; 62 return;
61 } 63 }
@@ -77,11 +79,8 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
77 add_keyword("pub", "pub "); 79 add_keyword("pub", "pub ");
78 } 80 }
79 81
80 if expects_item || expects_assoc_item || has_block_expr_parent || ctx.is_match_arm {
81 add_keyword("unsafe", "unsafe ");
82 }
83
84 if expects_item || expects_assoc_item || has_block_expr_parent { 82 if expects_item || expects_assoc_item || has_block_expr_parent {
83 add_keyword("unsafe", "unsafe ");
85 add_keyword("fn", "fn $1($2) {\n $0\n}"); 84 add_keyword("fn", "fn $1($2) {\n $0\n}");
86 add_keyword("const", "const $0"); 85 add_keyword("const", "const $0");
87 add_keyword("type", "type $0"); 86 add_keyword("type", "type $0");
@@ -103,6 +102,9 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
103 } 102 }
104 103
105 if ctx.expects_expression() { 104 if ctx.expects_expression() {
105 if !has_block_expr_parent {
106 add_keyword("unsafe", "unsafe {\n $0\n}");
107 }
106 add_keyword("match", "match $1 {\n $0\n}"); 108 add_keyword("match", "match $1 {\n $0\n}");
107 add_keyword("while", "while $1 {\n $0\n}"); 109 add_keyword("while", "while $1 {\n $0\n}");
108 add_keyword("while let", "while let $1 = $2 {\n $0\n}"); 110 add_keyword("while let", "while let $1 = $2 {\n $0\n}");
@@ -574,6 +576,7 @@ pub mod future {
574 check( 576 check(
575 r#"fn main() { let _ = $0 }"#, 577 r#"fn main() { let _ = $0 }"#,
576 expect![[r#" 578 expect![[r#"
579 kw unsafe
577 kw match 580 kw match
578 kw while 581 kw while
579 kw while let 582 kw while let
@@ -634,6 +637,7 @@ fn foo() {
634} 637}
635"#, 638"#,
636 expect![[r#" 639 expect![[r#"
640 kw unsafe
637 kw match 641 kw match
638 kw while 642 kw while
639 kw while let 643 kw while let
diff --git a/crates/ide_completion/src/completions/lifetime.rs b/crates/ide_completion/src/completions/lifetime.rs
index 5f6285b84..8ccccb646 100644
--- a/crates/ide_completion/src/completions/lifetime.rs
+++ b/crates/ide_completion/src/completions/lifetime.rs
@@ -16,15 +16,14 @@ pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext)
16 (Some(lt), Some(lp)) if lp == lt.clone() => return, 16 (Some(lt), Some(lp)) if lp == lt.clone() => return,
17 (Some(_), Some(lp)) => { 17 (Some(_), Some(lp)) => {
18 lp_string = lp.to_string(); 18 lp_string = lp.to_string();
19 Some(&lp_string) 19 Some(&*lp_string)
20 } 20 }
21 _ => None, 21 _ => None,
22 }; 22 };
23 23
24 ctx.scope.process_all_names(&mut |name, res| { 24 ctx.scope.process_all_names(&mut |name, res| {
25 if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res { 25 if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res {
26 let name = name.to_string(); 26 if param_lifetime != Some(&*name.to_string()) {
27 if param_lifetime != Some(&name) {
28 acc.add_resolution(ctx, name, &res); 27 acc.add_resolution(ctx, name, &res);
29 } 28 }
30 } 29 }
@@ -41,7 +40,7 @@ pub(crate) fn complete_label(acc: &mut Completions, ctx: &CompletionContext) {
41 } 40 }
42 ctx.scope.process_all_names(&mut |name, res| { 41 ctx.scope.process_all_names(&mut |name, res| {
43 if let ScopeDef::Label(_) = res { 42 if let ScopeDef::Label(_) = res {
44 acc.add_resolution(ctx, name.to_string(), &res); 43 acc.add_resolution(ctx, name, &res);
45 } 44 }
46 }); 45 });
47} 46}
diff --git a/crates/ide_completion/src/completions/macro_in_item_position.rs b/crates/ide_completion/src/completions/macro_in_item_position.rs
index ec57aee30..202e71215 100644
--- a/crates/ide_completion/src/completions/macro_in_item_position.rs
+++ b/crates/ide_completion/src/completions/macro_in_item_position.rs
@@ -11,11 +11,11 @@ pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &Compl
11 11
12 ctx.scope.process_all_names(&mut |name, res| { 12 ctx.scope.process_all_names(&mut |name, res| {
13 if let hir::ScopeDef::MacroDef(mac) = res { 13 if let hir::ScopeDef::MacroDef(mac) = res {
14 acc.add_macro(ctx, Some(name.to_string()), mac); 14 acc.add_macro(ctx, Some(name.clone()), mac);
15 } 15 }
16 // FIXME: This should be done in qualified_path/unqualified_path instead? 16 // FIXME: This should be done in qualified_path/unqualified_path instead?
17 if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res { 17 if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
18 acc.add_resolution(ctx, name.to_string(), &res); 18 acc.add_resolution(ctx, name, &res);
19 } 19 }
20 }) 20 })
21} 21}
diff --git a/crates/ide_completion/src/completions/mod_.rs b/crates/ide_completion/src/completions/mod_.rs
index 4f9415736..6a5746fb9 100644
--- a/crates/ide_completion/src/completions/mod_.rs
+++ b/crates/ide_completion/src/completions/mod_.rs
@@ -9,14 +9,14 @@ use ide_db::{
9}; 9};
10use rustc_hash::FxHashSet; 10use rustc_hash::FxHashSet;
11 11
12use crate::CompletionItem; 12use crate::{patterns::ImmediateLocation, CompletionItem};
13 13
14use crate::{context::CompletionContext, item::CompletionKind, Completions}; 14use crate::{context::CompletionContext, item::CompletionKind, Completions};
15 15
16/// Complete mod declaration, i.e. `mod $0 ;` 16/// Complete mod declaration, i.e. `mod $0 ;`
17pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { 17pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
18 let mod_under_caret = match &ctx.mod_declaration_under_caret { 18 let mod_under_caret = match &ctx.completion_location {
19 Some(mod_under_caret) if mod_under_caret.item_list().is_none() => mod_under_caret, 19 Some(ImmediateLocation::ModDeclaration(mod_under_caret)) => mod_under_caret,
20 _ => return None, 20 _ => return None,
21 }; 21 };
22 22
diff --git a/crates/ide_completion/src/completions/pattern.rs b/crates/ide_completion/src/completions/pattern.rs
index b84e9a967..8a728c67e 100644
--- a/crates/ide_completion/src/completions/pattern.rs
+++ b/crates/ide_completion/src/completions/pattern.rs
@@ -51,7 +51,7 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
51 _ => false, 51 _ => false,
52 }; 52 };
53 if add_resolution { 53 if add_resolution {
54 acc.add_resolution(ctx, name.to_string(), &res); 54 acc.add_resolution(ctx, name, &res);
55 } 55 }
56 }); 56 });
57} 57}
diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs
index 7a0e1ead3..de58ce1cd 100644
--- a/crates/ide_completion/src/completions/qualified_path.rs
+++ b/crates/ide_completion/src/completions/qualified_path.rs
@@ -1,6 +1,6 @@
1//! Completion of paths, i.e. `some::prefix::$0`. 1//! Completion of paths, i.e. `some::prefix::$0`.
2 2
3use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; 3use hir::HasVisibility;
4use rustc_hash::FxHashSet; 4use rustc_hash::FxHashSet;
5use syntax::AstNode; 5use syntax::AstNode;
6 6
@@ -21,14 +21,14 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
21 }; 21 };
22 let context_module = ctx.scope.module(); 22 let context_module = ctx.scope.module();
23 if ctx.expects_assoc_item() { 23 if ctx.expects_assoc_item() {
24 if let PathResolution::Def(hir::ModuleDef::Module(module)) = resolution { 24 if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
25 let module_scope = module.scope(ctx.db, context_module); 25 let module_scope = module.scope(ctx.db, context_module);
26 for (name, def) in module_scope { 26 for (name, def) in module_scope {
27 if let ScopeDef::MacroDef(macro_def) = def { 27 if let hir::ScopeDef::MacroDef(macro_def) = def {
28 acc.add_macro(ctx, Some(name.to_string()), macro_def); 28 acc.add_macro(ctx, Some(name.clone()), macro_def);
29 } 29 }
30 if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def { 30 if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
31 acc.add_resolution(ctx, name.to_string(), &def); 31 acc.add_resolution(ctx, name, &def);
32 } 32 }
33 } 33 }
34 } 34 }
@@ -42,11 +42,11 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
42 }); 42 });
43 43
44 match resolution { 44 match resolution {
45 PathResolution::Def(hir::ModuleDef::Module(module)) => { 45 hir::PathResolution::Def(hir::ModuleDef::Module(module)) => {
46 let module_scope = module.scope(ctx.db, context_module); 46 let module_scope = module.scope(ctx.db, context_module);
47 for (name, def) in module_scope { 47 for (name, def) in module_scope {
48 if ctx.use_item_syntax.is_some() { 48 if ctx.use_item_syntax.is_some() {
49 if let ScopeDef::Unknown = def { 49 if let hir::ScopeDef::Unknown = def {
50 if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { 50 if let Some(name_ref) = ctx.name_ref_syntax.as_ref() {
51 if name_ref.syntax().text() == name.to_string().as_str() { 51 if name_ref.syntax().text() == name.to_string().as_str() {
52 // for `use self::foo$0`, don't suggest `foo` as a completion 52 // for `use self::foo$0`, don't suggest `foo` as a completion
@@ -57,20 +57,20 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
57 } 57 }
58 } 58 }
59 59
60 acc.add_resolution(ctx, name.to_string(), &def); 60 acc.add_resolution(ctx, name, &def);
61 } 61 }
62 } 62 }
63 PathResolution::Def(def @ hir::ModuleDef::Adt(_)) 63 hir::PathResolution::Def(def @ hir::ModuleDef::Adt(_))
64 | PathResolution::Def(def @ hir::ModuleDef::TypeAlias(_)) 64 | hir::PathResolution::Def(def @ hir::ModuleDef::TypeAlias(_))
65 | PathResolution::Def(def @ hir::ModuleDef::BuiltinType(_)) => { 65 | hir::PathResolution::Def(def @ hir::ModuleDef::BuiltinType(_)) => {
66 if let hir::ModuleDef::Adt(Adt::Enum(e)) = def { 66 if let hir::ModuleDef::Adt(hir::Adt::Enum(e)) = def {
67 add_enum_variants(ctx, acc, e); 67 add_enum_variants(ctx, acc, e);
68 } 68 }
69 let ty = match def { 69 let ty = match def {
70 hir::ModuleDef::Adt(adt) => adt.ty(ctx.db), 70 hir::ModuleDef::Adt(adt) => adt.ty(ctx.db),
71 hir::ModuleDef::TypeAlias(a) => { 71 hir::ModuleDef::TypeAlias(a) => {
72 let ty = a.ty(ctx.db); 72 let ty = a.ty(ctx.db);
73 if let Some(Adt::Enum(e)) = ty.as_adt() { 73 if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
74 cov_mark::hit!(completes_variant_through_alias); 74 cov_mark::hit!(completes_variant_through_alias);
75 add_enum_variants(ctx, acc, e); 75 add_enum_variants(ctx, acc, e);
76 } 76 }
@@ -117,7 +117,7 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
117 }); 117 });
118 } 118 }
119 } 119 }
120 PathResolution::Def(hir::ModuleDef::Trait(t)) => { 120 hir::PathResolution::Def(hir::ModuleDef::Trait(t)) => {
121 // Handles `Trait::assoc` as well as `<Ty as Trait>::assoc`. 121 // Handles `Trait::assoc` as well as `<Ty as Trait>::assoc`.
122 for item in t.items(ctx.db) { 122 for item in t.items(ctx.db) {
123 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { 123 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) {
@@ -130,15 +130,15 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
130 } 130 }
131 } 131 }
132 } 132 }
133 PathResolution::TypeParam(_) | PathResolution::SelfType(_) => { 133 hir::PathResolution::TypeParam(_) | hir::PathResolution::SelfType(_) => {
134 if let Some(krate) = ctx.krate { 134 if let Some(krate) = ctx.krate {
135 let ty = match resolution { 135 let ty = match resolution {
136 PathResolution::TypeParam(param) => param.ty(ctx.db), 136 hir::PathResolution::TypeParam(param) => param.ty(ctx.db),
137 PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db), 137 hir::PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db),
138 _ => return, 138 _ => return,
139 }; 139 };
140 140
141 if let Some(Adt::Enum(e)) = ty.as_adt() { 141 if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
142 add_enum_variants(ctx, acc, e); 142 add_enum_variants(ctx, acc, e);
143 } 143 }
144 144
diff --git a/crates/ide_completion/src/completions/record.rs b/crates/ide_completion/src/completions/record.rs
index e1526b70b..227c08d01 100644
--- a/crates/ide_completion/src/completions/record.rs
+++ b/crates/ide_completion/src/completions/record.rs
@@ -2,21 +2,21 @@
2use ide_db::{helpers::FamousDefs, SymbolKind}; 2use ide_db::{helpers::FamousDefs, SymbolKind};
3use syntax::ast::Expr; 3use syntax::ast::Expr;
4 4
5use crate::{item::CompletionKind, CompletionContext, CompletionItem, Completions}; 5use crate::{
6 item::CompletionKind, patterns::ImmediateLocation, CompletionContext, CompletionItem,
7 Completions,
8};
6 9
7pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { 10pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
8 let missing_fields = match (ctx.record_pat_syntax.as_ref(), ctx.record_lit_syntax.as_ref()) { 11 let missing_fields = match &ctx.completion_location {
9 (None, None) => return None, 12 Some(ImmediateLocation::RecordExpr(record_expr)) => {
10 (Some(_), Some(_)) => unreachable!("A record cannot be both a literal and a pattern"), 13 let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));
11 (Some(record_pat), _) => ctx.sema.record_pattern_missing_fields(record_pat),
12 (_, Some(record_lit)) => {
13 let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_lit.clone()));
14 let default_trait = FamousDefs(&ctx.sema, ctx.krate).core_default_Default(); 14 let default_trait = FamousDefs(&ctx.sema, ctx.krate).core_default_Default();
15 let impl_default_trait = default_trait 15 let impl_default_trait = default_trait
16 .zip(ty) 16 .zip(ty)
17 .map_or(false, |(default_trait, ty)| ty.impls_trait(ctx.db, default_trait, &[])); 17 .map_or(false, |(default_trait, ty)| ty.impls_trait(ctx.db, default_trait, &[]));
18 18
19 let missing_fields = ctx.sema.record_literal_missing_fields(record_lit); 19 let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
20 if impl_default_trait && !missing_fields.is_empty() { 20 if impl_default_trait && !missing_fields.is_empty() {
21 let completion_text = "..Default::default()"; 21 let completion_text = "..Default::default()";
22 let mut item = CompletionItem::new( 22 let mut item = CompletionItem::new(
@@ -32,6 +32,10 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
32 32
33 missing_fields 33 missing_fields
34 } 34 }
35 Some(ImmediateLocation::RecordPat(record_pat)) => {
36 ctx.sema.record_pattern_missing_fields(record_pat)
37 }
38 _ => return None,
35 }; 39 };
36 40
37 for (field, ty) in missing_fields { 41 for (field, ty) in missing_fields {
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs
index ede07f605..9db8516d0 100644
--- a/crates/ide_completion/src/completions/unqualified_path.rs
+++ b/crates/ide_completion/src/completions/unqualified_path.rs
@@ -14,10 +14,10 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
14 if ctx.expects_assoc_item() { 14 if ctx.expects_assoc_item() {
15 ctx.scope.process_all_names(&mut |name, def| { 15 ctx.scope.process_all_names(&mut |name, def| {
16 if let ScopeDef::MacroDef(macro_def) = def { 16 if let ScopeDef::MacroDef(macro_def) = def {
17 acc.add_macro(ctx, Some(name.to_string()), macro_def); 17 acc.add_macro(ctx, Some(name.clone()), macro_def);
18 } 18 }
19 if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def { 19 if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
20 acc.add_resolution(ctx, name.to_string(), &def); 20 acc.add_resolution(ctx, name, &def);
21 } 21 }
22 }); 22 });
23 return; 23 return;
@@ -27,7 +27,7 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
27 cov_mark::hit!(only_completes_modules_in_import); 27 cov_mark::hit!(only_completes_modules_in_import);
28 ctx.scope.process_all_names(&mut |name, res| { 28 ctx.scope.process_all_names(&mut |name, res| {
29 if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res { 29 if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
30 acc.add_resolution(ctx, name.to_string(), &res); 30 acc.add_resolution(ctx, name, &res);
31 } 31 }
32 }); 32 });
33 return; 33 return;
@@ -45,7 +45,7 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
45 cov_mark::hit!(skip_lifetime_completion); 45 cov_mark::hit!(skip_lifetime_completion);
46 return; 46 return;
47 } 47 }
48 acc.add_resolution(ctx, name.to_string(), &res); 48 acc.add_resolution(ctx, name, &res);
49 }); 49 });
50} 50}
51 51