Some(ImmediateLocation::RecordExpr(record_expr)) => {
let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));
let default_trait = FamousDefs(&ctx.sema, ctx.krate).core_default_Default();
- let impl_default_trait = default_trait
- .zip(ty)
- .map_or(false, |(default_trait, ty)| ty.impls_trait(ctx.db, default_trait, &[]));
+ let impl_default_trait = default_trait.zip(ty).map_or(false, |(default_trait, ty)| {
+ ty.original.impls_trait(ctx.db, default_trait, &[])
+ });
let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
if impl_default_trait && !missing_fields.is_empty() {
};
for (field, ty) in missing_fields {
- acc.add_field(ctx, field, &ty);
+ acc.add_field(ctx, None, field, &ty);
}
Some(())
}
-#[cfg(test)]
-mod tests {
- use expect_test::{expect, Expect};
- use ide_db::helpers::FamousDefs;
-
- use crate::{
- test_utils::{self, completion_list},
- CompletionKind,
- };
-
- fn check(ra_fixture: &str, expect: Expect) {
- let actual = completion_list(ra_fixture, CompletionKind::Reference);
- expect.assert_eq(&actual);
+pub(crate) fn complete_record_literal(
+ acc: &mut Completions,
+ ctx: &CompletionContext,
+) -> Option<()> {
+ if !ctx.expects_expression() {
+ return None;
}
- fn check_snippet(ra_fixture: &str, expect: Expect) {
- let actual = completion_list(
- &format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE),
- CompletionKind::Snippet,
- );
- expect.assert_eq(&actual);
+ if let hir::Adt::Struct(strukt) = ctx.expected_type.as_ref()?.as_adt()? {
+ acc.add_struct_literal(ctx, strukt, None);
}
- fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
- test_utils::check_edit(
- what,
- &format!(
- "//- /main.rs crate:main deps:core{}\n{}",
- ra_fixture_before,
- FamousDefs::FIXTURE,
- ),
- &(ra_fixture_after.to_owned() + "\n"),
- );
- }
-
- #[test]
- fn test_record_literal_field_default() {
- let test_code = r#"
-struct S { foo: u32, bar: usize }
-
-impl core::default::Default for S {
- fn default() -> Self {
- S {
- foo: 0,
- bar: 0,
- }
- }
-}
-
-fn process(f: S) {
- let other = S {
- foo: 5,
- .$0
- };
+ Some(())
}
-"#;
- check(
- test_code,
- expect![[r#"
- fd bar usize
- "#]],
- );
- check_snippet(
- test_code,
- expect![[r#"
- fd ..Default::default()
- "#]],
- );
- }
+#[cfg(test)]
+mod tests {
+ use crate::tests::check_edit;
#[test]
- fn test_record_literal_field_default_completion() {
+ fn literal_struct_completion_edit() {
check_edit(
- "..Default::default()",
+ "FooDesc {…}",
r#"
-struct S { foo: u32, bar: usize }
+struct FooDesc { pub bar: bool }
-impl core::default::Default for S {
- fn default() -> Self {
- S {
- foo: 0,
- bar: 0,
- }
- }
-}
+fn create_foo(foo_desc: &FooDesc) -> () { () }
-fn process(f: S) {
- let other = S {
- foo: 5,
- .$0
- };
+fn baz() {
+ let foo = create_foo(&$0);
}
-"#,
+ "#,
r#"
-struct S { foo: u32, bar: usize }
+struct FooDesc { pub bar: bool }
-impl core::default::Default for S {
- fn default() -> Self {
- S {
- foo: 0,
- bar: 0,
- }
- }
-}
+fn create_foo(foo_desc: &FooDesc) -> () { () }
-fn process(f: S) {
- let other = S {
- foo: 5,
- ..Default::default()
- };
+fn baz() {
+ let foo = create_foo(&FooDesc { bar: ${1:()} }$0);
}
-"#,
- );
+ "#,
+ )
}
#[test]
- fn test_record_literal_field_without_default() {
- let test_code = r#"
-struct S { foo: u32, bar: usize }
-
-fn process(f: S) {
- let other = S {
- foo: 5,
- .$0
- };
+ fn literal_struct_complexion_module() {
+ check_edit(
+ "FooDesc {…}",
+ r#"
+mod _69latrick {
+ pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, pub bar: bool }
+ pub fn create_foo(foo_desc: &FooDesc) -> () { () }
}
-"#;
- check(
- test_code,
- expect![[r#"
- fd bar usize
- "#]],
- );
- check_snippet(test_code, expect![[r#""#]]);
- }
+fn baz() {
+ use _69latrick::*;
- #[test]
- fn test_record_pattern_field() {
- check(
- r#"
-struct S { foo: u32 }
-
-fn process(f: S) {
- match f {
- S { f$0: 92 } => (),
- }
+ let foo = create_foo(&$0);
}
-"#,
- expect![[r#"
- fd foo u32
- "#]],
- );
- }
-
- #[test]
- fn test_record_pattern_enum_variant() {
- check(
+ "#,
r#"
-enum E { S { foo: u32, bar: () } }
-
-fn process(e: E) {
- match e {
- E::S { $0 } => (),
- }
+mod _69latrick {
+ pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, pub bar: bool }
+ pub fn create_foo(foo_desc: &FooDesc) -> () { () }
}
-"#,
- expect![[r#"
- fd foo u32
- fd bar ()
- "#]],
- );
- }
- #[test]
- fn test_record_pattern_field_in_simple_macro() {
- check(
- r"
-macro_rules! m { ($e:expr) => { $e } }
-struct S { foo: u32 }
+fn baz() {
+ use _69latrick::*;
-fn process(f: S) {
- m!(match f {
- S { f$0: 92 } => (),
- })
+ let foo = create_foo(&FooDesc { six: ${1:()}, neuf: ${2:()}, bar: ${3:()} }$0);
}
-",
- expect![[r#"
- fd foo u32
- "#]],
+ "#,
);
}
#[test]
- fn only_missing_fields_are_completed_in_destruct_pats() {
- check(
+ fn default_completion_edit() {
+ check_edit(
+ "..Default::default()",
r#"
-struct S {
- foo1: u32, foo2: u32,
- bar: u32, baz: u32,
-}
+//- minicore: default
+struct Struct { foo: u32, bar: usize }
-fn main() {
- let s = S {
- foo1: 1, foo2: 2,
- bar: 3, baz: 4,
- };
- if let S { foo1, foo2: a, $0 } = s {}
+impl Default for Struct {
+ fn default() -> Self {}
}
-"#,
- expect![[r#"
- fd bar u32
- fd baz u32
- "#]],
- );
- }
- #[test]
- fn test_record_literal_field() {
- check(
- r#"
-struct A { the_field: u32 }
fn foo() {
- A { the$0 }
+ let other = Struct {
+ foo: 5,
+ .$0
+ };
}
"#,
- expect![[r#"
- fd the_field u32
- "#]],
- );
- }
-
- #[test]
- fn test_record_literal_enum_variant() {
- check(
r#"
-enum E { A { a: u32 } }
-fn foo() {
- let _ = E::A { $0 }
-}
-"#,
- expect![[r#"
- fd a u32
- "#]],
- );
- }
+struct Struct { foo: u32, bar: usize }
- #[test]
- fn test_record_literal_two_structs() {
- check(
- r#"
-struct A { a: u32 }
-struct B { b: u32 }
+impl Default for Struct {
+ fn default() -> Self {}
+}
fn foo() {
- let _: A = B { $0 }
+ let other = Struct {
+ foo: 5,
+ ..Default::default()
+ };
}
"#,
- expect![[r#"
- fd b u32
- "#]],
);
- }
-
- #[test]
- fn test_record_literal_generic_struct() {
- check(
+ check_edit(
+ "..Default::default()",
r#"
-struct A<T> { a: T }
+//- minicore: default
+struct Struct { foo: u32, bar: usize }
-fn foo() {
- let _: A<u32> = A { $0 }
+impl Default for Struct {
+ fn default() -> Self {}
}
-"#,
- expect![[r#"
- fd a u32
- "#]],
- );
- }
- #[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$0 })
+ let other = Struct {
+ foo: 5,
+ $0
+ };
}
"#,
- expect![[r#"
- fd the_field u32
- "#]],
- );
- }
-
- #[test]
- fn only_missing_fields_are_completed() {
- check(
r#"
-struct S {
- foo1: u32, foo2: u32,
- bar: u32, baz: u32,
-}
+struct Struct { foo: u32, bar: usize }
-fn main() {
- let foo1 = 1;
- let s = S { foo1, foo2: 5, $0 }
+impl Default for Struct {
+ fn default() -> Self {}
}
-"#,
- expect![[r#"
- fd bar u32
- fd baz u32
- "#]],
- );
- }
- #[test]
- fn completes_functional_update() {
- check(
- r#"
-struct S { foo1: u32, foo2: u32 }
-
-fn main() {
- let foo1 = 1;
- let s = S { foo1, $0 .. loop {} }
+fn foo() {
+ let other = Struct {
+ foo: 5,
+ ..Default::default()
+ };
}
"#,
- expect![[r#"
- fd foo2 u32
- "#]],
);
}
}