blob: 67cf551fce84c5bc60dc7a49119edc0e08530f7f [file] [log] [blame]
//! Completion tests for pattern position.
use expect_test::{expect, Expect};
use crate::tests::{check_edit, check_empty, completion_list, BASE_ITEMS_FIXTURE};
fn check(ra_fixture: &str, expect: Expect) {
let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}\n{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_record_field_pat_with_generic_type_alias() {
check_empty(
r#"
type Wrap<T> = T;
enum X {
A { cool: u32, stuff: u32 },
B,
}
fn main() {
let wrapped = Wrap::<X>::A {
cool: 100,
stuff: 100,
};
if let Wrap::<X>::A { $0 } = &wrapped {};
}
"#,
expect![[r#"
fd cool u32
fd stuff u32
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 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 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#"
#![rustc_coherence_is_core]
#[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
"#]],
);
}
#[test]
fn through_alias() {
check_empty(
r#"
enum Enum<T> {
Unit,
Tuple(T),
}
type EnumAlias<T> = Enum<T>;
fn f(x: EnumAlias<u8>) {
match x {
EnumAlias::$0 => (),
_ => (),
}
}
"#,
expect![[r#"
bn Tuple(…) Tuple($1)$0
bn Unit Unit$0
"#]],
);
}
#[test]
fn pat_no_unstable_item_on_stable() {
check_empty(
r#"
//- /main.rs crate:main deps:std
use std::*;
fn foo() {
let a$0
}
//- /std.rs crate:std
#[unstable]
pub struct S;
#[unstable]
pub enum Enum {
Variant
}
"#,
expect![[r#"
md std
kw mut
kw ref
"#]],
);
}
#[test]
fn pat_unstable_item_on_nightly() {
check_empty(
r#"
//- toolchain:nightly
//- /main.rs crate:main deps:std
use std::*;
fn foo() {
let a$0
}
//- /std.rs crate:std
#[unstable]
pub struct S;
#[unstable]
pub enum Enum {
Variant
}
"#,
expect![[r#"
en Enum
md std
st S
kw mut
kw ref
"#]],
);
}