Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide-completion/src/completions.rs6
-rw-r--r--crates/ide-completion/src/completions/expr.rs1
-rw-r--r--crates/ide-completion/src/completions/pattern.rs1
-rw-r--r--crates/ide-completion/src/completions/use_.rs4
-rw-r--r--crates/ide-completion/src/render/pattern.rs41
-rw-r--r--crates/ide-completion/src/tests/fn_param.rs2
-rw-r--r--crates/ide-completion/src/tests/pattern.rs137
-rw-r--r--crates/ide-completion/src/tests/special.rs1
-rw-r--r--crates/ide-completion/src/tests/use_tree.rs23
9 files changed, 140 insertions, 76 deletions
diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs
index 81bb59681b..1bcbb3aaa6 100644
--- a/crates/ide-completion/src/completions.rs
+++ b/crates/ide-completion/src/completions.rs
@@ -357,6 +357,12 @@ impl Completions {
variant: hir::Variant,
local_name: Option<hir::Name>,
) {
+ if let PathCompletionCtx { kind: PathKind::Pat { pat_ctx }, .. } = path_ctx {
+ cov_mark::hit!(enum_variant_pattern_path);
+ self.add_variant_pat(ctx, pat_ctx, variant, local_name);
+ return;
+ }
+
if let Some(builder) =
render_variant_lit(RenderContext::new(ctx), path_ctx, local_name, variant, None)
{
diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs
index 058d0ab7bb..df0556ba45 100644
--- a/crates/ide-completion/src/completions/expr.rs
+++ b/crates/ide-completion/src/completions/expr.rs
@@ -115,6 +115,7 @@ pub(crate) fn complete_expr_path(
};
if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
+ cov_mark::hit!(completes_variant_through_self);
acc.add_enum_variants(ctx, path_ctx, e);
}
diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs
index 7a344c2c7b..65b6eee188 100644
--- a/crates/ide-completion/src/completions/pattern.rs
+++ b/crates/ide-completion/src/completions/pattern.rs
@@ -151,7 +151,6 @@ pub(crate) fn complete_pattern_path(
};
if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
- cov_mark::hit!(enum_plain_qualified_use_tree);
acc.add_enum_variants(ctx, path_ctx, e);
}
diff --git a/crates/ide-completion/src/completions/use_.rs b/crates/ide-completion/src/completions/use_.rs
index c98590f136..e5689f332d 100644
--- a/crates/ide-completion/src/completions/use_.rs
+++ b/crates/ide-completion/src/completions/use_.rs
@@ -79,9 +79,7 @@ pub(crate) fn complete_use_path(
}
hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Enum(e))) => {
cov_mark::hit!(enum_plain_qualified_use_tree);
- e.variants(ctx.db)
- .into_iter()
- .for_each(|variant| acc.add_enum_variant(ctx, path_ctx, variant, None));
+ acc.add_enum_variants(ctx, path_ctx, *e);
}
_ => {}
}
diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs
index f9c4037dee..d6779961c0 100644
--- a/crates/ide-completion/src/render/pattern.rs
+++ b/crates/ide-completion/src/render/pattern.rs
@@ -7,7 +7,10 @@ use syntax::SmolStr;
use crate::{
context::{ParamKind, PatternContext},
- render::{variant::visible_fields, RenderContext},
+ render::{
+ variant::{format_literal_label, visible_fields},
+ RenderContext,
+ },
CompletionItem, CompletionItemKind,
};
@@ -29,16 +32,11 @@ pub(crate) fn render_struct_pat(
let name = local_name.unwrap_or_else(|| strukt.name(ctx.db()));
let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
- let pat = render_pat(
- &ctx,
- pattern_ctx,
- &escaped_name,
- strukt.kind(ctx.db()),
- &visible_fields,
- fields_omitted,
- )?;
+ let kind = strukt.kind(ctx.db());
+ let label = format_literal_label(name.as_str(), kind);
+ let pat = render_pat(&ctx, pattern_ctx, &escaped_name, kind, &visible_fields, fields_omitted)?;
- Some(build_completion(ctx, name, pat, strukt))
+ Some(build_completion(ctx, label, pat, strukt))
}
pub(crate) fn render_variant_pat(
@@ -60,25 +58,20 @@ pub(crate) fn render_variant_pat(
(name.to_smol_str(), name.escaped().to_smol_str())
}
};
- let pat = render_pat(
- &ctx,
- pattern_ctx,
- &escaped_name,
- variant.kind(ctx.db()),
- &visible_fields,
- fields_omitted,
- )?;
+ let kind = variant.kind(ctx.db());
+ let label = format_literal_label(name.as_str(), kind);
+ let pat = render_pat(&ctx, pattern_ctx, &escaped_name, kind, &visible_fields, fields_omitted)?;
- Some(build_completion(ctx, name, pat, variant))
+ Some(build_completion(ctx, label, pat, variant))
}
fn build_completion(
ctx: RenderContext<'_>,
- name: SmolStr,
+ label: SmolStr,
pat: String,
def: impl HasAttrs + Copy,
) -> CompletionItem {
- let mut item = CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), name);
+ 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)
@@ -103,7 +96,7 @@ fn render_pat(
StructKind::Record => {
render_record_as_pat(ctx.db(), ctx.snippet_cap(), fields, name, fields_omitted)
}
- StructKind::Unit => return None,
+ StructKind::Unit => name.to_string(),
};
let needs_ascription = matches!(
@@ -138,7 +131,7 @@ fn render_record_as_pat(
format!(
"{name} {{ {}{} }}",
fields.enumerate().format_with(", ", |(idx, field), f| {
- f(&format_args!("{}${}", field.name(db), idx + 1))
+ f(&format_args!("{}${}", field.name(db).escaped(), idx + 1))
}),
if fields_omitted { ", .." } else { "" },
name = name
@@ -147,7 +140,7 @@ fn render_record_as_pat(
None => {
format!(
"{name} {{ {}{} }}",
- fields.map(|field| field.name(db)).format(", "),
+ fields.map(|field| field.name(db).escaped().to_smol_str()).format(", "),
if fields_omitted { ", .." } else { "" },
name = name
)
diff --git a/crates/ide-completion/src/tests/fn_param.rs b/crates/ide-completion/src/tests/fn_param.rs
index f5a5b5bae6..cce74604c2 100644
--- a/crates/ide-completion/src/tests/fn_param.rs
+++ b/crates/ide-completion/src/tests/fn_param.rs
@@ -139,8 +139,8 @@ fn foo2($0) {}
"#,
expect![[r#"
st Bar
- bn Bar Bar { bar$1 }: Bar$0
bn Bar { bar }: Bar
+ bn Bar {…} Bar { bar$1 }: Bar$0
kw mut
kw ref
"#]],
diff --git a/crates/ide-completion/src/tests/pattern.rs b/crates/ide-completion/src/tests/pattern.rs
index 7169209d81..63ccf9003b 100644
--- a/crates/ide-completion/src/tests/pattern.rs
+++ b/crates/ide-completion/src/tests/pattern.rs
@@ -1,7 +1,7 @@
//! Completion tests for pattern position.
use expect_test::{expect, Expect};
-use crate::tests::{completion_list, BASE_ITEMS_FIXTURE};
+use crate::tests::{check_edit, completion_list, BASE_ITEMS_FIXTURE};
fn check_empty(ra_fixture: &str, expect: Expect) {
let actual = completion_list(ra_fixture);
@@ -127,15 +127,15 @@ fn foo() {
expect![[r#"
ct CONST
en Enum
- ma makro!(…) macro_rules! makro
+ ma makro!(…) macro_rules! makro
md module
st Record
st Tuple
st Unit
ev TupleV
- bn Record Record { field$1 }$0
- bn Tuple Tuple($1)$0
- bn TupleV TupleV($1)$0
+ bn Record {…} Record { field$1 }$0
+ bn Tuple(…) Tuple($1)$0
+ bn TupleV(…) TupleV($1)$0
kw mut
kw ref
"#]],
@@ -162,8 +162,9 @@ fn foo() {
st Tuple
st Unit
ev Variant
- bn Record Record { field$1 }$0
- bn Tuple Tuple($1)$0
+ bn Record {…} Record { field$1 }$0
+ bn Tuple(…) Tuple($1)$0
+ bn Variant Variant$0
kw mut
kw ref
"#]],
@@ -178,13 +179,13 @@ fn foo(a$0) {
}
"#,
expect![[r#"
- ma makro!(…) macro_rules! makro
+ ma makro!(…) macro_rules! makro
md module
st Record
st Tuple
st Unit
- bn Record Record { field$1 }: Record$0
- bn Tuple Tuple($1): Tuple$0
+ bn Record {…} Record { field$1 }: Record$0
+ bn Tuple(…) Tuple($1): Tuple$0
kw mut
kw ref
"#]],
@@ -195,13 +196,13 @@ fn foo(a$0: Tuple) {
}
"#,
expect![[r#"
- ma makro!(…) macro_rules! makro
+ ma makro!(…) macro_rules! makro
md module
st Record
st Tuple
st Unit
- bn Record Record { field$1 }$0
- bn Tuple Tuple($1)$0
+ bn Record {…} Record { field$1 }$0
+ bn Tuple(…) Tuple($1)$0
kw mut
kw ref
"#]],
@@ -243,6 +244,7 @@ fn foo() {
expect![[r#"
en E
ma m!(…) macro_rules! m
+ bn E::X E::X$0
kw mut
kw ref
"#]],
@@ -269,8 +271,8 @@ fn outer() {
st Invisible
st Record
st Tuple
- bn Record Record { field$1, .. }$0
- bn Tuple Tuple($1, ..)$0
+ bn Record {…} Record { field$1, .. }$0
+ bn Tuple(…) Tuple($1, ..)$0
kw mut
kw ref
"#]],
@@ -293,8 +295,8 @@ impl Foo {
expect![[r#"
sp Self
st Foo
- bn Foo Foo($1)$0
- bn Self Self($1)$0
+ bn Foo(…) Foo($1)$0
+ bn Self(…) Self($1)$0
kw mut
kw ref
"#]],
@@ -316,9 +318,9 @@ fn func() {
"#,
expect![[r#"
ct ASSOC_CONST const ASSOC_CONST: ()
- ev RecordV {…} RecordV { field: u32 }
- ev TupleV(…) TupleV(u32)
- ev UnitV UnitV
+ bn RecordV {…} RecordV { field$1 }$0
+ bn TupleV(…) TupleV($1)$0
+ bn UnitV UnitV$0
"#]],
);
}
@@ -334,8 +336,8 @@ fn outer(Foo { bar: $0 }: Foo) {}
expect![[r#"
st Bar
st Foo
- bn Bar Bar($1)$0
- bn Foo Foo { bar$1 }$0
+ bn Bar(…) Bar($1)$0
+ bn Foo {…} Foo { bar$1 }$0
kw mut
kw ref
"#]],
@@ -368,8 +370,8 @@ fn foo($0) {}
expect![[r#"
st Bar
st Foo
- bn Bar Bar($1): Bar$0
- bn Foo Foo { bar$1 }: Foo$0
+ bn Bar(…) Bar($1): Bar$0
+ bn Foo {…} Foo { bar$1 }: Foo$0
kw mut
kw ref
"#]],
@@ -389,8 +391,8 @@ fn foo() {
expect![[r#"
st Bar
st Foo
- bn Bar Bar($1)$0
- bn Foo Foo { bar$1 }$0
+ bn Bar(…) Bar($1)$0
+ bn Foo {…} Foo { bar$1 }$0
kw mut
kw ref
"#]],
@@ -443,7 +445,7 @@ fn foo() {
}
"#,
expect![[r#"
- ev TupleVariant TupleVariant
+ bn TupleVariant(…) TupleVariant($1)$0
"#]],
);
check_empty(
@@ -458,7 +460,86 @@ fn foo() {
}
"#,
expect![[r#"
- ev RecordVariant RecordVariant
+ bn RecordVariant {…} RecordVariant { field$1 }$0
+ "#]],
+ );
+}
+
+#[test]
+fn completes_enum_variant_pat() {
+ cov_mark::check!(enum_variant_pattern_path);
+ check_edit(
+ "RecordVariant {…}",
+ r#"
+enum Enum {
+ RecordVariant { field: u32 }
+}
+fn foo() {
+ match (Enum::RecordVariant { field: 0 }) {
+ Enum::RecordV$0
+ }
+}
+"#,
+ r#"
+enum Enum {
+ RecordVariant { field: u32 }
+}
+fn foo() {
+ match (Enum::RecordVariant { field: 0 }) {
+ Enum::RecordVariant { field$1 }$0
+ }
+}
+"#,
+ );
+}
+
+#[test]
+fn completes_enum_variant_pat_escape() {
+ cov_mark::check!(enum_variant_pattern_path);
+ check_empty(
+ r#"
+enum Enum {
+ A,
+ B { r#type: i32 },
+ r#type,
+ r#struct { r#type: i32 },
+}
+fn foo() {
+ match (Enum::A) {
+ $0
+ }
+}
+"#,
+ expect![[r#"
+ en Enum
+ bn Enum::A Enum::A$0
+ bn Enum::B {…} Enum::B { r#type$1 }$0
+ bn Enum::struct {…} Enum::r#struct { r#type$1 }$0
+ bn Enum::type Enum::r#type$0
+ kw mut
+ kw ref
+ "#]],
+ );
+
+ check_empty(
+ r#"
+enum Enum {
+ A,
+ B { r#type: i32 },
+ r#type,
+ r#struct { r#type: i32 },
+}
+fn foo() {
+ match (Enum::A) {
+ Enum::$0
+ }
+}
+"#,
+ expect![[r#"
+ bn A A$0
+ bn B {…} B { r#type$1 }$0
+ bn struct {…} r#struct { r#type$1 }$0
+ bn type r#type$0
"#]],
);
}
diff --git a/crates/ide-completion/src/tests/special.rs b/crates/ide-completion/src/tests/special.rs
index 96d0219fef..fc59f781dd 100644
--- a/crates/ide-completion/src/tests/special.rs
+++ b/crates/ide-completion/src/tests/special.rs
@@ -519,6 +519,7 @@ fn foo() {
#[test]
fn completes_variant_through_self() {
+ cov_mark::check!(completes_variant_through_self);
check(
r#"
enum Foo {
diff --git a/crates/ide-completion/src/tests/use_tree.rs b/crates/ide-completion/src/tests/use_tree.rs
index 3134915bda..109007c7a0 100644
--- a/crates/ide-completion/src/tests/use_tree.rs
+++ b/crates/ide-completion/src/tests/use_tree.rs
@@ -165,30 +165,15 @@ fn enum_plain_qualified_use_tree() {
r#"
use Foo::$0
-enum Foo { Variant }
-impl Foo {
- const CONST: () = ()
- fn func() {}
-}
-"#,
- expect![[r#"
- ev Variant Variant
- "#]],
- );
-}
-
-#[test]
-fn enum_no_parens_in_qualified_use_tree() {
- cov_mark::check!(enum_plain_qualified_use_tree);
- check(
- r#"
-use Foo::$0
-
enum Foo {
UnitVariant,
TupleVariant(),
RecordVariant {},
}
+impl Foo {
+ const CONST: () = ()
+ fn func() {}
+}
"#,
expect![[r#"
ev RecordVariant RecordVariant