diff options
Diffstat (limited to 'crates/ide_completion/src/completions/qualified_path.rs')
-rw-r--r-- | crates/ide_completion/src/completions/qualified_path.rs | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs index 969249df6..eedb44873 100644 --- a/crates/ide_completion/src/completions/qualified_path.rs +++ b/crates/ide_completion/src/completions/qualified_path.rs | |||
@@ -52,18 +52,24 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
52 | | PathResolution::Def(def @ hir::ModuleDef::TypeAlias(_)) | 52 | | PathResolution::Def(def @ hir::ModuleDef::TypeAlias(_)) |
53 | | PathResolution::Def(def @ hir::ModuleDef::BuiltinType(_)) => { | 53 | | PathResolution::Def(def @ hir::ModuleDef::BuiltinType(_)) => { |
54 | if let hir::ModuleDef::Adt(Adt::Enum(e)) = def { | 54 | if let hir::ModuleDef::Adt(Adt::Enum(e)) = def { |
55 | for variant in e.variants(ctx.db) { | 55 | add_enum_variants(ctx, acc, e); |
56 | acc.add_enum_variant(ctx, variant, None); | ||
57 | } | ||
58 | } | 56 | } |
59 | let ty = match def { | 57 | let ty = match def { |
60 | hir::ModuleDef::Adt(adt) => adt.ty(ctx.db), | 58 | hir::ModuleDef::Adt(adt) => adt.ty(ctx.db), |
61 | hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db), | 59 | hir::ModuleDef::TypeAlias(a) => { |
60 | let ty = a.ty(ctx.db); | ||
61 | if let Some(Adt::Enum(e)) = ty.as_adt() { | ||
62 | cov_mark::hit!(completes_variant_through_alias); | ||
63 | add_enum_variants(ctx, acc, e); | ||
64 | } | ||
65 | ty | ||
66 | } | ||
62 | hir::ModuleDef::BuiltinType(builtin) => { | 67 | hir::ModuleDef::BuiltinType(builtin) => { |
63 | let module = match ctx.scope.module() { | 68 | let module = match ctx.scope.module() { |
64 | Some(it) => it, | 69 | Some(it) => it, |
65 | None => return, | 70 | None => return, |
66 | }; | 71 | }; |
72 | cov_mark::hit!(completes_primitive_assoc_const); | ||
67 | builtin.ty(ctx.db, module) | 73 | builtin.ty(ctx.db, module) |
68 | } | 74 | } |
69 | _ => unreachable!(), | 75 | _ => unreachable!(), |
@@ -92,9 +98,8 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
92 | if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { | 98 | if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { |
93 | return None; | 99 | return None; |
94 | } | 100 | } |
95 | match item { | 101 | if let hir::AssocItem::TypeAlias(ty) = item { |
96 | hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => {} | 102 | acc.add_type_alias(ctx, ty) |
97 | hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), | ||
98 | } | 103 | } |
99 | None::<()> | 104 | None::<()> |
100 | }); | 105 | }); |
@@ -122,9 +127,7 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
122 | }; | 127 | }; |
123 | 128 | ||
124 | if let Some(Adt::Enum(e)) = ty.as_adt() { | 129 | if let Some(Adt::Enum(e)) = ty.as_adt() { |
125 | for variant in e.variants(ctx.db) { | 130 | add_enum_variants(ctx, acc, e); |
126 | acc.add_enum_variant(ctx, variant, None); | ||
127 | } | ||
128 | } | 131 | } |
129 | 132 | ||
130 | let traits_in_scope = ctx.scope.traits_in_scope(); | 133 | let traits_in_scope = ctx.scope.traits_in_scope(); |
@@ -151,6 +154,12 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
151 | } | 154 | } |
152 | } | 155 | } |
153 | 156 | ||
157 | fn add_enum_variants(ctx: &CompletionContext, acc: &mut Completions, e: hir::Enum) { | ||
158 | for variant in e.variants(ctx.db) { | ||
159 | acc.add_enum_variant(ctx, variant, None); | ||
160 | } | ||
161 | } | ||
162 | |||
154 | #[cfg(test)] | 163 | #[cfg(test)] |
155 | mod tests { | 164 | mod tests { |
156 | use expect_test::{expect, Expect}; | 165 | use expect_test::{expect, Expect}; |
@@ -737,29 +746,7 @@ fn f() {} | |||
737 | } | 746 | } |
738 | 747 | ||
739 | #[test] | 748 | #[test] |
740 | fn completes_function() { | 749 | fn completes_variant_through_self() { |
741 | check( | ||
742 | r#" | ||
743 | fn foo( | ||
744 | a: i32, | ||
745 | b: i32 | ||
746 | ) { | ||
747 | |||
748 | } | ||
749 | |||
750 | fn main() { | ||
751 | fo$0 | ||
752 | } | ||
753 | "#, | ||
754 | expect![[r#" | ||
755 | fn main() fn() | ||
756 | fn foo(…) fn(i32, i32) | ||
757 | "#]], | ||
758 | ); | ||
759 | } | ||
760 | |||
761 | #[test] | ||
762 | fn completes_self_enum() { | ||
763 | check( | 750 | check( |
764 | r#" | 751 | r#" |
765 | enum Foo { | 752 | enum Foo { |
@@ -783,6 +770,7 @@ impl Foo { | |||
783 | 770 | ||
784 | #[test] | 771 | #[test] |
785 | fn completes_primitive_assoc_const() { | 772 | fn completes_primitive_assoc_const() { |
773 | cov_mark::check!(completes_primitive_assoc_const); | ||
786 | check( | 774 | check( |
787 | r#" | 775 | r#" |
788 | //- /lib.rs crate:lib deps:core | 776 | //- /lib.rs crate:lib deps:core |
@@ -804,4 +792,23 @@ impl u8 { | |||
804 | "#]], | 792 | "#]], |
805 | ); | 793 | ); |
806 | } | 794 | } |
795 | |||
796 | #[test] | ||
797 | fn completes_variant_through_alias() { | ||
798 | cov_mark::check!(completes_variant_through_alias); | ||
799 | check( | ||
800 | r#" | ||
801 | enum Foo { | ||
802 | Bar | ||
803 | } | ||
804 | type Foo2 = Foo; | ||
805 | fn main() { | ||
806 | Foo2::$0 | ||
807 | } | ||
808 | "#, | ||
809 | expect![[r#" | ||
810 | ev Bar () | ||
811 | "#]], | ||
812 | ); | ||
813 | } | ||
807 | } | 814 | } |