aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
authorMarcus Klaas de Vries <[email protected]>2019-01-10 15:03:15 +0000
committerMarcus Klaas de Vries <[email protected]>2019-01-14 12:52:57 +0000
commit5f5dc20d85dead5fbd51d163451f796255c9faea (patch)
tree2027553e671ee8c94dd1b6e5045868fd479cd682 /crates/ra_hir/src/ty.rs
parenta6146d35b1615cf5fb908b29f34e58bfde3bf96d (diff)
Try implementing integer type inference (WIP)
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs53
1 files changed, 27 insertions, 26 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 0baa205a1..13a1c2907 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;
@@ -151,14 +151,13 @@ pub enum Ty {
151 /// (a non-surrogate code point). Written as `char`. 151 /// (a non-surrogate code point). Written as `char`.
152 Char, 152 Char,
153 153
154 /// A primitive signed integer type. For example, `i32`. 154 /// A primitive integer type. For example, `i32`.
155 Int(primitive::IntTy), 155 Int(primitive::UncertainIntTy),
156
157 /// A primitive unsigned integer type. For example, `u32`.
158 Uint(primitive::UintTy),
159 156
157 // /// A primitive unsigned integer type. For example, `u32`.
158 // Uint(primitive::UintTy),
160 /// A primitive floating-point type. For example, `f64`. 159 /// A primitive floating-point type. For example, `f64`.
161 Float(primitive::FloatTy), 160 Float(primitive::UncertainFloatTy),
162 161
163 /// Structures, enumerations and unions. 162 /// Structures, enumerations and unions.
164 Adt { 163 Adt {
@@ -318,11 +317,9 @@ impl Ty {
318 return Ok(Ty::Char); 317 return Ok(Ty::Char);
319 } else if let Some(KnownName::Str) = name.as_known_name() { 318 } else if let Some(KnownName::Str) = name.as_known_name() {
320 return Ok(Ty::Str); 319 return Ok(Ty::Str);
321 } else if let Some(int_ty) = primitive::IntTy::from_name(name) { 320 } else if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) {
322 return Ok(Ty::Int(int_ty)); 321 return Ok(Ty::Int(int_ty));
323 } else if let Some(uint_ty) = primitive::UintTy::from_name(name) { 322 } 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)); 323 return Ok(Ty::Float(float_ty));
327 } else if name.as_known_name() == Some(KnownName::SelfType) { 324 } 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())); 325 return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type()));
@@ -392,7 +389,6 @@ impl fmt::Display for Ty {
392 Ty::Bool => write!(f, "bool"), 389 Ty::Bool => write!(f, "bool"),
393 Ty::Char => write!(f, "char"), 390 Ty::Char => write!(f, "char"),
394 Ty::Int(t) => write!(f, "{}", t.ty_to_string()), 391 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()), 392 Ty::Float(t) => write!(f, "{}", t.ty_to_string()),
397 Ty::Str => write!(f, "str"), 393 Ty::Str => write!(f, "str"),
398 Ty::Slice(t) => write!(f, "[{}]", t), 394 Ty::Slice(t) => write!(f, "[{}]", t),
@@ -587,7 +583,7 @@ fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
587 | BinaryOp::BitwiseAnd 583 | BinaryOp::BitwiseAnd
588 | BinaryOp::BitwiseOr 584 | BinaryOp::BitwiseOr
589 | BinaryOp::BitwiseXor => match rhs_ty { 585 | BinaryOp::BitwiseXor => match rhs_ty {
590 Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => rhs_ty, 586 Ty::Int(..) | Ty::Float(..) => rhs_ty,
591 _ => Ty::Unknown, 587 _ => Ty::Unknown,
592 }, 588 },
593 BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown, 589 BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown,
@@ -598,7 +594,7 @@ fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
598 match op { 594 match op {
599 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool, 595 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool,
600 BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty { 596 BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty {
601 Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty, 597 Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty,
602 _ => Ty::Unknown, 598 _ => Ty::Unknown,
603 }, 599 },
604 BinaryOp::LesserEqualTest 600 BinaryOp::LesserEqualTest
@@ -625,7 +621,7 @@ fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
625 | BinaryOp::BitwiseAnd 621 | BinaryOp::BitwiseAnd
626 | BinaryOp::BitwiseOr 622 | BinaryOp::BitwiseOr
627 | BinaryOp::BitwiseXor => match lhs_ty { 623 | BinaryOp::BitwiseXor => match lhs_ty {
628 Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => lhs_ty, 624 Ty::Int(..) | Ty::Float(..) => lhs_ty,
629 _ => Ty::Unknown, 625 _ => Ty::Unknown,
630 }, 626 },
631 _ => Ty::Unknown, 627 _ => Ty::Unknown,
@@ -695,13 +691,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
695 match (&*ty1, &*ty2) { 691 match (&*ty1, &*ty2) {
696 (Ty::Unknown, ..) => true, 692 (Ty::Unknown, ..) => true,
697 (.., Ty::Unknown) => true, 693 (.., Ty::Unknown) => true,
698 (Ty::Bool, _) 694 (Ty::Int(t1), Ty::Int(t2)) => match (t1, t2) {
699 | (Ty::Str, _) 695 (primitive::UncertainIntTy::Unknown, _)
700 | (Ty::Never, _) 696 | (_, primitive::UncertainIntTy::Unknown) => true,
701 | (Ty::Char, _) 697 _ => t1 == t2,
702 | (Ty::Int(..), Ty::Int(..)) 698 },
703 | (Ty::Uint(..), Ty::Uint(..)) 699 (Ty::Float(t1), Ty::Float(t2)) => match (t1, t2) {
704 | (Ty::Float(..), Ty::Float(..)) => ty1 == ty2, 700 (primitive::UncertainFloatTy::Unknown, _)
701 | (_, primitive::UncertainFloatTy::Unknown) => true,
702 _ => t1 == t2,
703 },
704 (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2,
705 ( 705 (
706 Ty::Adt { 706 Ty::Adt {
707 def_id: def_id1, .. 707 def_id: def_id1, ..
@@ -1071,11 +1071,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1071 Literal::Bool(..) => Ty::Bool, 1071 Literal::Bool(..) => Ty::Bool,
1072 Literal::String(..) => Ty::Ref(Arc::new(Ty::Str), Mutability::Shared), 1072 Literal::String(..) => Ty::Ref(Arc::new(Ty::Str), Mutability::Shared),
1073 Literal::ByteString(..) => { 1073 Literal::ByteString(..) => {
1074 let byte_type = Arc::new(Ty::Uint(primitive::UintTy::U8)); 1074 let byte_type = Arc::new(Ty::Int(primitive::UncertainIntTy::Unsigned(
1075 primitive::UintTy::U8,
1076 )));
1075 let slice_type = Arc::new(Ty::Slice(byte_type)); 1077 let slice_type = Arc::new(Ty::Slice(byte_type));
1076 Ty::Ref(slice_type, Mutability::Shared) 1078 Ty::Ref(slice_type, Mutability::Shared)
1077 } 1079 }
1078 Literal::Byte(..) => Ty::Uint(primitive::UintTy::U8),
1079 Literal::Char(..) => Ty::Char, 1080 Literal::Char(..) => Ty::Char,
1080 Literal::Tuple { values } => { 1081 Literal::Tuple { values } => {
1081 let mut inner_tys = Vec::new(); 1082 let mut inner_tys = Vec::new();
@@ -1095,8 +1096,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1095 // available 1096 // available
1096 Ty::Slice(Arc::new(inner_ty)) 1097 Ty::Slice(Arc::new(inner_ty))
1097 } 1098 }
1098 // TODO 1099 Literal::Int(_v, ty) => Ty::Int(*ty),
1099 Literal::Int | Literal::Float => Ty::Unknown, 1100 Literal::Float(_v, ty) => Ty::Float(*ty),
1100 }, 1101 },
1101 }; 1102 };
1102 // use a new type variable if we got Ty::Unknown here 1103 // use a new type variable if we got Ty::Unknown here