aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
authoruHOOCCOOHu <[email protected]>2019-09-25 22:56:55 +0100
committeruHOOCCOOHu <[email protected]>2019-09-25 23:16:58 +0100
commit29e56b8ee480828b81011cfa16c055fa0c9c89fe (patch)
tree45f901e9a92ffc8cf1d90a3fef1db45a70df632a /crates/ra_hir/src/ty/infer.rs
parent5807e261c27e4964fc6a8d2b8cf02e548292b940 (diff)
Support all coercion places
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs82
1 files changed, 57 insertions, 25 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index ba63050a9..db3377357 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -14,7 +14,7 @@
14//! the `ena` crate, which is extracted from rustc. 14//! the `ena` crate, which is extracted from rustc.
15 15
16use std::borrow::Cow; 16use std::borrow::Cow;
17use std::iter::repeat; 17use std::iter::{repeat, repeat_with};
18use std::mem; 18use std::mem;
19use std::ops::Index; 19use std::ops::Index;
20use std::sync::Arc; 20use std::sync::Arc;
@@ -876,10 +876,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
876 } 876 }
877 877
878 /// Infer type of expression with possibly implicit coerce to the expected type. 878 /// Infer type of expression with possibly implicit coerce to the expected type.
879 /// Return the type after possible coercion.
879 fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { 880 fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty {
880 let ty = self.infer_expr_inner(expr, &expected); 881 let ty = self.infer_expr_inner(expr, &expected);
881 self.coerce(&ty, &expected.ty); 882 let ty = if !self.coerce(&ty, &expected.ty) {
882 ty 883 self.result
884 .type_mismatches
885 .insert(expr, TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() });
886 // Return actual type when type mismatch.
887 // This is needed for diagnostic when return type mismatch.
888 ty
889 } else if expected.ty == Ty::Unknown {
890 ty
891 } else {
892 expected.ty.clone()
893 };
894
895 self.resolve_ty_as_possible(&mut vec![], ty)
883 } 896 }
884 897
885 /// Merge two types from different branches, with possible implicit coerce. 898 /// Merge two types from different branches, with possible implicit coerce.
@@ -1328,6 +1341,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1328 self.write_variant_resolution(tgt_expr.into(), variant); 1341 self.write_variant_resolution(tgt_expr.into(), variant);
1329 } 1342 }
1330 1343
1344 self.unify(&ty, &expected.ty);
1345
1331 let substs = ty.substs().unwrap_or_else(Substs::empty); 1346 let substs = ty.substs().unwrap_or_else(Substs::empty);
1332 for (field_idx, field) in fields.iter().enumerate() { 1347 for (field_idx, field) in fields.iter().enumerate() {
1333 let field_ty = def_id 1348 let field_ty = def_id
@@ -1343,7 +1358,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1343 }) 1358 })
1344 .map_or(Ty::Unknown, |field| field.ty(self.db)) 1359 .map_or(Ty::Unknown, |field| field.ty(self.db))
1345 .subst(&substs); 1360 .subst(&substs);
1346 self.infer_expr(field.expr, &Expectation::has_type(field_ty)); 1361 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
1347 } 1362 }
1348 if let Some(expr) = spread { 1363 if let Some(expr) = spread {
1349 self.infer_expr(*expr, &Expectation::has_type(ty.clone())); 1364 self.infer_expr(*expr, &Expectation::has_type(ty.clone()));
@@ -1513,35 +1528,41 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1513 Ty::Unknown 1528 Ty::Unknown
1514 } 1529 }
1515 Expr::Tuple { exprs } => { 1530 Expr::Tuple { exprs } => {
1516 let mut ty_vec = Vec::with_capacity(exprs.len()); 1531 let mut tys = match &expected.ty {
1517 for arg in exprs.iter() { 1532 ty_app!(TypeCtor::Tuple { .. }, st) => st
1518 ty_vec.push(self.infer_expr(*arg, &Expectation::none())); 1533 .iter()
1534 .cloned()
1535 .chain(repeat_with(|| self.new_type_var()))
1536 .take(exprs.len())
1537 .collect::<Vec<_>>(),
1538 _ => (0..exprs.len()).map(|_| self.new_type_var()).collect(),
1539 };
1540
1541 for (expr, ty) in exprs.iter().zip(tys.iter_mut()) {
1542 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
1519 } 1543 }
1520 1544
1521 Ty::apply( 1545 Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into()))
1522 TypeCtor::Tuple { cardinality: ty_vec.len() as u16 },
1523 Substs(ty_vec.into()),
1524 )
1525 } 1546 }
1526 Expr::Array(array) => { 1547 Expr::Array(array) => {
1527 let elem_ty = match &expected.ty { 1548 let elem_ty = match &expected.ty {
1528 Ty::Apply(a_ty) => match a_ty.ctor { 1549 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => {
1529 TypeCtor::Slice | TypeCtor::Array => { 1550 st.as_single().clone()
1530 Ty::clone(&a_ty.parameters.as_single()) 1551 }
1531 }
1532 _ => self.new_type_var(),
1533 },
1534 _ => self.new_type_var(), 1552 _ => self.new_type_var(),
1535 }; 1553 };
1536 1554
1537 match array { 1555 match array {
1538 Array::ElementList(items) => { 1556 Array::ElementList(items) => {
1539 for expr in items.iter() { 1557 for expr in items.iter() {
1540 self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone())); 1558 self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
1541 } 1559 }
1542 } 1560 }
1543 Array::Repeat { initializer, repeat } => { 1561 Array::Repeat { initializer, repeat } => {
1544 self.infer_expr(*initializer, &Expectation::has_type(elem_ty.clone())); 1562 self.infer_expr_coerce(
1563 *initializer,
1564 &Expectation::has_type(elem_ty.clone()),
1565 );
1545 self.infer_expr( 1566 self.infer_expr(
1546 *repeat, 1567 *repeat,
1547 &Expectation::has_type(Ty::simple(TypeCtor::Int( 1568 &Expectation::has_type(Ty::simple(TypeCtor::Int(
@@ -1588,12 +1609,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1588 Statement::Let { pat, type_ref, initializer } => { 1609 Statement::Let { pat, type_ref, initializer } => {
1589 let decl_ty = 1610 let decl_ty =
1590 type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); 1611 type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown);
1591 let decl_ty = self.insert_type_vars(decl_ty); 1612
1613 // Always use the declared type when specified
1614 let mut ty = decl_ty.clone();
1615
1592 if let Some(expr) = initializer { 1616 if let Some(expr) = initializer {
1593 self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); 1617 let actual_ty =
1618 self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone()));
1619 if decl_ty == Ty::Unknown {
1620 ty = actual_ty;
1621 }
1594 } 1622 }
1595 1623
1596 let ty = self.resolve_ty_as_possible(&mut vec![], decl_ty); 1624 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
1597 self.infer_pat(*pat, &ty, BindingMode::default()); 1625 self.infer_pat(*pat, &ty, BindingMode::default());
1598 } 1626 }
1599 Statement::Expr(expr) => { 1627 Statement::Expr(expr) => {
@@ -1601,9 +1629,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1601 } 1629 }
1602 } 1630 }
1603 } 1631 }
1604 let ty = 1632
1605 if let Some(expr) = tail { self.infer_expr_inner(expr, expected) } else { Ty::unit() }; 1633 if let Some(expr) = tail {
1606 ty 1634 self.infer_expr_coerce(expr, expected)
1635 } else {
1636 self.coerce(&Ty::unit(), &expected.ty);
1637 Ty::unit()
1638 }
1607 } 1639 }
1608 1640
1609 fn check_call_arguments(&mut self, args: &[ExprId], param_tys: &[Ty]) { 1641 fn check_call_arguments(&mut self, args: &[ExprId], param_tys: &[Ty]) {