diff options
author | Lukas Wirth <[email protected]> | 2021-02-09 20:32:05 +0000 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2021-02-09 20:35:02 +0000 |
commit | 5454559c0a45d208db963df105f22f5e17f0340a (patch) | |
tree | 6038de6fd6a16ad6edef22a4bef9bd323071dc99 /crates/completion/src/completions/unqualified_path.rs | |
parent | 5d4ae1c8e3b76798fcb5eb656d886fe65a2c7277 (diff) |
Show qualified variant pattern completions
Diffstat (limited to 'crates/completion/src/completions/unqualified_path.rs')
-rw-r--r-- | crates/completion/src/completions/unqualified_path.rs | 46 |
1 files changed, 4 insertions, 42 deletions
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs index 5112ecc2d..e9d0ff665 100644 --- a/crates/completion/src/completions/unqualified_path.rs +++ b/crates/completion/src/completions/unqualified_path.rs | |||
@@ -1,8 +1,6 @@ | |||
1 | //! Completion of names from the current scope, e.g. locals and imported items. | 1 | //! Completion of names from the current scope, e.g. locals and imported items. |
2 | 2 | ||
3 | use std::iter; | 3 | use hir::ScopeDef; |
4 | |||
5 | use hir::{known, Adt, ModuleDef, ScopeDef, Type}; | ||
6 | use syntax::AstNode; | 4 | use syntax::AstNode; |
7 | use test_utils::mark; | 5 | use test_utils::mark; |
8 | 6 | ||
@@ -21,7 +19,9 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC | |||
21 | } | 19 | } |
22 | 20 | ||
23 | if let Some(ty) = &ctx.expected_type { | 21 | if let Some(ty) = &ctx.expected_type { |
24 | complete_enum_variants(acc, ctx, ty); | 22 | super::complete_enum_variants(acc, ctx, ty, |acc, ctx, variant, path| { |
23 | acc.add_qualified_enum_variant(ctx, variant, path) | ||
24 | }); | ||
25 | } | 25 | } |
26 | 26 | ||
27 | if ctx.is_pat_binding_or_const { | 27 | if ctx.is_pat_binding_or_const { |
@@ -45,44 +45,6 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC | |||
45 | }); | 45 | }); |
46 | } | 46 | } |
47 | 47 | ||
48 | fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &Type) { | ||
49 | if let Some(Adt::Enum(enum_data)) = | ||
50 | iter::successors(Some(ty.clone()), |ty| ty.remove_ref()).last().and_then(|ty| ty.as_adt()) | ||
51 | { | ||
52 | let variants = enum_data.variants(ctx.db); | ||
53 | |||
54 | let module = if let Some(module) = ctx.scope.module() { | ||
55 | // Compute path from the completion site if available. | ||
56 | module | ||
57 | } else { | ||
58 | // Otherwise fall back to the enum's definition site. | ||
59 | enum_data.module(ctx.db) | ||
60 | }; | ||
61 | |||
62 | if let Some(impl_) = ctx.impl_def.as_ref().and_then(|impl_| ctx.sema.to_def(impl_)) { | ||
63 | if impl_.target_ty(ctx.db) == *ty { | ||
64 | for &variant in &variants { | ||
65 | let self_path = hir::ModPath::from_segments( | ||
66 | hir::PathKind::Plain, | ||
67 | iter::once(known::SELF_TYPE).chain(iter::once(variant.name(ctx.db))), | ||
68 | ); | ||
69 | acc.add_qualified_enum_variant(ctx, variant, self_path.clone()); | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | for variant in variants { | ||
75 | if let Some(path) = module.find_use_path(ctx.db, ModuleDef::from(variant)) { | ||
76 | // Variants with trivial paths are already added by the existing completion logic, | ||
77 | // so we should avoid adding these twice | ||
78 | if path.segments().len() > 1 { | ||
79 | acc.add_qualified_enum_variant(ctx, variant, path); | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | #[cfg(test)] | 48 | #[cfg(test)] |
87 | mod tests { | 49 | mod tests { |
88 | use expect_test::{expect, Expect}; | 50 | use expect_test::{expect, Expect}; |