diff options
-rw-r--r-- | crates/completion/src/completions/pattern.rs | 57 | ||||
-rw-r--r-- | crates/completion/src/context.rs | 3 |
2 files changed, 46 insertions, 14 deletions
diff --git a/crates/completion/src/completions/pattern.rs b/crates/completion/src/completions/pattern.rs index 7ab7f09fe..4f63ff0ef 100644 --- a/crates/completion/src/completions/pattern.rs +++ b/crates/completion/src/completions/pattern.rs | |||
@@ -4,7 +4,7 @@ use crate::{CompletionContext, Completions}; | |||
4 | 4 | ||
5 | /// Completes constats and paths in patterns. | 5 | /// Completes constats 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 { | 7 | if !(ctx.is_pat_binding_or_const || ctx.is_irrefutable_let_pat_binding) { |
8 | return; | 8 | return; |
9 | } | 9 | } |
10 | if ctx.record_pat_syntax.is_some() { | 10 | if ctx.record_pat_syntax.is_some() { |
@@ -14,20 +14,27 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | |||
14 | // FIXME: ideally, we should look at the type we are matching against and | 14 | // FIXME: ideally, we should look at the type we are matching against and |
15 | // suggest variants + auto-imports | 15 | // suggest variants + auto-imports |
16 | ctx.scope.process_all_names(&mut |name, res| { | 16 | ctx.scope.process_all_names(&mut |name, res| { |
17 | match &res { | 17 | let add_resolution = match &res { |
18 | hir::ScopeDef::ModuleDef(def) => match def { | 18 | hir::ScopeDef::ModuleDef(def) => { |
19 | hir::ModuleDef::Adt(hir::Adt::Enum(..)) | 19 | if ctx.is_irrefutable_let_pat_binding { |
20 | | hir::ModuleDef::Adt(hir::Adt::Struct(..)) | 20 | matches!(def, hir::ModuleDef::Adt(hir::Adt::Struct(_))) |
21 | | hir::ModuleDef::EnumVariant(..) | 21 | } else { |
22 | | hir::ModuleDef::Const(..) | 22 | matches!( |
23 | | hir::ModuleDef::Module(..) => (), | 23 | def, |
24 | _ => return, | 24 | hir::ModuleDef::Adt(hir::Adt::Enum(..)) |
25 | }, | 25 | | hir::ModuleDef::Adt(hir::Adt::Struct(..)) |
26 | hir::ScopeDef::MacroDef(_) => (), | 26 | | hir::ModuleDef::EnumVariant(..) |
27 | _ => return, | 27 | | hir::ModuleDef::Const(..) |
28 | | hir::ModuleDef::Module(..) | ||
29 | ) | ||
30 | } | ||
31 | } | ||
32 | hir::ScopeDef::MacroDef(_) => true, | ||
33 | _ => false, | ||
28 | }; | 34 | }; |
29 | 35 | if add_resolution { | |
30 | acc.add_resolution(ctx, name.to_string(), &res) | 36 | acc.add_resolution(ctx, name.to_string(), &res); |
37 | } | ||
31 | }); | 38 | }); |
32 | } | 39 | } |
33 | 40 | ||
@@ -85,4 +92,26 @@ fn foo() { | |||
85 | "#]], | 92 | "#]], |
86 | ); | 93 | ); |
87 | } | 94 | } |
95 | |||
96 | #[test] | ||
97 | fn completes_in_irrefutable_let() { | ||
98 | check( | ||
99 | r#" | ||
100 | enum E { X } | ||
101 | use self::E::X; | ||
102 | const Z: E = E::X; | ||
103 | mod m {} | ||
104 | |||
105 | static FOO: E = E::X; | ||
106 | struct Bar { f: u32 } | ||
107 | |||
108 | fn foo() { | ||
109 | let <|> | ||
110 | } | ||
111 | "#, | ||
112 | expect![[r#" | ||
113 | st Bar | ||
114 | "#]], | ||
115 | ); | ||
116 | } | ||
88 | } | 117 | } |
diff --git a/crates/completion/src/context.rs b/crates/completion/src/context.rs index bf70ee478..5cd11cf77 100644 --- a/crates/completion/src/context.rs +++ b/crates/completion/src/context.rs | |||
@@ -51,6 +51,7 @@ pub(crate) struct CompletionContext<'a> { | |||
51 | /// If a name-binding or reference to a const in a pattern. | 51 | /// If a name-binding or reference to a const in a pattern. |
52 | /// Irrefutable patterns (like let) are excluded. | 52 | /// Irrefutable patterns (like let) are excluded. |
53 | pub(super) is_pat_binding_or_const: bool, | 53 | pub(super) is_pat_binding_or_const: bool, |
54 | pub(super) is_irrefutable_let_pat_binding: bool, | ||
54 | /// A single-indent path, like `foo`. `::foo` should not be considered a trivial path. | 55 | /// A single-indent path, like `foo`. `::foo` should not be considered a trivial path. |
55 | pub(super) is_trivial_path: bool, | 56 | pub(super) is_trivial_path: bool, |
56 | /// If not a trivial path, the prefix (qualifier). | 57 | /// If not a trivial path, the prefix (qualifier). |
@@ -146,6 +147,7 @@ impl<'a> CompletionContext<'a> { | |||
146 | active_parameter: ActiveParameter::at(db, position), | 147 | active_parameter: ActiveParameter::at(db, position), |
147 | is_param: false, | 148 | is_param: false, |
148 | is_pat_binding_or_const: false, | 149 | is_pat_binding_or_const: false, |
150 | is_irrefutable_let_pat_binding: false, | ||
149 | is_trivial_path: false, | 151 | is_trivial_path: false, |
150 | path_qual: None, | 152 | path_qual: None, |
151 | after_if: false, | 153 | after_if: false, |
@@ -330,6 +332,7 @@ impl<'a> CompletionContext<'a> { | |||
330 | if pat.syntax().text_range().contains_range(bind_pat.syntax().text_range()) | 332 | if pat.syntax().text_range().contains_range(bind_pat.syntax().text_range()) |
331 | { | 333 | { |
332 | self.is_pat_binding_or_const = false; | 334 | self.is_pat_binding_or_const = false; |
335 | self.is_irrefutable_let_pat_binding = true; | ||
333 | } | 336 | } |
334 | } | 337 | } |
335 | } | 338 | } |