aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs148
1 files changed, 104 insertions, 44 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index fa46ddfe9..5579db8fb 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -14,7 +14,7 @@
14//! rustc. 14//! rustc.
15 15
16mod autoderef; 16mod autoderef;
17mod primitive; 17pub(crate) mod primitive;
18#[cfg(test)] 18#[cfg(test)]
19mod tests; 19mod tests;
20pub(crate) mod method_resolution; 20pub(crate) mod method_resolution;
@@ -38,7 +38,7 @@ use crate::{
38 db::HirDatabase, 38 db::HirDatabase,
39 type_ref::{TypeRef, Mutability}, 39 type_ref::{TypeRef, Mutability},
40 name::KnownName, 40 name::KnownName,
41 expr::{Body, Expr, ExprId, PatId, UnaryOp, BinaryOp, Statement}, 41 expr::{Body, Expr, Literal, ExprId, PatId, UnaryOp, BinaryOp, Statement},
42}; 42};
43 43
44fn transpose<T>(x: Cancelable<Option<T>>) -> Option<Cancelable<T>> { 44fn transpose<T>(x: Cancelable<Option<T>>) -> Option<Cancelable<T>> {
@@ -107,13 +107,35 @@ impl UnifyValue for TypeVarValue {
107 } 107 }
108} 108}
109 109
110/// The kinds of placeholders we need during type inference. Currently, we only 110/// The kinds of placeholders we need during type inference. There's separate
111/// have type variables; in the future, we will probably also need int and float 111/// values for general types, and for integer and float variables. The latter
112/// variables, for inference of literal values (e.g. `100` could be one of 112/// two are used for inference of literal values (e.g. `100` could be one of
113/// several integer types). 113/// several integer types).
114#[derive(Clone, PartialEq, Eq, Hash, Debug)] 114#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
115pub enum InferTy { 115pub enum InferTy {
116 TypeVar(TypeVarId), 116 TypeVar(TypeVarId),
117 IntVar(TypeVarId),
118 FloatVar(TypeVarId),
119}
120
121impl InferTy {
122 fn to_inner(self) -> TypeVarId {
123 match self {
124 InferTy::TypeVar(ty) | InferTy::IntVar(ty) | InferTy::FloatVar(ty) => ty,
125 }
126 }
127
128 fn fallback_value(self) -> Ty {
129 match self {
130 InferTy::TypeVar(..) => Ty::Unknown,
131 InferTy::IntVar(..) => {
132 Ty::Int(primitive::UncertainIntTy::Signed(primitive::IntTy::I32))
133 }
134 InferTy::FloatVar(..) => {
135 Ty::Float(primitive::UncertainFloatTy::Known(primitive::FloatTy::F64))
136 }
137 }
138 }
117} 139}
118 140
119/// When inferring an expression, we propagate downward whatever type hint we 141/// When inferring an expression, we propagate downward whatever type hint we
@@ -151,14 +173,11 @@ pub enum Ty {
151 /// (a non-surrogate code point). Written as `char`. 173 /// (a non-surrogate code point). Written as `char`.
152 Char, 174 Char,
153 175
154 /// A primitive signed integer type. For example, `i32`. 176 /// A primitive integer type. For example, `i32`.
155 Int(primitive::IntTy), 177 Int(primitive::UncertainIntTy),
156
157 /// A primitive unsigned integer type. For example, `u32`.
158 Uint(primitive::UintTy),
159 178
160 /// A primitive floating-point type. For example, `f64`. 179 /// A primitive floating-point type. For example, `f64`.
161 Float(primitive::FloatTy), 180 Float(primitive::UncertainFloatTy),
162 181
163 /// Structures, enumerations and unions. 182 /// Structures, enumerations and unions.
164 Adt { 183 Adt {
@@ -198,8 +217,9 @@ pub enum Ty {
198 // above function pointer type. Once we implement generics, we will probably 217 // above function pointer type. Once we implement generics, we will probably
199 // need this as well. 218 // need this as well.
200 219
201 // A trait, defined with `dyn trait`. 220 // A trait, defined with `dyn Trait`.
202 // Dynamic(), 221 // Dynamic(),
222
203 // The anonymous type of a closure. Used to represent the type of 223 // The anonymous type of a closure. Used to represent the type of
204 // `|a| a`. 224 // `|a| a`.
205 // Closure(DefId, ClosureSubsts<'tcx>), 225 // Closure(DefId, ClosureSubsts<'tcx>),
@@ -312,20 +332,19 @@ impl Ty {
312 path: &Path, 332 path: &Path,
313 ) -> Cancelable<Self> { 333 ) -> Cancelable<Self> {
314 if let Some(name) = path.as_ident() { 334 if let Some(name) = path.as_ident() {
315 if let Some(KnownName::Bool) = name.as_known_name() { 335 if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) {
316 return Ok(Ty::Bool);
317 } else if let Some(KnownName::Char) = name.as_known_name() {
318 return Ok(Ty::Char);
319 } else if let Some(KnownName::Str) = name.as_known_name() {
320 return Ok(Ty::Str);
321 } else if let Some(int_ty) = primitive::IntTy::from_name(name) {
322 return Ok(Ty::Int(int_ty)); 336 return Ok(Ty::Int(int_ty));
323 } else if let Some(uint_ty) = primitive::UintTy::from_name(name) { 337 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) {
324 return Ok(Ty::Uint(uint_ty));
325 } else if let Some(float_ty) = primitive::FloatTy::from_name(name) {
326 return Ok(Ty::Float(float_ty)); 338 return Ok(Ty::Float(float_ty));
327 } else if name.as_known_name() == Some(KnownName::SelfType) { 339 } else if name.as_known_name() == Some(KnownName::SelfType) {
328 return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type())); 340 return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type()));
341 } else if let Some(known) = name.as_known_name() {
342 match known {
343 KnownName::Bool => return Ok(Ty::Bool),
344 KnownName::Char => return Ok(Ty::Char),
345 KnownName::Str => return Ok(Ty::Str),
346 _ => {}
347 }
329 } 348 }
330 } 349 }
331 350
@@ -392,7 +411,6 @@ impl fmt::Display for Ty {
392 Ty::Bool => write!(f, "bool"), 411 Ty::Bool => write!(f, "bool"),
393 Ty::Char => write!(f, "char"), 412 Ty::Char => write!(f, "char"),
394 Ty::Int(t) => write!(f, "{}", t.ty_to_string()), 413 Ty::Int(t) => write!(f, "{}", t.ty_to_string()),
395 Ty::Uint(t) => write!(f, "{}", t.ty_to_string()),
396 Ty::Float(t) => write!(f, "{}", t.ty_to_string()), 414 Ty::Float(t) => write!(f, "{}", t.ty_to_string()),
397 Ty::Str => write!(f, "str"), 415 Ty::Str => write!(f, "str"),
398 Ty::Slice(t) => write!(f, "[{}]", t), 416 Ty::Slice(t) => write!(f, "[{}]", t),
@@ -587,7 +605,7 @@ fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
587 | BinaryOp::BitwiseAnd 605 | BinaryOp::BitwiseAnd
588 | BinaryOp::BitwiseOr 606 | BinaryOp::BitwiseOr
589 | BinaryOp::BitwiseXor => match rhs_ty { 607 | BinaryOp::BitwiseXor => match rhs_ty {
590 Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => rhs_ty, 608 Ty::Int(..) | Ty::Float(..) => rhs_ty,
591 _ => Ty::Unknown, 609 _ => Ty::Unknown,
592 }, 610 },
593 BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown, 611 BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown,
@@ -598,7 +616,7 @@ fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
598 match op { 616 match op {
599 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool, 617 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool,
600 BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty { 618 BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty {
601 Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty, 619 Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty,
602 _ => Ty::Unknown, 620 _ => Ty::Unknown,
603 }, 621 },
604 BinaryOp::LesserEqualTest 622 BinaryOp::LesserEqualTest
@@ -625,7 +643,7 @@ fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
625 | BinaryOp::BitwiseAnd 643 | BinaryOp::BitwiseAnd
626 | BinaryOp::BitwiseOr 644 | BinaryOp::BitwiseOr
627 | BinaryOp::BitwiseXor => match lhs_ty { 645 | BinaryOp::BitwiseXor => match lhs_ty {
628 Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => lhs_ty, 646 Ty::Int(..) | Ty::Float(..) => lhs_ty,
629 _ => Ty::Unknown, 647 _ => Ty::Unknown,
630 }, 648 },
631 _ => Ty::Unknown, 649 _ => Ty::Unknown,
@@ -695,13 +713,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
695 match (&*ty1, &*ty2) { 713 match (&*ty1, &*ty2) {
696 (Ty::Unknown, ..) => true, 714 (Ty::Unknown, ..) => true,
697 (.., Ty::Unknown) => true, 715 (.., Ty::Unknown) => true,
698 (Ty::Bool, _) 716 (Ty::Int(t1), Ty::Int(t2)) => match (t1, t2) {
699 | (Ty::Str, _) 717 (primitive::UncertainIntTy::Unknown, _)
700 | (Ty::Never, _) 718 | (_, primitive::UncertainIntTy::Unknown) => true,
701 | (Ty::Char, _) 719 _ => t1 == t2,
702 | (Ty::Int(..), Ty::Int(..)) 720 },
703 | (Ty::Uint(..), Ty::Uint(..)) 721 (Ty::Float(t1), Ty::Float(t2)) => match (t1, t2) {
704 | (Ty::Float(..), Ty::Float(..)) => ty1 == ty2, 722 (primitive::UncertainFloatTy::Unknown, _)
723 | (_, primitive::UncertainFloatTy::Unknown) => true,
724 _ => t1 == t2,
725 },
726 (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2,
705 ( 727 (
706 Ty::Adt { 728 Ty::Adt {
707 def_id: def_id1, .. 729 def_id: def_id1, ..
@@ -718,12 +740,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
718 .iter() 740 .iter()
719 .zip(ts2.iter()) 741 .zip(ts2.iter())
720 .all(|(t1, t2)| self.unify(t1, t2)), 742 .all(|(t1, t2)| self.unify(t1, t2)),
721 (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) => { 743 (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2)))
744 | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2)))
745 | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => {
722 // both type vars are unknown since we tried to resolve them 746 // both type vars are unknown since we tried to resolve them
723 self.var_unification_table.union(*tv1, *tv2); 747 self.var_unification_table.union(*tv1, *tv2);
724 true 748 true
725 } 749 }
726 (Ty::Infer(InferTy::TypeVar(tv)), other) | (other, Ty::Infer(InferTy::TypeVar(tv))) => { 750 (Ty::Infer(InferTy::TypeVar(tv)), other)
751 | (other, Ty::Infer(InferTy::TypeVar(tv)))
752 | (Ty::Infer(InferTy::IntVar(tv)), other)
753 | (other, Ty::Infer(InferTy::IntVar(tv)))
754 | (Ty::Infer(InferTy::FloatVar(tv)), other)
755 | (other, Ty::Infer(InferTy::FloatVar(tv))) => {
727 // the type var is unknown since we tried to resolve it 756 // the type var is unknown since we tried to resolve it
728 self.var_unification_table 757 self.var_unification_table
729 .union_value(*tv, TypeVarValue::Known(other.clone())); 758 .union_value(*tv, TypeVarValue::Known(other.clone()));
@@ -739,10 +768,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
739 )) 768 ))
740 } 769 }
741 770
771 fn new_integer_var(&mut self) -> Ty {
772 Ty::Infer(InferTy::IntVar(
773 self.var_unification_table.new_key(TypeVarValue::Unknown),
774 ))
775 }
776
777 fn new_float_var(&mut self) -> Ty {
778 Ty::Infer(InferTy::FloatVar(
779 self.var_unification_table.new_key(TypeVarValue::Unknown),
780 ))
781 }
782
742 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. 783 /// 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 { 784 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
744 match ty { 785 match ty {
745 Ty::Unknown => self.new_type_var(), 786 Ty::Unknown => self.new_type_var(),
787 Ty::Int(primitive::UncertainIntTy::Unknown) => self.new_integer_var(),
788 Ty::Float(primitive::UncertainFloatTy::Unknown) => self.new_float_var(),
746 _ => ty, 789 _ => ty,
747 } 790 }
748 } 791 }
@@ -757,12 +800,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
757 /// known type. 800 /// known type.
758 fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { 801 fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty {
759 ty.fold(&mut |ty| match ty { 802 ty.fold(&mut |ty| match ty {
760 Ty::Infer(InferTy::TypeVar(tv)) => { 803 Ty::Infer(tv) => {
761 if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { 804 let inner = tv.to_inner();
805 if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() {
762 // known_ty may contain other variables that are known by now 806 // known_ty may contain other variables that are known by now
763 self.resolve_ty_as_possible(known_ty.clone()) 807 self.resolve_ty_as_possible(known_ty.clone())
764 } else { 808 } else {
765 Ty::Infer(InferTy::TypeVar(tv)) 809 ty
766 } 810 }
767 } 811 }
768 _ => ty, 812 _ => ty,
@@ -773,8 +817,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
773 /// otherwise, return ty. 817 /// otherwise, return ty.
774 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { 818 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> {
775 match ty { 819 match ty {
776 Ty::Infer(InferTy::TypeVar(tv)) => { 820 Ty::Infer(tv) => {
777 match self.var_unification_table.probe_value(*tv).known() { 821 let inner = tv.to_inner();
822 match self.var_unification_table.probe_value(inner).known() {
778 Some(known_ty) => { 823 Some(known_ty) => {
779 // The known_ty can't be a type var itself 824 // The known_ty can't be a type var itself
780 Cow::Owned(known_ty.clone()) 825 Cow::Owned(known_ty.clone())
@@ -790,12 +835,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
790 /// replaced by Ty::Unknown. 835 /// replaced by Ty::Unknown.
791 fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { 836 fn resolve_ty_completely(&mut self, ty: Ty) -> Ty {
792 ty.fold(&mut |ty| match ty { 837 ty.fold(&mut |ty| match ty {
793 Ty::Infer(InferTy::TypeVar(tv)) => { 838 Ty::Infer(tv) => {
794 if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { 839 let inner = tv.to_inner();
840 if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() {
795 // known_ty may contain other variables that are known by now 841 // known_ty may contain other variables that are known by now
796 self.resolve_ty_completely(known_ty.clone()) 842 self.resolve_ty_completely(known_ty.clone())
797 } else { 843 } else {
798 Ty::Unknown 844 tv.fallback_value()
799 } 845 }
800 } 846 }
801 _ => ty, 847 _ => ty,
@@ -1067,6 +1113,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1067 1113
1068 Ty::Tuple(Arc::from(ty_vec)) 1114 Ty::Tuple(Arc::from(ty_vec))
1069 } 1115 }
1116 Expr::Literal(lit) => match lit {
1117 Literal::Bool(..) => Ty::Bool,
1118 Literal::String(..) => Ty::Ref(Arc::new(Ty::Str), Mutability::Shared),
1119 Literal::ByteString(..) => {
1120 let byte_type = Arc::new(Ty::Int(primitive::UncertainIntTy::Unsigned(
1121 primitive::UintTy::U8,
1122 )));
1123 let slice_type = Arc::new(Ty::Slice(byte_type));
1124 Ty::Ref(slice_type, Mutability::Shared)
1125 }
1126 Literal::Char(..) => Ty::Char,
1127 Literal::Int(_v, ty) => Ty::Int(*ty),
1128 Literal::Float(_v, ty) => Ty::Float(*ty),
1129 },
1070 }; 1130 };
1071 // use a new type variable if we got Ty::Unknown here 1131 // use a new type variable if we got Ty::Unknown here
1072 let ty = self.insert_type_vars_shallow(ty); 1132 let ty = self.insert_type_vars_shallow(ty);