aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2018-12-25 16:17:39 +0000
committerFlorian Diebold <[email protected]>2018-12-25 19:36:06 +0000
commit2870effd5c69941bbf32a44c0ee6d9d42e0b038d (patch)
treebf2c5ff08e6f316c1d9d629ae3595e6f7c069e5d /crates/ra_hir/src/ty.rs
parentb96d3612390e070936a176571c946ad0cafa69a9 (diff)
Implement reference / pointer types
- parse them - infer types of & and * expressions
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs84
1 files changed, 69 insertions, 15 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 3674688ef..54aa6715c 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -11,7 +11,7 @@ use rustc_hash::{FxHashMap};
11use ra_db::{LocalSyntaxPtr, Cancelable}; 11use ra_db::{LocalSyntaxPtr, Cancelable};
12use ra_syntax::{ 12use ra_syntax::{
13 SmolStr, 13 SmolStr,
14 ast::{self, AstNode, LoopBodyOwner, ArgListOwner}, 14 ast::{self, AstNode, LoopBodyOwner, ArgListOwner, PrefixOp},
15 SyntaxNodeRef 15 SyntaxNodeRef
16}; 16};
17 17
@@ -21,6 +21,36 @@ use crate::{
21 adt::VariantData, 21 adt::VariantData,
22}; 22};
23 23
24#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
25pub enum Mutability {
26 Shared,
27 Mut,
28}
29
30impl Mutability {
31 pub fn from_mutable(mutable: bool) -> Mutability {
32 if mutable {
33 Mutability::Mut
34 } else {
35 Mutability::Shared
36 }
37 }
38
39 pub fn as_keyword_for_ref(self) -> &'static str {
40 match self {
41 Mutability::Shared => "",
42 Mutability::Mut => "mut ",
43 }
44 }
45
46 pub fn as_keyword_for_ptr(self) -> &'static str {
47 match self {
48 Mutability::Shared => "const ",
49 Mutability::Mut => "mut ",
50 }
51 }
52}
53
24#[derive(Clone, PartialEq, Eq, Hash, Debug)] 54#[derive(Clone, PartialEq, Eq, Hash, Debug)]
25pub enum Ty { 55pub enum Ty {
26 /// The primitive boolean type. Written as `bool`. 56 /// The primitive boolean type. Written as `bool`.
@@ -56,12 +86,13 @@ pub enum Ty {
56 /// The pointee of an array slice. Written as `[T]`. 86 /// The pointee of an array slice. Written as `[T]`.
57 Slice(TyRef), 87 Slice(TyRef),
58 88
59 // A raw pointer. Written as `*mut T` or `*const T` 89 /// A raw pointer. Written as `*mut T` or `*const T`
60 // RawPtr(TypeAndMut<'tcx>), 90 RawPtr(TyRef, Mutability),
91
92 /// A reference; a pointer with an associated lifetime. Written as
93 /// `&'a mut T` or `&'a T`.
94 Ref(TyRef, Mutability),
61 95
62 // A reference; a pointer with an associated lifetime. Written as
63 // `&'a mut T` or `&'a T`.
64 // Ref(Ty<'tcx>, hir::Mutability),
65 /// A pointer to a function. Written as `fn() -> i32`. 96 /// A pointer to a function. Written as `fn() -> i32`.
66 /// 97 ///
67 /// For example the type of `bar` here: 98 /// For example the type of `bar` here:
@@ -172,7 +203,7 @@ impl Ty {
172 ) -> Cancelable<Self> { 203 ) -> Cancelable<Self> {
173 use ra_syntax::ast::TypeRef::*; 204 use ra_syntax::ast::TypeRef::*;
174 Ok(match node { 205 Ok(match node {
175 ParenType(_inner) => Ty::Unknown, // TODO 206 ParenType(inner) => Ty::new_opt(db, module, inner.type_ref())?,
176 TupleType(_inner) => Ty::Unknown, // TODO 207 TupleType(_inner) => Ty::Unknown, // TODO
177 NeverType(..) => Ty::Never, 208 NeverType(..) => Ty::Never,
178 PathType(inner) => { 209 PathType(inner) => {
@@ -182,10 +213,18 @@ impl Ty {
182 Ty::Unknown 213 Ty::Unknown
183 } 214 }
184 } 215 }
185 PointerType(_inner) => Ty::Unknown, // TODO 216 PointerType(inner) => {
186 ArrayType(_inner) => Ty::Unknown, // TODO 217 let inner_ty = Ty::new_opt(db, module, inner.type_ref())?;
187 SliceType(_inner) => Ty::Unknown, // TODO 218 let mutability = Mutability::from_mutable(inner.is_mut());
188 ReferenceType(_inner) => Ty::Unknown, // TODO 219 Ty::RawPtr(Arc::new(inner_ty), mutability)
220 }
221 ArrayType(_inner) => Ty::Unknown, // TODO
222 SliceType(_inner) => Ty::Unknown, // TODO
223 ReferenceType(inner) => {
224 let inner_ty = Ty::new_opt(db, module, inner.type_ref())?;
225 let mutability = Mutability::from_mutable(inner.is_mut());
226 Ty::Ref(Arc::new(inner_ty), mutability)
227 }
189 PlaceholderType(_inner) => Ty::Unknown, // TODO 228 PlaceholderType(_inner) => Ty::Unknown, // TODO
190 FnPointerType(_inner) => Ty::Unknown, // TODO 229 FnPointerType(_inner) => Ty::Unknown, // TODO
191 ForType(_inner) => Ty::Unknown, // TODO 230 ForType(_inner) => Ty::Unknown, // TODO
@@ -209,6 +248,8 @@ impl fmt::Display for Ty {
209 Ty::Float(t) => write!(f, "{}", t.ty_to_string()), 248 Ty::Float(t) => write!(f, "{}", t.ty_to_string()),
210 Ty::Str => write!(f, "str"), 249 Ty::Str => write!(f, "str"),
211 Ty::Slice(t) => write!(f, "[{}]", t), 250 Ty::Slice(t) => write!(f, "[{}]", t),
251 Ty::RawPtr(t, m) => write!(f, "*{}{}", m.as_keyword_for_ptr(), t),
252 Ty::Ref(t, m) => write!(f, "&{}{}", m.as_keyword_for_ref(), t),
212 Ty::Never => write!(f, "!"), 253 Ty::Never => write!(f, "!"),
213 Ty::Tuple(ts) => { 254 Ty::Tuple(ts) => {
214 write!(f, "(")?; 255 write!(f, "(")?;
@@ -539,12 +580,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
539 cast_ty 580 cast_ty
540 } 581 }
541 ast::Expr::RefExpr(e) => { 582 ast::Expr::RefExpr(e) => {
542 let _inner_ty = self.infer_expr_opt(e.expr())?; 583 let inner_ty = self.infer_expr_opt(e.expr())?;
543 Ty::Unknown 584 let m = Mutability::from_mutable(e.is_mut());
585 // TODO reference coercions etc.
586 Ty::Ref(Arc::new(inner_ty), m)
544 } 587 }
545 ast::Expr::PrefixExpr(e) => { 588 ast::Expr::PrefixExpr(e) => {
546 let _inner_ty = self.infer_expr_opt(e.expr())?; 589 let inner_ty = self.infer_expr_opt(e.expr())?;
547 Ty::Unknown 590 match e.op() {
591 Some(PrefixOp::Deref) => {
592 match inner_ty {
593 // builtin deref:
594 Ty::Ref(ref_inner, _) => (*ref_inner).clone(),
595 Ty::RawPtr(ptr_inner, _) => (*ptr_inner).clone(),
596 // TODO Deref::deref
597 _ => Ty::Unknown,
598 }
599 }
600 _ => Ty::Unknown,
601 }
548 } 602 }
549 ast::Expr::RangeExpr(_e) => Ty::Unknown, 603 ast::Expr::RangeExpr(_e) => Ty::Unknown,
550 ast::Expr::BinExpr(_e) => Ty::Unknown, 604 ast::Expr::BinExpr(_e) => Ty::Unknown,