From 73b7b34f89091530ef492a8dd5ba683ae543d241 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 11 Aug 2021 18:05:39 +0200 Subject: [PATCH] Fill out expected type for functional update syntax completion --- crates/ide_completion/src/context.rs | 49 ++++++++++++++++++----- crates/ide_completion/src/tests/record.rs | 1 + 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index ac5cd1ce8e..e38234a8a5 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs @@ -480,18 +480,30 @@ impl<'a> CompletionContext<'a> { }) .unwrap_or((None, None)) }, - ast::RecordExprFieldList(_it) => { - cov_mark::hit!(expected_type_struct_field_without_leading_char); + ast::RecordExprFieldList(it) => { // wouldn't try {} be nice... (|| { - let expr_field = self.token.prev_sibling_or_token()? - .into_node() - .and_then(ast::RecordExprField::cast)?; - let (_, _, ty) = self.sema.resolve_record_field(&expr_field)?; - Some(( - Some(ty), - expr_field.field_name().map(NameOrNameRef::NameRef), - )) + if self.token.kind() == T![..] + || self.token.prev_token().map(|t| t.kind()) == Some(T![..]) + { + cov_mark::hit!(expected_type_struct_func_update); + let record_expr = it.syntax().parent().and_then(ast::RecordExpr::cast)?; + let ty = self.sema.type_of_expr(&record_expr.into())?; + Some(( + Some(ty.original), + None + )) + } else { + cov_mark::hit!(expected_type_struct_field_without_leading_char); + let expr_field = self.token.prev_sibling_or_token()? + .into_node() + .and_then(ast::RecordExprField::cast)?; + let (_, _, ty) = self.sema.resolve_record_field(&expr_field)?; + Some(( + Some(ty), + expr_field.field_name().map(NameOrNameRef::NameRef), + )) + } })().unwrap_or((None, None)) }, ast::RecordExprField(it) => { @@ -533,6 +545,7 @@ impl<'a> CompletionContext<'a> { .unwrap_or((None, None)) }, ast::Stmt(_it) => (None, None), + ast::Item(__) => (None, None), _ => { match node.parent() { Some(n) => { @@ -1091,4 +1104,20 @@ impl S { expect![[r#"ty: u32, name: t"#]], ); } + + #[test] + fn expected_type_functional_update() { + cov_mark::check!(expected_type_struct_func_update); + check_expected_type_and_name( + r#" +struct Foo { field: u32 } +fn foo() { + Foo { + ..$0 + } +} +"#, + expect![[r#"ty: Foo, name: ?"#]], + ); + } } diff --git a/crates/ide_completion/src/tests/record.rs b/crates/ide_completion/src/tests/record.rs index 326c1abee5..3769977b62 100644 --- a/crates/ide_completion/src/tests/record.rs +++ b/crates/ide_completion/src/tests/record.rs @@ -179,6 +179,7 @@ fn main() { fd ..Default::default() fd foo1 u32 fd foo2 u32 + sn Foo {…} Foo { foo1: ${1:()}, foo2: ${2:()} }$0 "#]], ); }