diff options
Diffstat (limited to 'crates/ide_completion/src/completions')
9 files changed, 115 insertions, 91 deletions
diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs index 9d5b61562..be9cfbded 100644 --- a/crates/ide_completion/src/completions/flyimport.rs +++ b/crates/ide_completion/src/completions/flyimport.rs | |||
@@ -110,13 +110,7 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext) | |||
110 | if !ctx.config.enable_imports_on_the_fly { | 110 | if !ctx.config.enable_imports_on_the_fly { |
111 | return None; | 111 | return None; |
112 | } | 112 | } |
113 | if ctx.use_item_syntax.is_some() | 113 | if ctx.use_item_syntax.is_some() || ctx.is_path_disallowed() { |
114 | || ctx.attribute_under_caret.is_some() | ||
115 | || ctx.mod_declaration_under_caret.is_some() | ||
116 | || ctx.record_lit_syntax.is_some() | ||
117 | || ctx.has_trait_parent | ||
118 | || ctx.has_impl_parent | ||
119 | { | ||
120 | return None; | 114 | return None; |
121 | } | 115 | } |
122 | let potential_import_name = { | 116 | let potential_import_name = { |
diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index 61b667104..58e35bad9 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::iter; | 3 | use std::iter; |
4 | 4 | ||
5 | use syntax::SyntaxKind; | 5 | use syntax::{SyntaxKind, T}; |
6 | 6 | ||
7 | use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions}; | 7 | use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions}; |
8 | 8 | ||
@@ -49,78 +49,75 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
49 | return; | 49 | return; |
50 | } | 50 | } |
51 | 51 | ||
52 | let has_trait_or_impl_parent = ctx.has_impl_parent || ctx.has_trait_parent; | 52 | let has_trait_or_impl_parent = ctx.has_impl_or_trait_parent(); |
53 | if ctx.trait_as_prev_sibling || ctx.impl_as_prev_sibling { | 53 | let has_block_expr_parent = ctx.has_block_expr_parent(); |
54 | let has_item_list_parent = ctx.has_item_list_parent(); | ||
55 | if ctx.has_impl_or_trait_prev_sibling() { | ||
54 | add_keyword(ctx, acc, "where", "where "); | 56 | add_keyword(ctx, acc, "where", "where "); |
55 | return; | 57 | return; |
56 | } | 58 | } |
57 | if ctx.unsafe_is_prev { | 59 | if ctx.previous_token_is(T![unsafe]) { |
58 | if ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent { | 60 | if has_item_list_parent || has_block_expr_parent { |
59 | add_keyword(ctx, acc, "fn", "fn $0() {}") | 61 | add_keyword(ctx, acc, "fn", "fn $1($2) {\n $0\n}") |
60 | } | 62 | } |
61 | 63 | ||
62 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { | 64 | if has_item_list_parent || has_block_expr_parent { |
63 | add_keyword(ctx, acc, "trait", "trait $0 {}"); | 65 | add_keyword(ctx, acc, "trait", "trait $1 {\n $0\n}"); |
64 | add_keyword(ctx, acc, "impl", "impl $0 {}"); | 66 | add_keyword(ctx, acc, "impl", "impl $1 {\n $0\n}"); |
65 | } | 67 | } |
66 | 68 | ||
67 | return; | 69 | return; |
68 | } | 70 | } |
69 | if ctx.has_item_list_or_source_file_parent || has_trait_or_impl_parent || ctx.block_expr_parent | 71 | if has_item_list_parent || has_trait_or_impl_parent || has_block_expr_parent { |
70 | { | 72 | add_keyword(ctx, acc, "fn", "fn $1($2) {\n $0\n}"); |
71 | add_keyword(ctx, acc, "fn", "fn $0() {}"); | ||
72 | } | 73 | } |
73 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { | 74 | if has_item_list_parent || has_block_expr_parent { |
74 | add_keyword(ctx, acc, "use", "use "); | 75 | add_keyword(ctx, acc, "use", "use "); |
75 | add_keyword(ctx, acc, "impl", "impl $0 {}"); | 76 | add_keyword(ctx, acc, "impl", "impl $1 {\n $0\n}"); |
76 | add_keyword(ctx, acc, "trait", "trait $0 {}"); | 77 | add_keyword(ctx, acc, "trait", "trait $1 {\n $0\n}"); |
77 | } | 78 | } |
78 | 79 | ||
79 | if ctx.has_item_list_or_source_file_parent { | 80 | if has_item_list_parent { |
80 | add_keyword(ctx, acc, "enum", "enum $0 {}"); | 81 | add_keyword(ctx, acc, "enum", "enum $1 {\n $0\n}"); |
81 | add_keyword(ctx, acc, "struct", "struct $0"); | 82 | add_keyword(ctx, acc, "struct", "struct $0"); |
82 | add_keyword(ctx, acc, "union", "union $0 {}"); | 83 | add_keyword(ctx, acc, "union", "union $1 {\n $0\n}"); |
83 | } | 84 | } |
84 | 85 | ||
85 | if ctx.is_expr { | 86 | if ctx.is_expr { |
86 | add_keyword(ctx, acc, "match", "match $0 {}"); | 87 | add_keyword(ctx, acc, "match", "match $1 {\n $0\n}"); |
87 | add_keyword(ctx, acc, "while", "while $0 {}"); | 88 | add_keyword(ctx, acc, "while", "while $1 {\n $0\n}"); |
88 | add_keyword(ctx, acc, "while let", "while let $1 = $0 {}"); | 89 | add_keyword(ctx, acc, "while let", "while let $1 = $2 {\n $0\n}"); |
89 | add_keyword(ctx, acc, "loop", "loop {$0}"); | 90 | add_keyword(ctx, acc, "loop", "loop {\n $0\n}"); |
90 | add_keyword(ctx, acc, "if", "if $0 {}"); | 91 | add_keyword(ctx, acc, "if", "if $1 {\n $0\n}"); |
91 | add_keyword(ctx, acc, "if let", "if let $1 = $0 {}"); | 92 | add_keyword(ctx, acc, "if let", "if let $1 = $2 {\n $0\n}"); |
92 | add_keyword(ctx, acc, "for", "for $1 in $0 {}"); | 93 | add_keyword(ctx, acc, "for", "for $1 in $2 {\n $0\n}"); |
93 | } | 94 | } |
94 | 95 | ||
95 | if ctx.if_is_prev || ctx.block_expr_parent { | 96 | if ctx.previous_token_is(T![if]) || ctx.previous_token_is(T![while]) || has_block_expr_parent { |
96 | add_keyword(ctx, acc, "let", "let "); | 97 | add_keyword(ctx, acc, "let", "let "); |
97 | } | 98 | } |
98 | 99 | ||
99 | if ctx.after_if { | 100 | if ctx.after_if { |
100 | add_keyword(ctx, acc, "else", "else {$0}"); | 101 | add_keyword(ctx, acc, "else", "else {\n $0\n}"); |
101 | add_keyword(ctx, acc, "else if", "else if $0 {}"); | 102 | add_keyword(ctx, acc, "else if", "else if $1 {\n $0\n}"); |
102 | } | 103 | } |
103 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { | 104 | if has_item_list_parent || has_block_expr_parent { |
104 | add_keyword(ctx, acc, "mod", "mod $0"); | 105 | add_keyword(ctx, acc, "mod", "mod $0"); |
105 | } | 106 | } |
106 | if ctx.bind_pat_parent || ctx.ref_pat_parent { | 107 | if ctx.has_ident_or_ref_pat_parent() { |
107 | add_keyword(ctx, acc, "mut", "mut "); | 108 | add_keyword(ctx, acc, "mut", "mut "); |
108 | } | 109 | } |
109 | if ctx.has_item_list_or_source_file_parent || has_trait_or_impl_parent || ctx.block_expr_parent | 110 | if has_item_list_parent || has_trait_or_impl_parent || has_block_expr_parent { |
110 | { | ||
111 | add_keyword(ctx, acc, "const", "const "); | 111 | add_keyword(ctx, acc, "const", "const "); |
112 | add_keyword(ctx, acc, "type", "type "); | 112 | add_keyword(ctx, acc, "type", "type "); |
113 | } | 113 | } |
114 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { | 114 | if has_item_list_parent || has_block_expr_parent { |
115 | add_keyword(ctx, acc, "static", "static "); | 115 | add_keyword(ctx, acc, "static", "static "); |
116 | }; | 116 | }; |
117 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { | 117 | if has_item_list_parent || has_block_expr_parent { |
118 | add_keyword(ctx, acc, "extern", "extern "); | 118 | add_keyword(ctx, acc, "extern", "extern "); |
119 | } | 119 | } |
120 | if ctx.has_item_list_or_source_file_parent | 120 | if has_item_list_parent || has_trait_or_impl_parent || has_block_expr_parent || ctx.is_match_arm |
121 | || has_trait_or_impl_parent | ||
122 | || ctx.block_expr_parent | ||
123 | || ctx.is_match_arm | ||
124 | { | 121 | { |
125 | add_keyword(ctx, acc, "unsafe", "unsafe "); | 122 | add_keyword(ctx, acc, "unsafe", "unsafe "); |
126 | } | 123 | } |
@@ -133,7 +130,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
133 | add_keyword(ctx, acc, "break", "break"); | 130 | add_keyword(ctx, acc, "break", "break"); |
134 | } | 131 | } |
135 | } | 132 | } |
136 | if ctx.has_item_list_or_source_file_parent || ctx.has_impl_parent | ctx.has_field_list_parent { | 133 | if has_item_list_parent || ctx.has_impl_parent() || ctx.has_field_list_parent() { |
137 | add_keyword(ctx, acc, "pub(crate)", "pub(crate) "); | 134 | add_keyword(ctx, acc, "pub(crate)", "pub(crate) "); |
138 | add_keyword(ctx, acc, "pub", "pub "); | 135 | add_keyword(ctx, acc, "pub", "pub "); |
139 | } | 136 | } |
@@ -141,7 +138,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
141 | if !ctx.is_trivial_path { | 138 | if !ctx.is_trivial_path { |
142 | return; | 139 | return; |
143 | } | 140 | } |
144 | let fn_def = match &ctx.function_syntax { | 141 | let fn_def = match &ctx.function_def { |
145 | Some(it) => it, | 142 | Some(it) => it, |
146 | None => return, | 143 | None => return, |
147 | }; | 144 | }; |
@@ -342,7 +339,9 @@ mod tests { | |||
342 | check_edit( | 339 | check_edit( |
343 | "else", | 340 | "else", |
344 | r#"fn quux() { if true { () } $0 }"#, | 341 | r#"fn quux() { if true { () } $0 }"#, |
345 | r#"fn quux() { if true { () } else {$0} }"#, | 342 | r#"fn quux() { if true { () } else { |
343 | $0 | ||
344 | } }"#, | ||
346 | ); | 345 | ); |
347 | } | 346 | } |
348 | 347 | ||
@@ -646,7 +645,9 @@ fn foo() { | |||
646 | fn main() { let x = $0 } | 645 | fn main() { let x = $0 } |
647 | "#, | 646 | "#, |
648 | r#" | 647 | r#" |
649 | fn main() { let x = match $0 {}; } | 648 | fn main() { let x = match $1 { |
649 | $0 | ||
650 | }; } | ||
650 | "#, | 651 | "#, |
651 | ); | 652 | ); |
652 | 653 | ||
@@ -660,7 +661,9 @@ fn main() { | |||
660 | "#, | 661 | "#, |
661 | r#" | 662 | r#" |
662 | fn main() { | 663 | fn main() { |
663 | let x = if $0 {}; | 664 | let x = if $1 { |
665 | $0 | ||
666 | }; | ||
664 | let y = 92; | 667 | let y = 92; |
665 | } | 668 | } |
666 | "#, | 669 | "#, |
@@ -676,7 +679,9 @@ fn main() { | |||
676 | "#, | 679 | "#, |
677 | r#" | 680 | r#" |
678 | fn main() { | 681 | fn main() { |
679 | let x = loop {$0}; | 682 | let x = loop { |
683 | $0 | ||
684 | }; | ||
680 | bar(); | 685 | bar(); |
681 | } | 686 | } |
682 | "#, | 687 | "#, |
diff --git a/crates/ide_completion/src/completions/lifetime.rs b/crates/ide_completion/src/completions/lifetime.rs index 5eeddf7a4..5f6285b84 100644 --- a/crates/ide_completion/src/completions/lifetime.rs +++ b/crates/ide_completion/src/completions/lifetime.rs | |||
@@ -8,19 +8,24 @@ pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext) | |||
8 | if !ctx.lifetime_allowed { | 8 | if !ctx.lifetime_allowed { |
9 | return; | 9 | return; |
10 | } | 10 | } |
11 | let lp_string; | ||
11 | let param_lifetime = match ( | 12 | let param_lifetime = match ( |
12 | &ctx.lifetime_syntax, | 13 | &ctx.lifetime_syntax, |
13 | ctx.lifetime_param_syntax.as_ref().and_then(|lp| lp.lifetime()), | 14 | ctx.lifetime_param_syntax.as_ref().and_then(|lp| lp.lifetime()), |
14 | ) { | 15 | ) { |
15 | (Some(lt), Some(lp)) if lp == lt.clone() => return, | 16 | (Some(lt), Some(lp)) if lp == lt.clone() => return, |
16 | (Some(_), Some(lp)) => Some(lp.to_string()), | 17 | (Some(_), Some(lp)) => { |
18 | lp_string = lp.to_string(); | ||
19 | Some(&lp_string) | ||
20 | } | ||
17 | _ => None, | 21 | _ => None, |
18 | }; | 22 | }; |
19 | 23 | ||
20 | ctx.scope.process_all_names(&mut |name, res| { | 24 | ctx.scope.process_all_names(&mut |name, res| { |
21 | if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res { | 25 | if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res { |
22 | if param_lifetime != Some(name.to_string()) { | 26 | let name = name.to_string(); |
23 | acc.add_resolution(ctx, name.to_string(), &res); | 27 | if param_lifetime != Some(&name) { |
28 | acc.add_resolution(ctx, name, &res); | ||
24 | } | 29 | } |
25 | } | 30 | } |
26 | }); | 31 | }); |
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 2be299ac2..c5e377500 100644 --- a/crates/ide_completion/src/completions/macro_in_item_position.rs +++ b/crates/ide_completion/src/completions/macro_in_item_position.rs | |||
@@ -4,13 +4,15 @@ use crate::{CompletionContext, Completions}; | |||
4 | 4 | ||
5 | pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { | 5 | pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { |
6 | // Show only macros in top level. | 6 | // Show only macros in top level. |
7 | if ctx.is_new_item { | 7 | if !ctx.is_new_item { |
8 | ctx.scope.process_all_names(&mut |name, res| { | 8 | return; |
9 | if let hir::ScopeDef::MacroDef(mac) = res { | ||
10 | acc.add_macro(ctx, Some(name.to_string()), mac); | ||
11 | } | ||
12 | }) | ||
13 | } | 9 | } |
10 | |||
11 | ctx.scope.process_all_names(&mut |name, res| { | ||
12 | if let hir::ScopeDef::MacroDef(mac) = res { | ||
13 | acc.add_macro(ctx, Some(name.to_string()), mac); | ||
14 | } | ||
15 | }) | ||
14 | } | 16 | } |
15 | 17 | ||
16 | #[cfg(test)] | 18 | #[cfg(test)] |
diff --git a/crates/ide_completion/src/completions/pattern.rs b/crates/ide_completion/src/completions/pattern.rs index 8dc9ab73c..b84e9a967 100644 --- a/crates/ide_completion/src/completions/pattern.rs +++ b/crates/ide_completion/src/completions/pattern.rs | |||
@@ -1,17 +1,15 @@ | |||
1 | //! Completes constants and paths in patterns. | 1 | //! Completes constants and paths in patterns. |
2 | 2 | ||
3 | use crate::{CompletionContext, Completions}; | 3 | use crate::{context::PatternRefutability, CompletionContext, Completions}; |
4 | 4 | ||
5 | /// Completes constants and paths in patterns. | 5 | /// Completes constants and paths in patterns. |
6 | pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | 6 | pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { |
7 | if !(ctx.is_pat_binding_or_const || ctx.is_irrefutable_pat_binding) { | 7 | let refutable = match ctx.is_pat_or_const { |
8 | return; | 8 | Some(it) => it == PatternRefutability::Refutable, |
9 | } | 9 | None => return, |
10 | if ctx.record_pat_syntax.is_some() { | 10 | }; |
11 | return; | ||
12 | } | ||
13 | 11 | ||
14 | if !ctx.is_irrefutable_pat_binding { | 12 | if refutable { |
15 | if let Some(hir::Adt::Enum(e)) = | 13 | if let Some(hir::Adt::Enum(e)) = |
16 | ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt()) | 14 | ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt()) |
17 | { | 15 | { |
@@ -31,14 +29,14 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | |||
31 | acc.add_struct_pat(ctx, *strukt, Some(name.clone())); | 29 | acc.add_struct_pat(ctx, *strukt, Some(name.clone())); |
32 | true | 30 | true |
33 | } | 31 | } |
34 | hir::ModuleDef::Variant(variant) if !ctx.is_irrefutable_pat_binding => { | 32 | hir::ModuleDef::Variant(variant) if refutable => { |
35 | acc.add_variant_pat(ctx, *variant, Some(name.clone())); | 33 | acc.add_variant_pat(ctx, *variant, Some(name.clone())); |
36 | true | 34 | true |
37 | } | 35 | } |
38 | hir::ModuleDef::Adt(hir::Adt::Enum(..)) | 36 | hir::ModuleDef::Adt(hir::Adt::Enum(..)) |
39 | | hir::ModuleDef::Variant(..) | 37 | | hir::ModuleDef::Variant(..) |
40 | | hir::ModuleDef::Const(..) | 38 | | hir::ModuleDef::Const(..) |
41 | | hir::ModuleDef::Module(..) => !ctx.is_irrefutable_pat_binding, | 39 | | hir::ModuleDef::Module(..) => refutable, |
42 | _ => false, | 40 | _ => false, |
43 | }, | 41 | }, |
44 | hir::ScopeDef::MacroDef(_) => true, | 42 | hir::ScopeDef::MacroDef(_) => true, |
@@ -47,7 +45,7 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | |||
47 | acc.add_struct_pat(ctx, strukt, Some(name.clone())); | 45 | acc.add_struct_pat(ctx, strukt, Some(name.clone())); |
48 | true | 46 | true |
49 | } | 47 | } |
50 | Some(hir::Adt::Enum(_)) => !ctx.is_irrefutable_pat_binding, | 48 | Some(hir::Adt::Enum(_)) => refutable, |
51 | _ => true, | 49 | _ => true, |
52 | }, | 50 | }, |
53 | _ => false, | 51 | _ => false, |
@@ -402,4 +400,31 @@ impl Foo { | |||
402 | "#]], | 400 | "#]], |
403 | ) | 401 | ) |
404 | } | 402 | } |
403 | |||
404 | #[test] | ||
405 | fn completes_in_record_field_pat() { | ||
406 | check_snippet( | ||
407 | r#" | ||
408 | struct Foo { bar: Bar } | ||
409 | struct Bar(u32); | ||
410 | fn outer(Foo { bar: $0 }: Foo) {} | ||
411 | "#, | ||
412 | expect![[r#" | ||
413 | bn Foo Foo { bar$1 }$0 | ||
414 | bn Bar Bar($1)$0 | ||
415 | "#]], | ||
416 | ) | ||
417 | } | ||
418 | |||
419 | #[test] | ||
420 | fn skips_in_record_field_pat_name() { | ||
421 | check_snippet( | ||
422 | r#" | ||
423 | struct Foo { bar: Bar } | ||
424 | struct Bar(u32); | ||
425 | fn outer(Foo { bar$0 }: Foo) {} | ||
426 | "#, | ||
427 | expect![[r#""#]], | ||
428 | ) | ||
429 | } | ||
405 | } | 430 | } |
diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs index eedb44873..ed48f61af 100644 --- a/crates/ide_completion/src/completions/qualified_path.rs +++ b/crates/ide_completion/src/completions/qualified_path.rs | |||
@@ -7,21 +7,19 @@ use syntax::AstNode; | |||
7 | use crate::{CompletionContext, Completions}; | 7 | use crate::{CompletionContext, Completions}; |
8 | 8 | ||
9 | pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { | 9 | pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { |
10 | if ctx.is_path_disallowed() { | ||
11 | return; | ||
12 | } | ||
10 | let path = match &ctx.path_qual { | 13 | let path = match &ctx.path_qual { |
11 | Some(path) => path.clone(), | 14 | Some(path) => path.clone(), |
12 | None => return, | 15 | None => return, |
13 | }; | 16 | }; |
14 | 17 | ||
15 | if ctx.attribute_under_caret.is_some() || ctx.mod_declaration_under_caret.is_some() { | ||
16 | return; | ||
17 | } | ||
18 | |||
19 | let context_module = ctx.scope.module(); | ||
20 | |||
21 | let resolution = match ctx.sema.resolve_path(&path) { | 18 | let resolution = match ctx.sema.resolve_path(&path) { |
22 | Some(res) => res, | 19 | Some(res) => res, |
23 | None => return, | 20 | None => return, |
24 | }; | 21 | }; |
22 | let context_module = ctx.scope.module(); | ||
25 | 23 | ||
26 | // Add associated types on type parameters and `Self`. | 24 | // Add associated types on type parameters and `Self`. |
27 | resolution.assoc_type_shorthand_candidates(ctx.db, |_, alias| { | 25 | resolution.assoc_type_shorthand_candidates(ctx.db, |_, alias| { |
diff --git a/crates/ide_completion/src/completions/record.rs b/crates/ide_completion/src/completions/record.rs index 40006fb74..e1526b70b 100644 --- a/crates/ide_completion/src/completions/record.rs +++ b/crates/ide_completion/src/completions/record.rs | |||
@@ -13,20 +13,19 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> | |||
13 | let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_lit.clone())); | 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 | .and_then(|default_trait| ty.map(|ty| ty.impls_trait(ctx.db, default_trait, &[]))) | 16 | .zip(ty) |
17 | .unwrap_or(false); | 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_lit); |
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 completion_text = completion_text | ||
23 | .strip_prefix(ctx.token.to_string().as_str()) | ||
24 | .unwrap_or(completion_text); | ||
25 | let mut item = CompletionItem::new( | 22 | let mut item = CompletionItem::new( |
26 | CompletionKind::Snippet, | 23 | CompletionKind::Snippet, |
27 | ctx.source_range(), | 24 | ctx.source_range(), |
28 | "..Default::default()", | 25 | completion_text, |
29 | ); | 26 | ); |
27 | let completion_text = | ||
28 | completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text); | ||
30 | item.insert_text(completion_text).kind(SymbolKind::Field); | 29 | item.insert_text(completion_text).kind(SymbolKind::Field); |
31 | item.add_to(acc); | 30 | item.add_to(acc); |
32 | } | 31 | } |
diff --git a/crates/ide_completion/src/completions/snippet.rs b/crates/ide_completion/src/completions/snippet.rs index 14cfb61de..defc25b00 100644 --- a/crates/ide_completion/src/completions/snippet.rs +++ b/crates/ide_completion/src/completions/snippet.rs | |||
@@ -14,7 +14,7 @@ fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) | |||
14 | } | 14 | } |
15 | 15 | ||
16 | pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) { | 16 | pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) { |
17 | if !(ctx.is_trivial_path && ctx.function_syntax.is_some()) { | 17 | if !(ctx.is_trivial_path && ctx.function_def.is_some()) { |
18 | return; | 18 | return; |
19 | } | 19 | } |
20 | let cap = match ctx.config.snippet_cap { | 20 | let cap = match ctx.config.snippet_cap { |
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs index 7875500c1..046a393ae 100644 --- a/crates/ide_completion/src/completions/unqualified_path.rs +++ b/crates/ide_completion/src/completions/unqualified_path.rs | |||
@@ -9,11 +9,7 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC | |||
9 | if !ctx.is_trivial_path { | 9 | if !ctx.is_trivial_path { |
10 | return; | 10 | return; |
11 | } | 11 | } |
12 | if ctx.record_lit_syntax.is_some() | 12 | if ctx.is_path_disallowed() { |
13 | || ctx.record_pat_syntax.is_some() | ||
14 | || ctx.attribute_under_caret.is_some() | ||
15 | || ctx.mod_declaration_under_caret.is_some() | ||
16 | { | ||
17 | return; | 13 | return; |
18 | } | 14 | } |
19 | 15 | ||
@@ -86,7 +82,7 @@ fn quux(x: Option<Enum>) { | |||
86 | } | 82 | } |
87 | } | 83 | } |
88 | "#, | 84 | "#, |
89 | expect![[""]], | 85 | expect![[r#""#]], |
90 | ); | 86 | ); |
91 | } | 87 | } |
92 | 88 | ||
@@ -102,7 +98,7 @@ fn quux(x: Option<Enum>) { | |||
102 | } | 98 | } |
103 | } | 99 | } |
104 | "#, | 100 | "#, |
105 | expect![[""]], | 101 | expect![[r#""#]], |
106 | ); | 102 | ); |
107 | } | 103 | } |
108 | 104 | ||