diff options
author | Florian Diebold <[email protected]> | 2021-05-21 16:41:20 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-05-21 17:23:03 +0100 |
commit | 556c9cebdb91278702263df4ac8c99ec24ab331a (patch) | |
tree | d1895aa19a6ec1b7532871e171f1c37870298f58 /crates/hir_ty/src/infer.rs | |
parent | 99c73537faba59c881805573442562418e0b650a (diff) |
Refactor expectation handling
So as to not use `TyKind::Error` as "no expectation".
Diffstat (limited to 'crates/hir_ty/src/infer.rs')
-rw-r--r-- | crates/hir_ty/src/infer.rs | 59 |
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)] |
682 | struct Expectation { | 678 | enum 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 | ||
688 | impl Expectation { | 685 | impl 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 | } |