aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
authorMarcus Klaas de Vries <[email protected]>2019-01-10 17:08:54 +0000
committerMarcus Klaas de Vries <[email protected]>2019-01-14 12:54:31 +0000
commit1574715be5d3fc7e07160708810dcbc9c1b01733 (patch)
treec482c99282393d75606c4487d316103b14208561 /crates/ra_hir/src/ty.rs
parent5f5dc20d85dead5fbd51d163451f796255c9faea (diff)
Use type variables to determine exact type for ambiguous numeric literals
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs45
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)]
115pub enum InferTy { 115pub 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,