From a7fc2061eaf0ee56d12ef217629d5a15906830b9 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 10 Dec 2021 18:25:54 +0100 Subject: [PATCH] Show enum completions for single variant enums in irrefutable patterns --- .../ide_completion/src/completions/pattern.rs | 27 ++++++++++--------- crates/ide_completion/src/tests/pattern.rs | 12 ++++++--- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/crates/ide_completion/src/completions/pattern.rs b/crates/ide_completion/src/completions/pattern.rs index 04765901428..b3b27f251f6 100644 --- a/crates/ide_completion/src/completions/pattern.rs +++ b/crates/ide_completion/src/completions/pattern.rs @@ -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(), diff --git a/crates/ide_completion/src/tests/pattern.rs b/crates/ide_completion/src/tests/pattern.rs index 81c45c64cc1..99e20b6ed09 100644 --- a/crates/ide_completion/src/tests/pattern.rs +++ b/crates/ide_completion/src/tests/pattern.rs @@ -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 "##]], ); } -- 2.44.0