]> git.lizzy.rs Git - rust.git/commitdiff
Show enum completions for single variant enums in irrefutable patterns
authorLukas Wirth <lukastw97@gmail.com>
Fri, 10 Dec 2021 17:25:54 +0000 (18:25 +0100)
committerLukas Wirth <lukastw97@gmail.com>
Fri, 10 Dec 2021 17:25:54 +0000 (18:25 +0100)
crates/ide_completion/src/completions/pattern.rs
crates/ide_completion/src/tests/pattern.rs

index 047659014286cfaff8a7ac2de37cc6ae0b365e70..b3b27f251f6f3d520de016e30b24771345a75ee1 100644 (file)
@@ -1,5 +1,7 @@
 //! Completes constants and paths in unqualified patterns.
 
+use hir::db::DefDatabase;
+
 use crate::{
     context::{PatternContext, PatternRefutability},
     CompletionContext, Completions,
@@ -13,11 +15,12 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
         }
         _ => return,
     };
+    let single_variant_enum = |enum_: hir::Enum| ctx.db.enum_data(enum_.into()).variants.len() == 1;
 
-    if refutable {
-        if let Some(hir::Adt::Enum(e)) =
-            ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
-        {
+    if let Some(hir::Adt::Enum(e)) =
+        ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
+    {
+        if refutable || single_variant_enum(e) {
             super::enum_variants_with_paths(acc, ctx, e, |acc, ctx, variant, path| {
                 acc.add_qualified_variant_pat(ctx, variant, path.clone());
                 acc.add_qualified_enum_variant(ctx, variant, path);
@@ -28,20 +31,20 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
     // FIXME: ideally, we should look at the type we are matching against and
     // suggest variants + auto-imports
     ctx.process_all_names(&mut |name, res| {
-        let add_resolution = match &res {
+        let add_resolution = match res {
             hir::ScopeDef::ModuleDef(def) => match def {
                 hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => {
-                    acc.add_struct_pat(ctx, *strukt, Some(name.clone()));
+                    acc.add_struct_pat(ctx, strukt, Some(name.clone()));
                     true
                 }
-                hir::ModuleDef::Variant(variant) if refutable => {
-                    acc.add_variant_pat(ctx, *variant, Some(name.clone()));
+                hir::ModuleDef::Variant(variant)
+                    if refutable || single_variant_enum(variant.parent_enum(ctx.db)) =>
+                {
+                    acc.add_variant_pat(ctx, variant, Some(name.clone()));
                     true
                 }
-                hir::ModuleDef::Adt(hir::Adt::Enum(..))
-                | hir::ModuleDef::Variant(..)
-                | hir::ModuleDef::Const(..)
-                | hir::ModuleDef::Module(..) => refutable,
+                hir::ModuleDef::Adt(hir::Adt::Enum(e)) => refutable || single_variant_enum(e),
+                hir::ModuleDef::Const(..) | hir::ModuleDef::Module(..) => refutable,
                 _ => false,
             },
             hir::ScopeDef::MacroDef(mac) => mac.is_fn_like(),
index 81c45c64cc1d24333b9e99efa2a2a9545f5dd42f..99e20b6ed092c35dc59e6209e75fc1d24cbd003f 100644 (file)
@@ -130,18 +130,24 @@ fn foo() {
 fn irrefutable() {
     check(
         r#"
+enum SingleVariantEnum {
+    Variant
+}
+use SingleVariantEnum::Variant;
 fn foo() {
    let a$0
 }
 "#,
         expect![[r##"
             kw mut
-            bn Record    Record { field$1 }$0
+            bn Record            Record { field$1 }$0
             st Record
-            bn Tuple     Tuple($1)$0
+            bn Tuple             Tuple($1)$0
             st Tuple
+            ev Variant
+            en SingleVariantEnum
             st Unit
-            ma makro!(…) #[macro_export] macro_rules! makro
+            ma makro!(…)         #[macro_export] macro_rules! makro
         "##]],
     );
 }