diff options
Diffstat (limited to 'crates/ide_completion/src/completions/pattern.rs')
-rw-r--r-- | crates/ide_completion/src/completions/pattern.rs | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/crates/ide_completion/src/completions/pattern.rs b/crates/ide_completion/src/completions/pattern.rs index 8dc9ab73c..b84e9a967 100644 --- a/crates/ide_completion/src/completions/pattern.rs +++ b/crates/ide_completion/src/completions/pattern.rs | |||
@@ -1,17 +1,15 @@ | |||
1 | //! Completes constants and paths in patterns. | 1 | //! Completes constants and paths in patterns. |
2 | 2 | ||
3 | use crate::{CompletionContext, Completions}; | 3 | use crate::{context::PatternRefutability, CompletionContext, Completions}; |
4 | 4 | ||
5 | /// Completes constants and paths in patterns. | 5 | /// Completes constants and paths in patterns. |
6 | pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | 6 | pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { |
7 | if !(ctx.is_pat_binding_or_const || ctx.is_irrefutable_pat_binding) { | 7 | let refutable = match ctx.is_pat_or_const { |
8 | return; | 8 | Some(it) => it == PatternRefutability::Refutable, |
9 | } | 9 | None => return, |
10 | if ctx.record_pat_syntax.is_some() { | 10 | }; |
11 | return; | ||
12 | } | ||
13 | 11 | ||
14 | if !ctx.is_irrefutable_pat_binding { | 12 | if refutable { |
15 | if let Some(hir::Adt::Enum(e)) = | 13 | if let Some(hir::Adt::Enum(e)) = |
16 | ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt()) | 14 | ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt()) |
17 | { | 15 | { |
@@ -31,14 +29,14 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | |||
31 | acc.add_struct_pat(ctx, *strukt, Some(name.clone())); | 29 | acc.add_struct_pat(ctx, *strukt, Some(name.clone())); |
32 | true | 30 | true |
33 | } | 31 | } |
34 | hir::ModuleDef::Variant(variant) if !ctx.is_irrefutable_pat_binding => { | 32 | hir::ModuleDef::Variant(variant) if refutable => { |
35 | acc.add_variant_pat(ctx, *variant, Some(name.clone())); | 33 | acc.add_variant_pat(ctx, *variant, Some(name.clone())); |
36 | true | 34 | true |
37 | } | 35 | } |
38 | hir::ModuleDef::Adt(hir::Adt::Enum(..)) | 36 | hir::ModuleDef::Adt(hir::Adt::Enum(..)) |
39 | | hir::ModuleDef::Variant(..) | 37 | | hir::ModuleDef::Variant(..) |
40 | | hir::ModuleDef::Const(..) | 38 | | hir::ModuleDef::Const(..) |
41 | | hir::ModuleDef::Module(..) => !ctx.is_irrefutable_pat_binding, | 39 | | hir::ModuleDef::Module(..) => refutable, |
42 | _ => false, | 40 | _ => false, |
43 | }, | 41 | }, |
44 | hir::ScopeDef::MacroDef(_) => true, | 42 | hir::ScopeDef::MacroDef(_) => true, |
@@ -47,7 +45,7 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | |||
47 | acc.add_struct_pat(ctx, strukt, Some(name.clone())); | 45 | acc.add_struct_pat(ctx, strukt, Some(name.clone())); |
48 | true | 46 | true |
49 | } | 47 | } |
50 | Some(hir::Adt::Enum(_)) => !ctx.is_irrefutable_pat_binding, | 48 | Some(hir::Adt::Enum(_)) => refutable, |
51 | _ => true, | 49 | _ => true, |
52 | }, | 50 | }, |
53 | _ => false, | 51 | _ => false, |
@@ -402,4 +400,31 @@ impl Foo { | |||
402 | "#]], | 400 | "#]], |
403 | ) | 401 | ) |
404 | } | 402 | } |
403 | |||
404 | #[test] | ||
405 | fn completes_in_record_field_pat() { | ||
406 | check_snippet( | ||
407 | r#" | ||
408 | struct Foo { bar: Bar } | ||
409 | struct Bar(u32); | ||
410 | fn outer(Foo { bar: $0 }: Foo) {} | ||
411 | "#, | ||
412 | expect![[r#" | ||
413 | bn Foo Foo { bar$1 }$0 | ||
414 | bn Bar Bar($1)$0 | ||
415 | "#]], | ||
416 | ) | ||
417 | } | ||
418 | |||
419 | #[test] | ||
420 | fn skips_in_record_field_pat_name() { | ||
421 | check_snippet( | ||
422 | r#" | ||
423 | struct Foo { bar: Bar } | ||
424 | struct Bar(u32); | ||
425 | fn outer(Foo { bar$0 }: Foo) {} | ||
426 | "#, | ||
427 | expect![[r#""#]], | ||
428 | ) | ||
429 | } | ||
405 | } | 430 | } |