diff options
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 79 |
2 files changed, 49 insertions, 34 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 20c512517..03dd6ae76 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -21,10 +21,6 @@ impl<'a> InferenceContext<'a> { | |||
21 | pub(super) fn coerce(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool { | 21 | pub(super) fn coerce(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool { |
22 | let from_ty = self.resolve_ty_shallow(from_ty); | 22 | let from_ty = self.resolve_ty_shallow(from_ty); |
23 | let to_ty = self.resolve_ty_shallow(to_ty); | 23 | let to_ty = self.resolve_ty_shallow(to_ty); |
24 | // TODO handle expectations properly | ||
25 | if to_ty.is_unknown() { | ||
26 | return true; | ||
27 | } | ||
28 | match self.coerce_inner(from_ty, &to_ty) { | 24 | match self.coerce_inner(from_ty, &to_ty) { |
29 | Ok(result) => { | 25 | Ok(result) => { |
30 | self.table.register_infer_ok(result); | 26 | self.table.register_infer_ok(result); |
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 | }; |