diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 58 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 53 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/primitive.rs | 50 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/basics.txt | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/binary_op.txt | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/let.txt | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/literals.txt | 2 |
7 files changed, 128 insertions, 45 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index e07725d05..bc8515836 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -11,6 +11,7 @@ use ra_syntax::{ | |||
11 | }; | 11 | }; |
12 | 12 | ||
13 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; | 13 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; |
14 | use crate::ty::primitive::{UintTy, IntTy, FloatTy, UncertainIntTy, UncertainFloatTy}; | ||
14 | 15 | ||
15 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 16 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
16 | pub struct ExprId(RawId); | 17 | pub struct ExprId(RawId); |
@@ -112,9 +113,8 @@ pub enum Literal { | |||
112 | ByteString(Vec<u8>), | 113 | ByteString(Vec<u8>), |
113 | Char(char), | 114 | Char(char), |
114 | Bool(bool), | 115 | Bool(bool), |
115 | Byte(u8), | 116 | Int(u64, UncertainIntTy), |
116 | Int, // this and float need additional information | 117 | Float(u64, UncertainFloatTy), // FIXME: f64 is not Eq |
117 | Float, | ||
118 | Tuple { values: Vec<ExprId> }, | 118 | Tuple { values: Vec<ExprId> }, |
119 | Array { values: Vec<ExprId> }, | 119 | Array { values: Vec<ExprId> }, |
120 | } | 120 | } |
@@ -328,13 +328,7 @@ impl Expr { | |||
328 | f(val); | 328 | f(val); |
329 | } | 329 | } |
330 | } | 330 | } |
331 | Literal::String(..) | 331 | _ => {} |
332 | | Literal::ByteString(..) | ||
333 | | Literal::Byte(..) | ||
334 | | Literal::Bool(..) | ||
335 | | Literal::Char(..) | ||
336 | | Literal::Int | ||
337 | | Literal::Float => {} | ||
338 | }, | 332 | }, |
339 | } | 333 | } |
340 | } | 334 | } |
@@ -669,8 +663,43 @@ impl ExprCollector { | |||
669 | 663 | ||
670 | if let Some(c) = child { | 664 | if let Some(c) = child { |
671 | let lit = match c.kind() { | 665 | let lit = match c.kind() { |
672 | SyntaxKind::INT_NUMBER => Literal::Int, | 666 | SyntaxKind::INT_NUMBER => { |
673 | SyntaxKind::FLOAT_NUMBER => Literal::Float, | 667 | let text = c.text().to_string(); |
668 | |||
669 | // FIXME: don't do it like this. maybe use something like | ||
670 | // the IntTy::from_name functions | ||
671 | let ty = if text.ends_with("isize") { | ||
672 | UncertainIntTy::Signed(IntTy::Isize) | ||
673 | } else if text.ends_with("i128") { | ||
674 | UncertainIntTy::Signed(IntTy::I128) | ||
675 | } else if text.ends_with("i64") { | ||
676 | UncertainIntTy::Signed(IntTy::I64) | ||
677 | } else if text.ends_with("i32") { | ||
678 | UncertainIntTy::Signed(IntTy::I32) | ||
679 | } else if text.ends_with("i16") { | ||
680 | UncertainIntTy::Signed(IntTy::I16) | ||
681 | } else if text.ends_with("i8") { | ||
682 | UncertainIntTy::Signed(IntTy::I8) | ||
683 | } else if text.ends_with("usize") { | ||
684 | UncertainIntTy::Unsigned(UintTy::Usize) | ||
685 | } else if text.ends_with("u128") { | ||
686 | UncertainIntTy::Unsigned(UintTy::U128) | ||
687 | } else if text.ends_with("u64") { | ||
688 | UncertainIntTy::Unsigned(UintTy::U64) | ||
689 | } else if text.ends_with("u32") { | ||
690 | UncertainIntTy::Unsigned(UintTy::U32) | ||
691 | } else if text.ends_with("u16") { | ||
692 | UncertainIntTy::Unsigned(UintTy::U16) | ||
693 | } else if text.ends_with("u8") { | ||
694 | UncertainIntTy::Unsigned(UintTy::U8) | ||
695 | } else { | ||
696 | UncertainIntTy::Unknown | ||
697 | }; | ||
698 | |||
699 | // TODO: actually parse integer | ||
700 | Literal::Int(0u64, ty) | ||
701 | } | ||
702 | SyntaxKind::FLOAT_NUMBER => Literal::Float(0, UncertainFloatTy::Unknown), | ||
674 | SyntaxKind::STRING => { | 703 | SyntaxKind::STRING => { |
675 | // FIXME: this likely includes the " characters | 704 | // FIXME: this likely includes the " characters |
676 | let text = c.text().to_string(); | 705 | let text = c.text().to_string(); |
@@ -698,7 +727,10 @@ impl ExprCollector { | |||
698 | } | 727 | } |
699 | SyntaxKind::BYTE => { | 728 | SyntaxKind::BYTE => { |
700 | let character = c.text().char_at(1).unwrap_or('X'); | 729 | let character = c.text().char_at(1).unwrap_or('X'); |
701 | Literal::Byte(character as u8) | 730 | Literal::Int( |
731 | character as u8 as u64, | ||
732 | UncertainIntTy::Unsigned(UintTy::U8), | ||
733 | ) | ||
702 | } | 734 | } |
703 | _ => return self.alloc_expr(Expr::Missing, syntax_ptr), | 735 | _ => return self.alloc_expr(Expr::Missing, syntax_ptr), |
704 | }; | 736 | }; |
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 | ||
16 | mod autoderef; | 16 | mod autoderef; |
17 | mod primitive; | 17 | pub(crate) mod primitive; |
18 | #[cfg(test)] | 18 | #[cfg(test)] |
19 | mod tests; | 19 | mod tests; |
20 | pub(crate) mod method_resolution; | 20 | pub(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 |
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index 498d42d52..5741ca90d 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs | |||
@@ -2,6 +2,56 @@ use std::fmt; | |||
2 | 2 | ||
3 | use crate::{Name, KnownName}; | 3 | use crate::{Name, KnownName}; |
4 | 4 | ||
5 | #[derive(Debug, Clone, Eq, PartialEq, Hash, Copy)] | ||
6 | pub enum UncertainIntTy { | ||
7 | Unknown, | ||
8 | Unsigned(UintTy), | ||
9 | Signed(IntTy), | ||
10 | } | ||
11 | |||
12 | impl UncertainIntTy { | ||
13 | pub fn ty_to_string(&self) -> &'static str { | ||
14 | match *self { | ||
15 | UncertainIntTy::Unknown => "{integer}", | ||
16 | UncertainIntTy::Signed(ty) => ty.ty_to_string(), | ||
17 | UncertainIntTy::Unsigned(ty) => ty.ty_to_string(), | ||
18 | } | ||
19 | } | ||
20 | |||
21 | pub fn from_name(name: &Name) -> Option<UncertainIntTy> { | ||
22 | if let Some(ty) = IntTy::from_name(name) { | ||
23 | Some(UncertainIntTy::Signed(ty)) | ||
24 | } else if let Some(ty) = UintTy::from_name(name) { | ||
25 | Some(UncertainIntTy::Unsigned(ty)) | ||
26 | } else { | ||
27 | None | ||
28 | } | ||
29 | } | ||
30 | } | ||
31 | |||
32 | #[derive(Debug, Clone, Eq, PartialEq, Hash, Copy)] | ||
33 | pub enum UncertainFloatTy { | ||
34 | Unknown, | ||
35 | Known(FloatTy), | ||
36 | } | ||
37 | |||
38 | impl UncertainFloatTy { | ||
39 | pub fn ty_to_string(&self) -> &'static str { | ||
40 | match *self { | ||
41 | UncertainFloatTy::Unknown => "{float}", | ||
42 | UncertainFloatTy::Known(ty) => ty.ty_to_string(), | ||
43 | } | ||
44 | } | ||
45 | |||
46 | pub fn from_name(name: &Name) -> Option<UncertainFloatTy> { | ||
47 | if let Some(ty) = FloatTy::from_name(name) { | ||
48 | Some(UncertainFloatTy::Known(ty)) | ||
49 | } else { | ||
50 | None | ||
51 | } | ||
52 | } | ||
53 | } | ||
54 | |||
5 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] | 55 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] |
6 | pub enum IntTy { | 56 | pub enum IntTy { |
7 | Isize, | 57 | Isize, |
diff --git a/crates/ra_hir/src/ty/tests/data/basics.txt b/crates/ra_hir/src/ty/tests/data/basics.txt index e02947ba8..4a3b69b7e 100644 --- a/crates/ra_hir/src/ty/tests/data/basics.txt +++ b/crates/ra_hir/src/ty/tests/data/basics.txt | |||
@@ -7,7 +7,7 @@ | |||
7 | [55; 56) 'b': isize | 7 | [55; 56) 'b': isize |
8 | [62; 63) 'c': ! | 8 | [62; 63) 'c': ! |
9 | [69; 70) 'd': &str | 9 | [69; 70) 'd': &str |
10 | [76; 82) '1usize': [unknown] | 10 | [76; 82) '1usize': usize |
11 | [88; 94) '1isize': [unknown] | 11 | [88; 94) '1isize': isize |
12 | [100; 106) '"test"': &str | 12 | [100; 106) '"test"': &str |
13 | [112; 118) '1.0f32': [unknown] | 13 | [112; 118) '1.0f32': [unknown] |
diff --git a/crates/ra_hir/src/ty/tests/data/binary_op.txt b/crates/ra_hir/src/ty/tests/data/binary_op.txt index 8a515ac5e..7fdb8a900 100644 --- a/crates/ra_hir/src/ty/tests/data/binary_op.txt +++ b/crates/ra_hir/src/ty/tests/data/binary_op.txt | |||
@@ -16,7 +16,7 @@ | |||
16 | [112; 113) 'y': bool | 16 | [112; 113) 'y': bool |
17 | [123; 134) 'minus_forty': isize | 17 | [123; 134) 'minus_forty': isize |
18 | [144; 152) '-40isize': isize | 18 | [144; 152) '-40isize': isize |
19 | [145; 152) '40isize': [unknown] | 19 | [145; 152) '40isize': isize |
20 | [162; 163) 'h': bool | 20 | [162; 163) 'h': bool |
21 | [166; 177) 'minus_forty': isize | 21 | [166; 177) 'minus_forty': isize |
22 | [166; 188) 'minus_...ONST_2': bool | 22 | [166; 188) 'minus_...ONST_2': bool |
diff --git a/crates/ra_hir/src/ty/tests/data/let.txt b/crates/ra_hir/src/ty/tests/data/let.txt index 30f4a2cf5..8815dba41 100644 --- a/crates/ra_hir/src/ty/tests/data/let.txt +++ b/crates/ra_hir/src/ty/tests/data/let.txt | |||
@@ -1,6 +1,6 @@ | |||
1 | [11; 71) '{ ...= b; }': () | 1 | [11; 71) '{ ...= b; }': () |
2 | [21; 22) 'a': [unknown] | 2 | [21; 22) 'a': isize |
3 | [25; 31) '1isize': [unknown] | 3 | [25; 31) '1isize': isize |
4 | [41; 42) 'b': usize | 4 | [41; 42) 'b': usize |
5 | [52; 53) '1': usize | 5 | [52; 53) '1': usize |
6 | [63; 64) 'c': usize | 6 | [63; 64) 'c': usize |
diff --git a/crates/ra_hir/src/ty/tests/data/literals.txt b/crates/ra_hir/src/ty/tests/data/literals.txt index 8b22eee31..e139d57a8 100644 --- a/crates/ra_hir/src/ty/tests/data/literals.txt +++ b/crates/ra_hir/src/ty/tests/data/literals.txt | |||
@@ -1,5 +1,5 @@ | |||
1 | [11; 135) '{ ...lse] }': () | 1 | [11; 135) '{ ...lse] }': () |
2 | [17; 21) '5i32': [unknown] | 2 | [17; 21) '5i32': i32 |
3 | [27; 34) '"hello"': &str | 3 | [27; 34) '"hello"': &str |
4 | [40; 48) 'b"bytes"': &[u8] | 4 | [40; 48) 'b"bytes"': &[u8] |
5 | [54; 57) ''c'': char | 5 | [54; 57) ''c'': char |