diff options
Diffstat (limited to '')
-rw-r--r-- | src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs | 716 |
1 files changed, 716 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs new file mode 100644 index 000000000..30ddbe2dc --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs @@ -0,0 +1,716 @@ +//! Completion tests for pattern position. +use expect_test::{expect, Expect}; + +use crate::tests::{check_edit, completion_list, BASE_ITEMS_FIXTURE}; + +fn check_empty(ra_fixture: &str, expect: Expect) { + let actual = completion_list(ra_fixture); + expect.assert_eq(&actual) +} + +fn check(ra_fixture: &str, expect: Expect) { + let actual = completion_list(&format!("{}\n{}", BASE_ITEMS_FIXTURE, ra_fixture)); + expect.assert_eq(&actual) +} + +#[test] +fn wildcard() { + check( + r#" +fn quux() { + let _$0 +} +"#, + expect![""], + ); +} + +#[test] +fn ident_rebind_pat() { + check_empty( + r#" +fn quux() { + let en$0 @ x +} +"#, + expect![[r#" + kw mut + kw ref + "#]], + ); +} + +#[test] +fn ident_ref_pat() { + check_empty( + r#" +fn quux() { + let ref en$0 +} +"#, + expect![[r#" + kw mut + "#]], + ); + check_empty( + r#" +fn quux() { + let ref en$0 @ x +} +"#, + expect![[r#" + kw mut + "#]], + ); +} + +#[test] +fn ident_ref_mut_pat() { + check_empty( + r#" +fn quux() { + let ref mut en$0 +} +"#, + expect![[r#""#]], + ); + check_empty( + r#" +fn quux() { + let ref mut en$0 @ x +} +"#, + expect![[r#""#]], + ); +} + +#[test] +fn ref_pat() { + check_empty( + r#" +fn quux() { + let &en$0 +} +"#, + expect![[r#" + kw mut + "#]], + ); + check_empty( + r#" +fn quux() { + let &mut en$0 +} +"#, + expect![[r#""#]], + ); + check_empty( + r#" +fn foo() { + for &$0 in () {} +} +"#, + expect![[r#" + kw mut + "#]], + ); +} + +#[test] +fn refutable() { + check( + r#" +fn foo() { + if let a$0 +} +"#, + expect![[r#" + ct CONST + en Enum + 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 + kw mut + kw ref + "#]], + ); +} + +#[test] +fn irrefutable() { + check( + r#" +enum SingleVariantEnum { + Variant +} +use SingleVariantEnum::Variant; +fn foo() { + let a$0 +} +"#, + expect![[r#" + en SingleVariantEnum + ma makro!(…) macro_rules! makro + md module + st Record + st Tuple + st Unit + ev Variant + bn Record {…} Record { field$1 }$0 + bn Tuple(…) Tuple($1)$0 + bn Variant Variant$0 + kw mut + kw ref + "#]], + ); +} + +#[test] +fn in_param() { + check( + r#" +fn foo(a$0) { +} +"#, + expect![[r#" + 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 + kw mut + kw ref + "#]], + ); + check( + r#" +fn foo(a$0: Tuple) { +} +"#, + expect![[r#" + ma makro!(…) macro_rules! makro + md module + st Record + st Tuple + st Unit + bn Record {…} Record { field$1 }$0 + bn Tuple(…) Tuple($1)$0 + kw mut + kw ref + "#]], + ); +} + +#[test] +fn only_fn_like_macros() { + check_empty( + r#" +macro_rules! m { ($e:expr) => { $e } } + +#[rustc_builtin_macro] +macro Clone {} + +fn foo() { + let x$0 +} +"#, + expect![[r#" + ma m!(…) macro_rules! m + kw mut + kw ref + "#]], + ); +} + +#[test] +fn in_simple_macro_call() { + check_empty( + r#" +macro_rules! m { ($e:expr) => { $e } } +enum E { X } + +fn foo() { + m!(match E::X { a$0 }) +} +"#, + expect![[r#" + en E + ma m!(…) macro_rules! m + bn E::X E::X$0 + kw mut + kw ref + "#]], + ); +} + +#[test] +fn omits_private_fields_pat() { + check_empty( + r#" +mod foo { + pub struct Record { pub field: i32, _field: i32 } + pub struct Tuple(pub u32, u32); + pub struct Invisible(u32, u32); +} +use foo::*; + +fn outer() { + if let a$0 +} +"#, + expect![[r#" + md foo + st Invisible + st Record + st Tuple + bn Record {…} Record { field$1, .. }$0 + bn Tuple(…) Tuple($1, ..)$0 + kw mut + kw ref + "#]], + ) +} + +#[test] +fn completes_self_pats() { + check_empty( + r#" +struct Foo(i32); +impl Foo { + fn foo() { + match Foo(0) { + a$0 + } + } +} + "#, + expect![[r#" + sp Self + st Foo + bn Foo(…) Foo($1)$0 + bn Self(…) Self($1)$0 + kw mut + kw ref + "#]], + ) +} + +#[test] +fn enum_qualified() { + check( + r#" +impl Enum { + type AssocType = (); + const ASSOC_CONST: () = (); + fn assoc_fn() {} +} +fn func() { + if let Enum::$0 = unknown {} +} +"#, + expect![[r#" + ct ASSOC_CONST const ASSOC_CONST: () + bn RecordV {…} RecordV { field$1 }$0 + bn TupleV(…) TupleV($1)$0 + bn UnitV UnitV$0 + "#]], + ); +} + +#[test] +fn completes_in_record_field_pat() { + check_empty( + r#" +struct Foo { bar: Bar } +struct Bar(u32); +fn outer(Foo { bar: $0 }: Foo) {} +"#, + expect![[r#" + st Bar + st Foo + bn Bar(…) Bar($1)$0 + bn Foo {…} Foo { bar$1 }$0 + kw mut + kw ref + "#]], + ) +} + +#[test] +fn skips_in_record_field_pat_name() { + check_empty( + r#" +struct Foo { bar: Bar } +struct Bar(u32); +fn outer(Foo { bar$0 }: Foo) {} +"#, + expect![[r#" + kw mut + kw ref + "#]], + ) +} + +#[test] +fn completes_in_fn_param() { + check_empty( + r#" +struct Foo { bar: Bar } +struct Bar(u32); +fn foo($0) {} +"#, + expect![[r#" + st Bar + st Foo + bn Bar(…) Bar($1): Bar$0 + bn Foo {…} Foo { bar$1 }: Foo$0 + kw mut + kw ref + "#]], + ) +} + +#[test] +fn completes_in_closure_param() { + check_empty( + r#" +struct Foo { bar: Bar } +struct Bar(u32); +fn foo() { + |$0| {}; +} +"#, + expect![[r#" + st Bar + st Foo + bn Bar(…) Bar($1)$0 + bn Foo {…} Foo { bar$1 }$0 + kw mut + kw ref + "#]], + ) +} + +#[test] +fn completes_no_delims_if_existing() { + check_empty( + r#" +struct Bar(u32); +fn foo() { + match Bar(0) { + B$0(b) => {} + } +} +"#, + expect![[r#" + st Bar + kw crate:: + kw self:: + "#]], + ); + check_empty( + r#" +struct Foo { bar: u32 } +fn foo() { + match (Foo { bar: 0 }) { + F$0 { bar } => {} + } +} +"#, + expect![[r#" + st Foo + kw crate:: + kw self:: + "#]], + ); + check_empty( + r#" +enum Enum { + TupleVariant(u32) +} +fn foo() { + match Enum::TupleVariant(0) { + Enum::T$0(b) => {} + } +} +"#, + expect![[r#" + bn TupleVariant TupleVariant + "#]], + ); + check_empty( + r#" +enum Enum { + RecordVariant { field: u32 } +} +fn foo() { + match (Enum::RecordVariant { field: 0 }) { + Enum::RecordV$0 { field } => {} + } +} +"#, + expect![[r#" + bn RecordVariant RecordVariant + "#]], + ); +} + +#[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 + "#]], + ); +} + +#[test] +fn completes_associated_const() { + check_empty( + r#" +#[derive(PartialEq, Eq)] +struct Ty(u8); + +impl Ty { + const ABC: Self = Self(0); +} + +fn f(t: Ty) { + match t { + Ty::$0 => {} + _ => {} + } +} +"#, + expect![[r#" + ct ABC const ABC: Self + "#]], + ); + + check_empty( + r#" +enum MyEnum {} + +impl MyEnum { + pub const A: i32 = 123; + pub const B: i32 = 456; +} + +fn f(e: MyEnum) { + match e { + MyEnum::$0 => {} + _ => {} + } +} +"#, + expect![[r#" + ct A pub const A: i32 + ct B pub const B: i32 + "#]], + ); + + check_empty( + r#" +union U { + i: i32, + f: f32, +} + +impl U { + pub const C: i32 = 123; + pub const D: i32 = 456; +} + +fn f(u: U) { + match u { + U::$0 => {} + _ => {} + } +} +"#, + expect![[r#" + ct C pub const C: i32 + ct D pub const D: i32 + "#]], + ); + + check_empty( + r#" +#[lang = "u32"] +impl u32 { + pub const MIN: Self = 0; +} + +fn f(v: u32) { + match v { + u32::$0 + } +} + "#, + expect![[r#" + ct MIN pub const MIN: Self + "#]], + ); +} + +#[test] +fn in_method_param() { + check_empty( + r#" +struct Ty(u8); + +impl Ty { + fn foo($0) +} +"#, + expect![[r#" + sp Self + st Ty + bn &mut self + bn &self + bn Self(…) Self($1): Self$0 + bn Ty(…) Ty($1): Ty$0 + bn mut self + bn self + kw mut + kw ref + "#]], + ); + check_empty( + r#" +struct Ty(u8); + +impl Ty { + fn foo(s$0) +} +"#, + expect![[r#" + sp Self + st Ty + bn &mut self + bn &self + bn Self(…) Self($1): Self$0 + bn Ty(…) Ty($1): Ty$0 + bn mut self + bn self + kw mut + kw ref + "#]], + ); + check_empty( + r#" +struct Ty(u8); + +impl Ty { + fn foo(s$0, foo: u8) +} +"#, + expect![[r#" + sp Self + st Ty + bn &mut self + bn &self + bn Self(…) Self($1): Self$0 + bn Ty(…) Ty($1): Ty$0 + bn mut self + bn self + kw mut + kw ref + "#]], + ); + check_empty( + r#" +struct Ty(u8); + +impl Ty { + fn foo(foo: u8, b$0) +} +"#, + expect![[r#" + sp Self + st Ty + bn Self(…) Self($1): Self$0 + bn Ty(…) Ty($1): Ty$0 + kw mut + kw ref + "#]], + ); +} |