diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 13a1c2907..b4b338874 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -114,6 +114,8 @@ impl UnifyValue for TypeVarValue { | |||
114 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | 114 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] |
115 | pub enum InferTy { | 115 | pub enum InferTy { |
116 | TypeVar(TypeVarId), | 116 | TypeVar(TypeVarId), |
117 | IntVar(TypeVarId), | ||
118 | FloatVar(TypeVarId), | ||
117 | } | 119 | } |
118 | 120 | ||
119 | /// When inferring an expression, we propagate downward whatever type hint we | 121 | /// When inferring an expression, we propagate downward whatever type hint we |
@@ -718,12 +720,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
718 | .iter() | 720 | .iter() |
719 | .zip(ts2.iter()) | 721 | .zip(ts2.iter()) |
720 | .all(|(t1, t2)| self.unify(t1, t2)), | 722 | .all(|(t1, t2)| self.unify(t1, t2)), |
721 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) => { | 723 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) |
724 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | ||
725 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => { | ||
722 | // both type vars are unknown since we tried to resolve them | 726 | // both type vars are unknown since we tried to resolve them |
723 | self.var_unification_table.union(*tv1, *tv2); | 727 | self.var_unification_table.union(*tv1, *tv2); |
724 | true | 728 | true |
725 | } | 729 | } |
726 | (Ty::Infer(InferTy::TypeVar(tv)), other) | (other, Ty::Infer(InferTy::TypeVar(tv))) => { | 730 | (Ty::Infer(InferTy::TypeVar(tv)), other) |
731 | | (other, Ty::Infer(InferTy::TypeVar(tv))) | ||
732 | | (Ty::Infer(InferTy::IntVar(tv)), other) | ||
733 | | (other, Ty::Infer(InferTy::IntVar(tv))) | ||
734 | | (Ty::Infer(InferTy::FloatVar(tv)), other) | ||
735 | | (other, Ty::Infer(InferTy::FloatVar(tv))) => { | ||
727 | // the type var is unknown since we tried to resolve it | 736 | // the type var is unknown since we tried to resolve it |
728 | self.var_unification_table | 737 | self.var_unification_table |
729 | .union_value(*tv, TypeVarValue::Known(other.clone())); | 738 | .union_value(*tv, TypeVarValue::Known(other.clone())); |
@@ -739,10 +748,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
739 | )) | 748 | )) |
740 | } | 749 | } |
741 | 750 | ||
751 | fn new_integer_var(&mut self) -> Ty { | ||
752 | Ty::Infer(InferTy::IntVar( | ||
753 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
754 | )) | ||
755 | } | ||
756 | |||
757 | fn new_float_var(&mut self) -> Ty { | ||
758 | Ty::Infer(InferTy::FloatVar( | ||
759 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
760 | )) | ||
761 | } | ||
762 | |||
742 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. | 763 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. |
743 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { | 764 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { |
744 | match ty { | 765 | match ty { |
745 | Ty::Unknown => self.new_type_var(), | 766 | Ty::Unknown => self.new_type_var(), |
767 | Ty::Int(primitive::UncertainIntTy::Unknown) => self.new_integer_var(), | ||
768 | Ty::Float(primitive::UncertainFloatTy::Unknown) => self.new_float_var(), | ||
746 | _ => ty, | 769 | _ => ty, |
747 | } | 770 | } |
748 | } | 771 | } |
@@ -757,12 +780,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
757 | /// known type. | 780 | /// known type. |
758 | fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { | 781 | fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { |
759 | ty.fold(&mut |ty| match ty { | 782 | ty.fold(&mut |ty| match ty { |
760 | Ty::Infer(InferTy::TypeVar(tv)) => { | 783 | Ty::Infer(InferTy::TypeVar(tv)) |
784 | | Ty::Infer(InferTy::IntVar(tv)) | ||
785 | | Ty::Infer(InferTy::FloatVar(tv)) => { | ||
761 | if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { | 786 | if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { |
762 | // known_ty may contain other variables that are known by now | 787 | // known_ty may contain other variables that are known by now |
763 | self.resolve_ty_as_possible(known_ty.clone()) | 788 | self.resolve_ty_as_possible(known_ty.clone()) |
764 | } else { | 789 | } else { |
765 | Ty::Infer(InferTy::TypeVar(tv)) | 790 | ty |
766 | } | 791 | } |
767 | } | 792 | } |
768 | _ => ty, | 793 | _ => ty, |
@@ -790,12 +815,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
790 | /// replaced by Ty::Unknown. | 815 | /// replaced by Ty::Unknown. |
791 | fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { | 816 | fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { |
792 | ty.fold(&mut |ty| match ty { | 817 | ty.fold(&mut |ty| match ty { |
793 | Ty::Infer(InferTy::TypeVar(tv)) => { | 818 | Ty::Infer(i) => { |
819 | let tv = match i { | ||
820 | InferTy::TypeVar(tv) | InferTy::IntVar(tv) | InferTy::FloatVar(tv) => tv, | ||
821 | }; | ||
822 | |||
794 | if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { | 823 | if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { |
795 | // known_ty may contain other variables that are known by now | 824 | // known_ty may contain other variables that are known by now |
796 | self.resolve_ty_completely(known_ty.clone()) | 825 | self.resolve_ty_completely(known_ty.clone()) |
797 | } else { | 826 | } else { |
798 | Ty::Unknown | 827 | match i { |
828 | InferTy::TypeVar(..) => Ty::Unknown, | ||
829 | InferTy::IntVar(..) => Ty::Int(primitive::UncertainIntTy::Unknown), | ||
830 | InferTy::FloatVar(..) => Ty::Float(primitive::UncertainFloatTy::Unknown), | ||
831 | } | ||
799 | } | 832 | } |
800 | } | 833 | } |
801 | _ => ty, | 834 | _ => ty, |