aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-05-23 17:10:40 +0100
committerFlorian Diebold <[email protected]>2021-05-23 17:45:44 +0100
commit7a0c93c58ac17b089edd8c9763fef303b7a81414 (patch)
tree49cb56219cd7aea41376c49252601264ebabcf1a /crates/ide_completion
parent4a6cdd776d403bacce0a5471d77e8c76695c5bc5 (diff)
Infer correct expected type for generic struct fields
Diffstat (limited to 'crates/ide_completion')
-rw-r--r--crates/ide_completion/src/context.rs32
-rw-r--r--crates/ide_completion/src/render.rs7
2 files changed, 23 insertions, 16 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index c929d7394..4a88a6e88 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -337,25 +337,25 @@ impl<'a> CompletionContext<'a> {
337 }, 337 },
338 ast::RecordExprFieldList(_it) => { 338 ast::RecordExprFieldList(_it) => {
339 cov_mark::hit!(expected_type_struct_field_without_leading_char); 339 cov_mark::hit!(expected_type_struct_field_without_leading_char);
340 self.token.prev_sibling_or_token() 340 // wouldn't try {} be nice...
341 .and_then(|se| se.into_node()) 341 (|| {
342 .and_then(|node| ast::RecordExprField::cast(node)) 342 let record_ty = self.sema.type_of_expr(&ast::Expr::cast(node.parent()?)?)?;
343 .and_then(|rf| self.sema.resolve_record_field(&rf).zip(Some(rf))) 343 let expr_field = self.token.prev_sibling_or_token()?
344 .map(|(f, rf)|( 344 .into_node()
345 Some(f.0.ty(self.db)), 345 .and_then(|node| ast::RecordExprField::cast(node))?;
346 rf.field_name().map(NameOrNameRef::NameRef), 346 let field = self.sema.resolve_record_field(&expr_field)?.0;
347 Some((
348 record_ty.field_type(self.db, field),
349 expr_field.field_name().map(NameOrNameRef::NameRef),
347 )) 350 ))
348 .unwrap_or((None, None)) 351 })().unwrap_or((None, None))
349 }, 352 },
350 ast::RecordExprField(it) => { 353 ast::RecordExprField(it) => {
351 cov_mark::hit!(expected_type_struct_field_with_leading_char); 354 cov_mark::hit!(expected_type_struct_field_with_leading_char);
352 self.sema 355 (
353 .resolve_record_field(&it) 356 it.expr().as_ref().and_then(|e| self.sema.type_of_expr(e)),
354 .map(|f|( 357 it.field_name().map(NameOrNameRef::NameRef),
355 Some(f.0.ty(self.db)), 358 )
356 it.field_name().map(NameOrNameRef::NameRef),
357 ))
358 .unwrap_or((None, None))
359 }, 359 },
360 ast::MatchExpr(it) => { 360 ast::MatchExpr(it) => {
361 cov_mark::hit!(expected_type_match_arm_without_leading_char); 361 cov_mark::hit!(expected_type_match_arm_without_leading_char);
@@ -910,7 +910,7 @@ fn foo() -> u32 {
910 } 910 }
911 911
912 #[test] 912 #[test]
913 fn expected_type_closure_param() { 913 fn expected_type_closure_param_return() {
914 check_expected_type_and_name( 914 check_expected_type_and_name(
915 r#" 915 r#"
916fn foo() { 916fn foo() {
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 6b04ee164..d7f96b864 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -667,6 +667,13 @@ fn foo() { A { the$0 } }
667 ), 667 ),
668 detail: "u32", 668 detail: "u32",
669 deprecated: true, 669 deprecated: true,
670 relevance: CompletionRelevance {
671 exact_name_match: false,
672 type_match: Some(
673 CouldUnify,
674 ),
675 is_local: false,
676 },
670 }, 677 },
671 ] 678 ]
672 "#]], 679 "#]],