2020-04-01 00:50:45 +03:00
|
|
|
//! Complete fields in record literals and patterns.
|
2020-10-18 13:09:00 +03:00
|
|
|
use crate::{CompletionContext, Completions};
|
2020-04-07 15:07:18 +02:00
|
|
|
|
2020-10-25 10:59:15 +03:00
|
|
|
pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
|
2020-04-11 23:33:17 +02:00
|
|
|
let missing_fields = match (ctx.record_pat_syntax.as_ref(), ctx.record_lit_syntax.as_ref()) {
|
2020-04-07 17:09:02 +02:00
|
|
|
(None, None) => return None,
|
|
|
|
(Some(_), Some(_)) => unreachable!("A record cannot be both a literal and a pattern"),
|
|
|
|
(Some(record_pat), _) => ctx.sema.record_pattern_missing_fields(record_pat),
|
|
|
|
(_, Some(record_lit)) => ctx.sema.record_literal_missing_fields(record_lit),
|
|
|
|
};
|
|
|
|
|
|
|
|
for (field, ty) in missing_fields {
|
|
|
|
acc.add_field(ctx, field, &ty)
|
2020-04-01 00:50:45 +03:00
|
|
|
}
|
|
|
|
|
2020-04-07 17:09:02 +02:00
|
|
|
Some(())
|
2020-04-01 00:50:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2020-08-21 13:19:31 +02:00
|
|
|
use expect_test::{expect, Expect};
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-10-18 13:09:00 +03:00
|
|
|
use crate::{test_utils::completion_list, CompletionKind};
|
2020-04-07 15:07:18 +02:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
fn check(ra_fixture: &str, expect: Expect) {
|
|
|
|
let actual = completion_list(ra_fixture, CompletionKind::Reference);
|
|
|
|
expect.assert_eq(&actual);
|
|
|
|
}
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
#[test]
|
|
|
|
fn test_record_pattern_field() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
struct S { foo: u32 }
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
fn process(f: S) {
|
|
|
|
match f {
|
|
|
|
S { f<|>: 92 } => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
fd foo u32
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
#[test]
|
|
|
|
fn test_record_pattern_enum_variant() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
enum E { S { foo: u32, bar: () } }
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
fn process(e: E) {
|
|
|
|
match e {
|
|
|
|
E::S { <|> } => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
fd bar ()
|
|
|
|
fd foo u32
|
|
|
|
"#]],
|
|
|
|
);
|
2020-04-01 00:50:45 +03:00
|
|
|
}
|
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
#[test]
|
|
|
|
fn test_record_pattern_field_in_simple_macro() {
|
|
|
|
check(
|
|
|
|
r"
|
|
|
|
macro_rules! m { ($e:expr) => { $e } }
|
|
|
|
struct S { foo: u32 }
|
|
|
|
|
|
|
|
fn process(f: S) {
|
|
|
|
m!(match f {
|
|
|
|
S { f<|>: 92 } => (),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
",
|
|
|
|
expect![[r#"
|
|
|
|
fd foo u32
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2020-04-07 15:07:18 +02:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
#[test]
|
|
|
|
fn only_missing_fields_are_completed_in_destruct_pats() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
struct S {
|
|
|
|
foo1: u32, foo2: u32,
|
|
|
|
bar: u32, baz: u32,
|
|
|
|
}
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
fn main() {
|
|
|
|
let s = S {
|
|
|
|
foo1: 1, foo2: 2,
|
|
|
|
bar: 3, baz: 4,
|
|
|
|
};
|
|
|
|
if let S { foo1, foo2: a, <|> } = s {}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
fd bar u32
|
|
|
|
fd baz u32
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
#[test]
|
|
|
|
fn test_record_literal_field() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
struct A { the_field: u32 }
|
|
|
|
fn foo() {
|
|
|
|
A { the<|> }
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
fd the_field u32
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
#[test]
|
|
|
|
fn test_record_literal_enum_variant() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
enum E { A { a: u32 } }
|
|
|
|
fn foo() {
|
|
|
|
let _ = E::A { <|> }
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
fd a u32
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
#[test]
|
|
|
|
fn test_record_literal_two_structs() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
struct A { a: u32 }
|
|
|
|
struct B { b: u32 }
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
fn foo() {
|
|
|
|
let _: A = B { <|> }
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
fd b u32
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
#[test]
|
|
|
|
fn test_record_literal_generic_struct() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
struct A<T> { a: T }
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
fn foo() {
|
|
|
|
let _: A<u32> = A { <|> }
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
fd a u32
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
#[test]
|
|
|
|
fn test_record_literal_field_in_simple_macro() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
macro_rules! m { ($e:expr) => { $e } }
|
|
|
|
struct A { the_field: u32 }
|
|
|
|
fn foo() {
|
|
|
|
m!(A { the<|> })
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
fd the_field u32
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
#[test]
|
|
|
|
fn only_missing_fields_are_completed() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
struct S {
|
|
|
|
foo1: u32, foo2: u32,
|
|
|
|
bar: u32, baz: u32,
|
|
|
|
}
|
2020-04-01 00:50:45 +03:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
fn main() {
|
|
|
|
let foo1 = 1;
|
|
|
|
let s = S { foo1, foo2: 5, <|> }
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
fd bar u32
|
|
|
|
fd baz u32
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2020-04-07 18:25:47 +02:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
#[test]
|
|
|
|
fn completes_functional_update() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
struct S { foo1: u32, foo2: u32 }
|
2020-04-07 18:25:47 +02:00
|
|
|
|
2020-07-03 11:48:48 +02:00
|
|
|
fn main() {
|
|
|
|
let foo1 = 1;
|
|
|
|
let s = S { foo1, <|> .. loop {} }
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
fd foo2 u32
|
|
|
|
"#]],
|
|
|
|
);
|
2020-04-01 00:50:45 +03:00
|
|
|
}
|
|
|
|
}
|