aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer.rs')
-rw-r--r--crates/hir_ty/src/infer.rs59
1 files changed, 39 insertions, 20 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index db2234018..a137c0f92 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -370,10 +370,6 @@ impl<'a> InferenceContext<'a> {
370 } 370 }
371 371
372 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 372 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
373 // TODO handle expectations properly
374 if ty2.is_unknown() {
375 return true;
376 }
377 self.table.unify(ty1, ty2) 373 self.table.unify(ty1, ty2)
378 } 374 }
379 375
@@ -679,17 +675,23 @@ impl<'a> InferenceContext<'a> {
679/// When inferring an expression, we propagate downward whatever type hint we 675/// When inferring an expression, we propagate downward whatever type hint we
680/// are able in the form of an `Expectation`. 676/// are able in the form of an `Expectation`.
681#[derive(Clone, PartialEq, Eq, Debug)] 677#[derive(Clone, PartialEq, Eq, Debug)]
682struct Expectation { 678enum Expectation {
683 ty: Ty, 679 None,
684 /// See the `rvalue_hint` method. 680 HasType(Ty),
685 rvalue_hint: bool, 681 // Castable(Ty), // rustc has this, we currently just don't propagate an expectation for casts
682 RValueLikeUnsized(Ty),
686} 683}
687 684
688impl Expectation { 685impl Expectation {
689 /// The expectation that the type of the expression needs to equal the given 686 /// The expectation that the type of the expression needs to equal the given
690 /// type. 687 /// type.
691 fn has_type(ty: Ty) -> Self { 688 fn has_type(ty: Ty) -> Self {
692 Expectation { ty, rvalue_hint: false } 689 if ty.is_unknown() {
690 // FIXME: get rid of this?
691 Expectation::None
692 } else {
693 Expectation::HasType(ty)
694 }
693 } 695 }
694 696
695 /// The following explanation is copied straight from rustc: 697 /// The following explanation is copied straight from rustc:
@@ -713,24 +715,41 @@ impl Expectation {
713 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169 715 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
714 /// for examples of where this comes up,. 716 /// for examples of where this comes up,.
715 fn rvalue_hint(ty: Ty) -> Self { 717 fn rvalue_hint(ty: Ty) -> Self {
716 Expectation { ty, rvalue_hint: true } 718 match ty.strip_references().kind(&Interner) {
719 TyKind::Slice(_) | TyKind::Str | TyKind::Dyn(_) => Expectation::RValueLikeUnsized(ty),
720 _ => Expectation::has_type(ty),
721 }
717 } 722 }
718 723
719 /// This expresses no expectation on the type. 724 /// This expresses no expectation on the type.
720 fn none() -> Self { 725 fn none() -> Self {
721 Expectation { 726 Expectation::None
722 // FIXME 727 }
723 ty: TyKind::Error.intern(&Interner), 728
724 rvalue_hint: false, 729 fn resolve(&self, table: &mut unify::InferenceTable) -> Expectation {
730 match self {
731 Expectation::None => Expectation::None,
732 Expectation::HasType(t) => Expectation::HasType(table.resolve_ty_shallow(t)),
733 Expectation::RValueLikeUnsized(t) => {
734 Expectation::RValueLikeUnsized(table.resolve_ty_shallow(t))
735 }
725 } 736 }
726 } 737 }
727 738
728 fn coercion_target(&self) -> Ty { 739 fn to_option(&self, table: &mut unify::InferenceTable) -> Option<Ty> {
729 if self.rvalue_hint { 740 match self.resolve(table) {
730 // FIXME 741 Expectation::None => None,
731 TyKind::Error.intern(&Interner) 742 Expectation::HasType(t) |
732 } else { 743 // Expectation::Castable(t) |
733 self.ty.clone() 744 Expectation::RValueLikeUnsized(t) => Some(t),
745 }
746 }
747
748 fn only_has_type(&self, table: &mut unify::InferenceTable) -> Option<Ty> {
749 match self {
750 Expectation::HasType(t) => Some(table.resolve_ty_shallow(t)),
751 // Expectation::Castable(_) |
752 Expectation::RValueLikeUnsized(_) | Expectation::None => None,
734 } 753 }
735 } 754 }
736} 755}