diff options
Diffstat (limited to 'crates/ide_completion/src/completions')
-rw-r--r-- | crates/ide_completion/src/completions/fn_param.rs | 15 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/keyword.rs | 18 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/mod_.rs | 6 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/record.rs | 20 |
4 files changed, 41 insertions, 18 deletions
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/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/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 { |