From 68fd1ce3139ca6517f2c46ad12866147aca6b178 Mon Sep 17 00:00:00 2001 From: feniljain Date: Mon, 12 Dec 2022 16:48:55 +0530 Subject: [PATCH 1/7] feat: bump variant suggestion for enums in patterns completion --- crates/ide-completion/src/completions.rs | 2 ++ crates/ide-completion/src/render/pattern.rs | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index 296dfc1425..cac5dccde2 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -496,6 +496,7 @@ impl Completions { variant, local_name.clone(), None, + false, )); } @@ -514,6 +515,7 @@ impl Completions { variant, None, path, + true, )); } diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index c845ff21aa..edb727b57d 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -7,6 +7,7 @@ use syntax::SmolStr; use crate::{ context::{ParamContext, ParamKind, PathCompletionCtx, PatternContext}, + item::CompletionRelevanceTypeMatch, render::{ variant::{format_literal_label, format_literal_lookup, visible_fields}, RenderContext, @@ -37,7 +38,7 @@ pub(crate) fn render_struct_pat( let lookup = format_literal_lookup(name.as_str(), kind); let pat = render_pat(&ctx, pattern_ctx, &escaped_name, kind, &visible_fields, fields_omitted)?; - Some(build_completion(ctx, label, lookup, pat, strukt)) + Some(build_completion(ctx, label, lookup, pat, strukt, false)) } pub(crate) fn render_variant_pat( @@ -47,6 +48,7 @@ pub(crate) fn render_variant_pat( variant: hir::Variant, local_name: Option, path: Option<&hir::ModPath>, + is_exact_type_match: bool, ) -> Option { let _p = profile::span("render_variant_pat"); @@ -81,7 +83,7 @@ pub(crate) fn render_variant_pat( } }; - Some(build_completion(ctx, label, lookup, pat, variant)) + Some(build_completion(ctx, label, lookup, pat, variant, is_exact_type_match)) } fn build_completion( @@ -90,13 +92,20 @@ fn build_completion( lookup: SmolStr, pat: String, def: impl HasAttrs + Copy, + is_exact_type_match: bool, ) -> CompletionItem { + let mut relevance = ctx.completion_relevance(); + + if is_exact_type_match { + relevance.type_match = Some(CompletionRelevanceTypeMatch::Exact); + } + let mut item = CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), label); item.set_documentation(ctx.docs(def)) .set_deprecated(ctx.is_deprecated(def)) .detail(&pat) .lookup_by(lookup) - .set_relevance(ctx.completion_relevance()); + .set_relevance(relevance); match ctx.snippet_cap() { Some(snippet_cap) => item.insert_snippet(snippet_cap, pat), None => item.insert_text(pat), From 794988c53b2ae41cabc23ee1dfb20e7d13b7dc3f Mon Sep 17 00:00:00 2001 From: feniljain Date: Sat, 17 Dec 2022 16:58:42 +0530 Subject: [PATCH 2/7] feat: filter already present enum variants in match arms --- crates/ide-completion/src/completions.rs | 25 +++++---- crates/ide-completion/src/completions/expr.rs | 1 + .../src/completions/flyimport.rs | 5 +- .../ide-completion/src/completions/pattern.rs | 1 + crates/ide-completion/src/context.rs | 2 + crates/ide-completion/src/context/analysis.rs | 53 ++++++++++++++++++- crates/ide-completion/src/render/pattern.rs | 2 +- crates/ide-completion/src/tests/record.rs | 41 ++++++++++++++ 8 files changed, 114 insertions(+), 16 deletions(-) diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index cac5dccde2..fddd02fc13 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -23,7 +23,7 @@ pub(crate) mod env_vars; use std::iter; -use hir::{known, ScopeDef}; +use hir::{known, ScopeDef, Variant}; use ide_db::{imports::import_assets::LocatedImport, SymbolKind}; use syntax::ast; @@ -538,18 +538,25 @@ fn enum_variants_with_paths( enum_: hir::Enum, impl_: &Option, cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::Variant, hir::ModPath), + missing_variants: Option>, ) { - let variants = enum_.variants(ctx.db); + let mut process_variant = |variant: Variant| { + let self_path = hir::ModPath::from_segments( + hir::PathKind::Plain, + iter::once(known::SELF_TYPE).chain(iter::once(variant.name(ctx.db))), + ); + + cb(acc, ctx, variant, self_path); + }; + + let variants = match missing_variants { + Some(missing_variants) => missing_variants, + None => enum_.variants(ctx.db), + }; if let Some(impl_) = impl_.as_ref().and_then(|impl_| ctx.sema.to_def(impl_)) { if impl_.self_ty(ctx.db).as_adt() == Some(hir::Adt::Enum(enum_)) { - for &variant in &variants { - let self_path = hir::ModPath::from_segments( - hir::PathKind::Plain, - iter::once(known::SELF_TYPE).chain(iter::once(variant.name(ctx.db))), - ); - cb(acc, ctx, variant, self_path); - } + variants.iter().for_each(|variant| process_variant(*variant)); } } diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs index 3192b21cfb..8946011280 100644 --- a/crates/ide-completion/src/completions/expr.rs +++ b/crates/ide-completion/src/completions/expr.rs @@ -208,6 +208,7 @@ pub(crate) fn complete_expr_path( |acc, ctx, variant, path| { acc.add_qualified_enum_variant(ctx, path_ctx, variant, path) }, + None, ); } } diff --git a/crates/ide-completion/src/completions/flyimport.rs b/crates/ide-completion/src/completions/flyimport.rs index 364969af9c..0979f6a6df 100644 --- a/crates/ide-completion/src/completions/flyimport.rs +++ b/crates/ide-completion/src/completions/flyimport.rs @@ -5,10 +5,7 @@ use ide_db::imports::{ insert_use::ImportScope, }; use itertools::Itertools; -use syntax::{ - ast::{self}, - AstNode, SyntaxNode, T, -}; +use syntax::{ast, AstNode, SyntaxNode, T}; use crate::{ context::{ diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs index 58d5bf114c..6ad6a06f11 100644 --- a/crates/ide-completion/src/completions/pattern.rs +++ b/crates/ide-completion/src/completions/pattern.rs @@ -58,6 +58,7 @@ pub(crate) fn complete_pattern( |acc, ctx, variant, path| { acc.add_qualified_variant_pat(ctx, pattern_ctx, variant, path); }, + Some(pattern_ctx.missing_variants.clone()), ); } } diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index aa77f44953..954e88e093 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -220,6 +220,8 @@ pub(super) struct PatternContext { /// The record pattern this name or ref is a field of pub(super) record_pat: Option, pub(super) impl_: Option, + /// List of missing variants in a match expr + pub(super) missing_variants: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index c142a7305f..73375250b5 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -1,7 +1,7 @@ //! Module responsible for analyzing the code surrounding the cursor for completion. use std::iter; -use hir::{Semantics, Type, TypeInfo}; +use hir::{Semantics, Type, TypeInfo, Variant}; use ide_db::{active_parameter::ActiveParameter, RootDatabase}; use syntax::{ algo::{find_node_at_offset, non_trivia_sibling}, @@ -1111,6 +1111,9 @@ fn pattern_context_for( pat: ast::Pat, ) -> PatternContext { let mut param_ctx = None; + + let mut missing_variants = vec![]; + let (refutability, has_type_ascription) = pat .syntax() @@ -1140,7 +1143,52 @@ fn pattern_context_for( })(); return (PatternRefutability::Irrefutable, has_type_ascription) }, - ast::MatchArm(_) => PatternRefutability::Refutable, + ast::MatchArm(match_arm) => { + let missing_variants_opt = match_arm + .syntax() + .parent() + .and_then(ast::MatchArmList::cast) + .and_then(|match_arm_list| { + match_arm_list + .syntax() + .parent() + .and_then(ast::MatchExpr::cast) + .and_then(|match_expr| { + let expr_opt = find_opt_node_in_file(&original_file, match_expr.expr()); + + expr_opt.and_then(|expr| { + sema.type_of_expr(&expr)? + .adjusted() + .autoderef(sema.db) + .find_map(|ty| match ty.as_adt() { + Some(hir::Adt::Enum(e)) => Some(e), + _ => None, + }).and_then(|enum_| { + Some(enum_.variants(sema.db)) + }) + }) + }).and_then(|variants| { + Some(variants.iter().filter_map(|variant| { + let variant_name = variant.name(sema.db).to_string(); + + let variant_already_present = match_arm_list.arms().any(|arm| { + arm.pat().and_then(|pat| { + let pat_already_present = pat.syntax().to_string().contains(&variant_name); + pat_already_present.then(|| pat_already_present) + }).is_some() + }); + + (!variant_already_present).then_some(variant.clone()) + }).collect::>()) + }) + }); + + if let Some(missing_variants_) = missing_variants_opt { + missing_variants = missing_variants_; + }; + + PatternRefutability::Refutable + }, ast::LetExpr(_) => PatternRefutability::Refutable, ast::ForExpr(_) => PatternRefutability::Irrefutable, _ => PatternRefutability::Irrefutable, @@ -1162,6 +1210,7 @@ fn pattern_context_for( ref_token, record_pat: None, impl_: fetch_immediate_impl(sema, original_file, pat.syntax()), + missing_variants, } } diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index edb727b57d..9cf766ce66 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -38,7 +38,7 @@ pub(crate) fn render_struct_pat( let lookup = format_literal_lookup(name.as_str(), kind); let pat = render_pat(&ctx, pattern_ctx, &escaped_name, kind, &visible_fields, fields_omitted)?; - Some(build_completion(ctx, label, lookup, pat, strukt, false)) + Some(build_completion(ctx, label, lookup, pat, strukt, true)) } pub(crate) fn render_variant_pat( diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs index 328faaa060..8b8c56d1d5 100644 --- a/crates/ide-completion/src/tests/record.rs +++ b/crates/ide-completion/src/tests/record.rs @@ -46,6 +46,47 @@ fn foo(s: Struct) { ); } +#[test] +fn record_pattern_field_enum() { + check( + r#" +enum Baz { FOO, BAR } + +fn foo(baz: Baz) { + match baz { + Baz::FOO => (), + $0 + } +} +"#, + expect![[r#" + en Baz + bn Baz::BAR Baz::BAR$0 + kw mut + kw ref + "#]], + ); + + check( + r#" +enum Baz { FOO, BAR } + +fn foo(baz: Baz) { + match baz { + FOO => (), + $0 + } +} +"#, + expect![[r#" + en Baz + bn Baz::BAR Baz::BAR$0 + kw mut + kw ref + "#]], + ); +} + #[test] fn pattern_enum_variant() { check( From a10372dac6e0e5abc222330dc2c9de89bcf0c4fc Mon Sep 17 00:00:00 2001 From: feniljain Date: Tue, 14 Mar 2023 11:41:25 +0530 Subject: [PATCH 3/7] fix: use compute_type_match correctly and update tests accordingly --- crates/ide-completion/src/completions.rs | 2 -- crates/ide-completion/src/render/pattern.rs | 15 ++++++------ crates/ide-completion/src/tests/record.rs | 26 ++++++++++++++++----- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index fddd02fc13..ec8a23e907 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -496,7 +496,6 @@ impl Completions { variant, local_name.clone(), None, - false, )); } @@ -515,7 +514,6 @@ impl Completions { variant, None, path, - true, )); } diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index 9cf766ce66..37c65abba9 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -7,7 +7,6 @@ use syntax::SmolStr; use crate::{ context::{ParamContext, ParamKind, PathCompletionCtx, PatternContext}, - item::CompletionRelevanceTypeMatch, render::{ variant::{format_literal_label, format_literal_lookup, visible_fields}, RenderContext, @@ -38,7 +37,9 @@ pub(crate) fn render_struct_pat( let lookup = format_literal_lookup(name.as_str(), kind); let pat = render_pat(&ctx, pattern_ctx, &escaped_name, kind, &visible_fields, fields_omitted)?; - Some(build_completion(ctx, label, lookup, pat, strukt, true)) + let db = ctx.db(); + + Some(build_completion(ctx, label, lookup, pat, strukt, strukt.ty(db))) } pub(crate) fn render_variant_pat( @@ -48,12 +49,12 @@ pub(crate) fn render_variant_pat( variant: hir::Variant, local_name: Option, path: Option<&hir::ModPath>, - is_exact_type_match: bool, ) -> Option { let _p = profile::span("render_variant_pat"); let fields = variant.fields(ctx.db()); let (visible_fields, fields_omitted) = visible_fields(ctx.completion, &fields, variant)?; + let enum_ty = variant.parent_enum(ctx.db()).ty(ctx.db()); let (name, escaped_name) = match path { Some(path) => (path.unescaped().to_string().into(), path.to_string().into()), @@ -83,7 +84,7 @@ pub(crate) fn render_variant_pat( } }; - Some(build_completion(ctx, label, lookup, pat, variant, is_exact_type_match)) + Some(build_completion(ctx, label, lookup, pat, variant, enum_ty)) } fn build_completion( @@ -92,13 +93,11 @@ fn build_completion( lookup: SmolStr, pat: String, def: impl HasAttrs + Copy, - is_exact_type_match: bool, + adt_ty: hir::Type, ) -> CompletionItem { let mut relevance = ctx.completion_relevance(); - if is_exact_type_match { - relevance.type_match = Some(CompletionRelevanceTypeMatch::Exact); - } + relevance.type_match = super::compute_type_match(ctx.completion, &adt_ty); let mut item = CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), label); item.set_documentation(ctx.docs(def)) diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs index 8b8c56d1d5..b9f157d199 100644 --- a/crates/ide-completion/src/tests/record.rs +++ b/crates/ide-completion/src/tests/record.rs @@ -50,6 +50,7 @@ fn foo(s: Struct) { fn record_pattern_field_enum() { check( r#" +//- minicore:result enum Baz { FOO, BAR } fn foo(baz: Baz) { @@ -61,7 +62,13 @@ fn foo(baz: Baz) { "#, expect![[r#" en Baz + en Result + md core + ev Err + ev Ok bn Baz::BAR Baz::BAR$0 + bn Err(…) Err($1)$0 + bn Ok(…) Ok($1)$0 kw mut kw ref "#]], @@ -69,6 +76,7 @@ fn foo(baz: Baz) { check( r#" +//- minicore:result enum Baz { FOO, BAR } fn foo(baz: Baz) { @@ -77,13 +85,19 @@ fn foo(baz: Baz) { $0 } } -"#, + "#, expect![[r#" - en Baz - bn Baz::BAR Baz::BAR$0 - kw mut - kw ref - "#]], + en Baz + en Result + md core + ev Err + ev Ok + bn Baz::BAR Baz::BAR$0 + bn Err(…) Err($1)$0 + bn Ok(…) Ok($1)$0 + kw mut + kw ref + "#]], ); } From d03c78979810ba7da446480f43b4893fcacdd317 Mon Sep 17 00:00:00 2001 From: feniljain Date: Wed, 15 Mar 2023 10:11:43 +0530 Subject: [PATCH 4/7] chore: change casing for variants in tests --- crates/ide-completion/src/tests/record.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs index b9f157d199..727114610e 100644 --- a/crates/ide-completion/src/tests/record.rs +++ b/crates/ide-completion/src/tests/record.rs @@ -51,11 +51,11 @@ fn record_pattern_field_enum() { check( r#" //- minicore:result -enum Baz { FOO, BAR } +enum Baz { Foo, Bar } fn foo(baz: Baz) { match baz { - Baz::FOO => (), + Baz::Foo => (), $0 } } @@ -66,7 +66,7 @@ fn foo(baz: Baz) { md core ev Err ev Ok - bn Baz::BAR Baz::BAR$0 + bn Baz::Bar Baz::Bar$0 bn Err(…) Err($1)$0 bn Ok(…) Ok($1)$0 kw mut @@ -77,11 +77,11 @@ fn foo(baz: Baz) { check( r#" //- minicore:result -enum Baz { FOO, BAR } +enum Baz { Foo, Bar } fn foo(baz: Baz) { match baz { - FOO => (), + Foo => (), $0 } } @@ -92,7 +92,7 @@ fn foo(baz: Baz) { md core ev Err ev Ok - bn Baz::BAR Baz::BAR$0 + bn Baz::Bar Baz::Bar$0 bn Err(…) Err($1)$0 bn Ok(…) Ok($1)$0 kw mut From 6778d1a6ebf865250c83398c0b2a984413284c47 Mon Sep 17 00:00:00 2001 From: feniljain Date: Thu, 16 Mar 2023 22:52:35 +0530 Subject: [PATCH 5/7] feat: do not remove other variants, just push them down in list --- crates/ide-completion/src/completions.rs | 6 +----- crates/ide-completion/src/completions/expr.rs | 1 - crates/ide-completion/src/completions/pattern.rs | 1 - crates/ide-completion/src/render.rs | 13 ++++++++++++- crates/ide-completion/src/render/pattern.rs | 11 +++++++++-- crates/ide-completion/src/tests/record.rs | 2 ++ 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index ec8a23e907..50be5c788f 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -536,7 +536,6 @@ fn enum_variants_with_paths( enum_: hir::Enum, impl_: &Option, cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::Variant, hir::ModPath), - missing_variants: Option>, ) { let mut process_variant = |variant: Variant| { let self_path = hir::ModPath::from_segments( @@ -547,10 +546,7 @@ fn enum_variants_with_paths( cb(acc, ctx, variant, self_path); }; - let variants = match missing_variants { - Some(missing_variants) => missing_variants, - None => enum_.variants(ctx.db), - }; + let variants = enum_.variants(ctx.db); if let Some(impl_) = impl_.as_ref().and_then(|impl_| ctx.sema.to_def(impl_)) { if impl_.self_ty(ctx.db).as_adt() == Some(hir::Adt::Enum(enum_)) { diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs index 8946011280..3192b21cfb 100644 --- a/crates/ide-completion/src/completions/expr.rs +++ b/crates/ide-completion/src/completions/expr.rs @@ -208,7 +208,6 @@ pub(crate) fn complete_expr_path( |acc, ctx, variant, path| { acc.add_qualified_enum_variant(ctx, path_ctx, variant, path) }, - None, ); } } diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs index 6ad6a06f11..58d5bf114c 100644 --- a/crates/ide-completion/src/completions/pattern.rs +++ b/crates/ide-completion/src/completions/pattern.rs @@ -58,7 +58,6 @@ pub(crate) fn complete_pattern( |acc, ctx, variant, path| { acc.add_qualified_variant_pat(ctx, pattern_ctx, variant, path); }, - Some(pattern_ctx.missing_variants.clone()), ); } } diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index 86302cb067..eb2df395c4 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -32,11 +32,22 @@ pub(crate) struct RenderContext<'a> { completion: &'a CompletionContext<'a>, is_private_editable: bool, import_to_add: Option, + // For variants which are missing + // in match completion context + // + // Option -> only applicable for enums + // bool -> is enum variant missing or not? + is_variant_missing: Option, } impl<'a> RenderContext<'a> { pub(crate) fn new(completion: &'a CompletionContext<'a>) -> RenderContext<'a> { - RenderContext { completion, is_private_editable: false, import_to_add: None } + RenderContext { + completion, + is_private_editable: false, + import_to_add: None, + is_variant_missing: None, + } } pub(crate) fn private_editable(mut self, private_editable: bool) -> Self { diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index 37c65abba9..d70f02127d 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -43,7 +43,7 @@ pub(crate) fn render_struct_pat( } pub(crate) fn render_variant_pat( - ctx: RenderContext<'_>, + mut ctx: RenderContext<'_>, pattern_ctx: &PatternContext, path_ctx: Option<&PathCompletionCtx>, variant: hir::Variant, @@ -56,6 +56,11 @@ pub(crate) fn render_variant_pat( let (visible_fields, fields_omitted) = visible_fields(ctx.completion, &fields, variant)?; let enum_ty = variant.parent_enum(ctx.db()).ty(ctx.db()); + // Missing in context of match statement completions + if pattern_ctx.missing_variants.contains(&variant) { + ctx.is_variant_missing = Some(true); + } + let (name, escaped_name) = match path { Some(path) => (path.unescaped().to_string().into(), path.to_string().into()), None => { @@ -97,7 +102,9 @@ fn build_completion( ) -> CompletionItem { let mut relevance = ctx.completion_relevance(); - relevance.type_match = super::compute_type_match(ctx.completion, &adt_ty); + if let Some(true) = ctx.is_variant_missing { + relevance.type_match = super::compute_type_match(ctx.completion, &adt_ty); + } let mut item = CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), label); item.set_documentation(ctx.docs(def)) diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs index 727114610e..2de42e8435 100644 --- a/crates/ide-completion/src/tests/record.rs +++ b/crates/ide-completion/src/tests/record.rs @@ -67,6 +67,7 @@ fn foo(baz: Baz) { ev Err ev Ok bn Baz::Bar Baz::Bar$0 + bn Baz::Foo Baz::Foo$0 bn Err(…) Err($1)$0 bn Ok(…) Ok($1)$0 kw mut @@ -93,6 +94,7 @@ fn foo(baz: Baz) { ev Err ev Ok bn Baz::Bar Baz::Bar$0 + bn Baz::Foo Baz::Foo$0 bn Err(…) Err($1)$0 bn Ok(…) Ok($1)$0 kw mut From f7113685b563f2b20e770ee1e901b2b93ccbc990 Mon Sep 17 00:00:00 2001 From: feniljain Date: Sat, 18 Mar 2023 11:43:45 +0530 Subject: [PATCH 6/7] fix: make tests valid rust code --- crates/ide-completion/src/tests/record.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs index 2de42e8435..65cefdb085 100644 --- a/crates/ide-completion/src/tests/record.rs +++ b/crates/ide-completion/src/tests/record.rs @@ -81,6 +81,7 @@ fn foo(baz: Baz) { enum Baz { Foo, Bar } fn foo(baz: Baz) { + use Baz::*; match baz { Foo => (), $0 @@ -91,12 +92,14 @@ fn foo(baz: Baz) { en Baz en Result md core + ev Bar ev Err + ev Foo ev Ok - bn Baz::Bar Baz::Bar$0 - bn Baz::Foo Baz::Foo$0 - bn Err(…) Err($1)$0 - bn Ok(…) Ok($1)$0 + bn Bar Bar$0 + bn Err(…) Err($1)$0 + bn Foo Foo$0 + bn Ok(…) Ok($1)$0 kw mut kw ref "#]], From a79a76a94274c22676e2047039cf68ca199c07dd Mon Sep 17 00:00:00 2001 From: feniljain Date: Sat, 18 Mar 2023 11:43:57 +0530 Subject: [PATCH 7/7] refactor: pass is_variant_missing as args to build_completion --- crates/ide-completion/src/render.rs | 13 +----------- crates/ide-completion/src/render/pattern.rs | 23 +++++++++++++-------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index eb2df395c4..86302cb067 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -32,22 +32,11 @@ pub(crate) struct RenderContext<'a> { completion: &'a CompletionContext<'a>, is_private_editable: bool, import_to_add: Option, - // For variants which are missing - // in match completion context - // - // Option -> only applicable for enums - // bool -> is enum variant missing or not? - is_variant_missing: Option, } impl<'a> RenderContext<'a> { pub(crate) fn new(completion: &'a CompletionContext<'a>) -> RenderContext<'a> { - RenderContext { - completion, - is_private_editable: false, - import_to_add: None, - is_variant_missing: None, - } + RenderContext { completion, is_private_editable: false, import_to_add: None } } pub(crate) fn private_editable(mut self, private_editable: bool) -> Self { diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index d70f02127d..fcc7899815 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -39,11 +39,11 @@ pub(crate) fn render_struct_pat( let db = ctx.db(); - Some(build_completion(ctx, label, lookup, pat, strukt, strukt.ty(db))) + Some(build_completion(ctx, label, lookup, pat, strukt, strukt.ty(db), false)) } pub(crate) fn render_variant_pat( - mut ctx: RenderContext<'_>, + ctx: RenderContext<'_>, pattern_ctx: &PatternContext, path_ctx: Option<&PathCompletionCtx>, variant: hir::Variant, @@ -56,11 +56,6 @@ pub(crate) fn render_variant_pat( let (visible_fields, fields_omitted) = visible_fields(ctx.completion, &fields, variant)?; let enum_ty = variant.parent_enum(ctx.db()).ty(ctx.db()); - // Missing in context of match statement completions - if pattern_ctx.missing_variants.contains(&variant) { - ctx.is_variant_missing = Some(true); - } - let (name, escaped_name) = match path { Some(path) => (path.unescaped().to_string().into(), path.to_string().into()), None => { @@ -89,7 +84,15 @@ pub(crate) fn render_variant_pat( } }; - Some(build_completion(ctx, label, lookup, pat, variant, enum_ty)) + Some(build_completion( + ctx, + label, + lookup, + pat, + variant, + enum_ty, + pattern_ctx.missing_variants.contains(&variant), + )) } fn build_completion( @@ -99,10 +102,12 @@ fn build_completion( pat: String, def: impl HasAttrs + Copy, adt_ty: hir::Type, + // Missing in context of match statement completions + is_variant_missing: bool, ) -> CompletionItem { let mut relevance = ctx.completion_relevance(); - if let Some(true) = ctx.is_variant_missing { + if is_variant_missing { relevance.type_match = super::compute_type_match(ctx.completion, &adt_ty); }