aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer/expr.rs')
-rw-r--r--crates/hir_ty/src/infer/expr.rs79
1 files changed, 49 insertions, 30 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index f5782ab24..4ef847d3a 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -39,12 +39,14 @@ impl<'a> InferenceContext<'a> {
39 // Any expression that produces a value of type `!` must have diverged 39 // Any expression that produces a value of type `!` must have diverged
40 self.diverges = Diverges::Always; 40 self.diverges = Diverges::Always;
41 } 41 }
42 let could_unify = self.unify(&ty, &expected.ty); 42 if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
43 if !could_unify { 43 let could_unify = self.unify(&ty, &expected_ty);
44 self.result.type_mismatches.insert( 44 if !could_unify {
45 tgt_expr.into(), 45 self.result.type_mismatches.insert(
46 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, 46 tgt_expr.into(),
47 ); 47 TypeMismatch { expected: expected_ty.clone(), actual: ty.clone() },
48 );
49 }
48 } 50 }
49 ty 51 ty
50 } 52 }
@@ -53,18 +55,20 @@ impl<'a> InferenceContext<'a> {
53 /// Return the type after possible coercion. 55 /// Return the type after possible coercion.
54 pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { 56 pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty {
55 let ty = self.infer_expr_inner(expr, &expected); 57 let ty = self.infer_expr_inner(expr, &expected);
56 let ty = if !self.coerce(&ty, &expected.coercion_target()) { 58 let ty = if let Some(target) = expected.only_has_type(&mut self.table) {
57 self.result.type_mismatches.insert( 59 if !self.coerce(&ty, &target) {
58 expr.into(), 60 self.result.type_mismatches.insert(
59 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, 61 expr.into(),
60 ); 62 TypeMismatch { expected: target.clone(), actual: ty.clone() },
61 // Return actual type when type mismatch. 63 );
62 // This is needed for diagnostic when return type mismatch. 64 // Return actual type when type mismatch.
63 ty 65 // This is needed for diagnostic when return type mismatch.
64 } else if expected.coercion_target().is_unknown() { 66 ty
65 ty 67 } else {
68 target.clone()
69 }
66 } else { 70 } else {
67 expected.ty.clone() 71 ty
68 }; 72 };
69 73
70 ty 74 ty
@@ -280,7 +284,9 @@ impl<'a> InferenceContext<'a> {
280 // Eagerly try to relate the closure type with the expected 284 // Eagerly try to relate the closure type with the expected
281 // type, otherwise we often won't have enough information to 285 // type, otherwise we often won't have enough information to
282 // infer the body. 286 // infer the body.
283 self.coerce(&closure_ty, &expected.ty); 287 if let Some(t) = expected.only_has_type(&mut self.table) {
288 self.coerce(&closure_ty, &t);
289 }
284 290
285 // Now go through the argument patterns 291 // Now go through the argument patterns
286 for (arg_pat, arg_ty) in args.iter().zip(sig_tys) { 292 for (arg_pat, arg_ty) in args.iter().zip(sig_tys) {
@@ -413,7 +419,9 @@ impl<'a> InferenceContext<'a> {
413 self.write_variant_resolution(tgt_expr.into(), variant); 419 self.write_variant_resolution(tgt_expr.into(), variant);
414 } 420 }
415 421
416 self.unify(&ty, &expected.ty); 422 if let Some(t) = expected.only_has_type(&mut self.table) {
423 self.unify(&ty, &t);
424 }
417 425
418 let substs = ty 426 let substs = ty
419 .as_adt() 427 .as_adt()
@@ -516,6 +524,7 @@ impl<'a> InferenceContext<'a> {
516 self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok()) 524 self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok())
517 } 525 }
518 Expr::Cast { expr, type_ref } => { 526 Expr::Cast { expr, type_ref } => {
527 // FIXME: propagate the "castable to" expectation (and find a test case that shows this is necessary)
519 let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 528 let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
520 let cast_ty = self.make_ty(type_ref); 529 let cast_ty = self.make_ty(type_ref);
521 // FIXME check the cast... 530 // FIXME check the cast...
@@ -523,14 +532,16 @@ impl<'a> InferenceContext<'a> {
523 } 532 }
524 Expr::Ref { expr, rawness, mutability } => { 533 Expr::Ref { expr, rawness, mutability } => {
525 let mutability = lower_to_chalk_mutability(*mutability); 534 let mutability = lower_to_chalk_mutability(*mutability);
526 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = 535 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = expected
527 &self.resolve_ty_shallow(&expected.ty).as_reference_or_ptr() 536 .only_has_type(&mut self.table)
537 .as_ref()
538 .and_then(|t| t.as_reference_or_ptr())
528 { 539 {
529 if *exp_mutability == Mutability::Mut && mutability == Mutability::Not { 540 if exp_mutability == Mutability::Mut && mutability == Mutability::Not {
530 // FIXME: record type error - expected mut reference but found shared ref, 541 // FIXME: record type error - expected mut reference but found shared ref,
531 // which cannot be coerced 542 // which cannot be coerced
532 } 543 }
533 if *exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr { 544 if exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr {
534 // FIXME: record type error - expected reference but found ptr, 545 // FIXME: record type error - expected reference but found ptr,
535 // which cannot be coerced 546 // which cannot be coerced
536 } 547 }
@@ -701,8 +712,12 @@ impl<'a> InferenceContext<'a> {
701 } 712 }
702 } 713 }
703 Expr::Tuple { exprs } => { 714 Expr::Tuple { exprs } => {
704 let mut tys = match self.resolve_ty_shallow(&expected.ty).kind(&Interner) { 715 let mut tys = match expected
705 TyKind::Tuple(_, substs) => substs 716 .only_has_type(&mut self.table)
717 .as_ref()
718 .map(|t| t.kind(&Interner))
719 {
720 Some(TyKind::Tuple(_, substs)) => substs
706 .iter(&Interner) 721 .iter(&Interner)
707 .map(|a| a.assert_ty_ref(&Interner).clone()) 722 .map(|a| a.assert_ty_ref(&Interner).clone())
708 .chain(repeat_with(|| self.table.new_type_var())) 723 .chain(repeat_with(|| self.table.new_type_var()))
@@ -718,14 +733,16 @@ impl<'a> InferenceContext<'a> {
718 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner) 733 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
719 } 734 }
720 Expr::Array(array) => { 735 Expr::Array(array) => {
721 let elem_ty = match self.resolve_ty_shallow(&expected.ty).kind(&Interner) { 736 let elem_ty =
722 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(), 737 match expected.to_option(&mut self.table).as_ref().map(|t| t.kind(&Interner)) {
723 _ => self.table.new_type_var(), 738 Some(TyKind::Array(st, _)) | Some(TyKind::Slice(st)) => st.clone(),
724 }; 739 _ => self.table.new_type_var(),
740 };
725 741
726 let len = match array { 742 let len = match array {
727 Array::ElementList(items) => { 743 Array::ElementList(items) => {
728 for expr in items.iter() { 744 for expr in items.iter() {
745 // FIXME: use CoerceMany (coerce_merge_branch)
729 self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone())); 746 self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
730 } 747 }
731 Some(items.len() as u64) 748 Some(items.len() as u64)
@@ -839,7 +856,9 @@ impl<'a> InferenceContext<'a> {
839 // we don't even make an attempt at coercion 856 // we don't even make an attempt at coercion
840 self.table.new_maybe_never_var() 857 self.table.new_maybe_never_var()
841 } else { 858 } else {
842 self.coerce(&TyBuilder::unit(), &expected.coercion_target()); 859 if let Some(t) = expected.only_has_type(&mut self.table) {
860 self.coerce(&TyBuilder::unit(), &t);
861 }
843 TyBuilder::unit() 862 TyBuilder::unit()
844 } 863 }
845 }; 864 };