diff options
Diffstat (limited to 'crates/ide_completion/src/completions')
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#" | ||
136 | struct Bar { bar: u32 } | ||
137 | |||
138 | fn foo(Bar { bar }: Bar) {} | ||
139 | fn 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 | ||
5 | use syntax::{SyntaxKind, T}; | 5 | use syntax::{SyntaxKind, T}; |
6 | 6 | ||
7 | use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions}; | 7 | use crate::{ |
8 | patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind, | ||
9 | CompletionKind, Completions, | ||
10 | }; | ||
8 | 11 | ||
9 | pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) { | 12 | pub(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 | }; |
10 | use rustc_hash::FxHashSet; | 10 | use rustc_hash::FxHashSet; |
11 | 11 | ||
12 | use crate::CompletionItem; | 12 | use crate::{patterns::ImmediateLocation, CompletionItem}; |
13 | 13 | ||
14 | use crate::{context::CompletionContext, item::CompletionKind, Completions}; | 14 | use crate::{context::CompletionContext, item::CompletionKind, Completions}; |
15 | 15 | ||
16 | /// Complete mod declaration, i.e. `mod $0 ;` | 16 | /// Complete mod declaration, i.e. `mod $0 ;` |
17 | pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { | 17 | pub(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 | ||
3 | use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; | 3 | use hir::HasVisibility; |
4 | use rustc_hash::FxHashSet; | 4 | use rustc_hash::FxHashSet; |
5 | use syntax::AstNode; | 5 | use 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 @@ | |||
2 | use ide_db::{helpers::FamousDefs, SymbolKind}; | 2 | use ide_db::{helpers::FamousDefs, SymbolKind}; |
3 | use syntax::ast::Expr; | 3 | use syntax::ast::Expr; |
4 | 4 | ||
5 | use crate::{item::CompletionKind, CompletionContext, CompletionItem, Completions}; | 5 | use crate::{ |
6 | item::CompletionKind, patterns::ImmediateLocation, CompletionContext, CompletionItem, | ||
7 | Completions, | ||
8 | }; | ||
6 | 9 | ||
7 | pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { | 10 | pub(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 | ||