aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/type_ref.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2018-12-25 20:14:13 +0000
committerFlorian Diebold <[email protected]>2018-12-25 20:14:13 +0000
commitcdca39706121b2d1734a94938a2372da881e10c6 (patch)
treed3f9687371eb1a7004c4694c59445af388eb1876 /crates/ra_hir/src/type_ref.rs
parent2870effd5c69941bbf32a44c0ee6d9d42e0b038d (diff)
Add a hir::TypeRef as an intermediate between ast::TypeRef and ty::Ty
Diffstat (limited to 'crates/ra_hir/src/type_ref.rs')
-rw-r--r--crates/ra_hir/src/type_ref.rs110
1 files changed, 110 insertions, 0 deletions
diff --git a/crates/ra_hir/src/type_ref.rs b/crates/ra_hir/src/type_ref.rs
new file mode 100644
index 000000000..ae163313f
--- /dev/null
+++ b/crates/ra_hir/src/type_ref.rs
@@ -0,0 +1,110 @@
1//! HIR for references to types. Paths in these are not yet resolved. They can
2//! be directly created from an ast::TypeRef, without further queries.
3
4use ra_syntax::ast;
5
6use crate::Path;
7
8#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
9pub enum Mutability {
10 Shared,
11 Mut,
12}
13
14impl Mutability {
15 pub fn from_mutable(mutable: bool) -> Mutability {
16 if mutable {
17 Mutability::Mut
18 } else {
19 Mutability::Shared
20 }
21 }
22
23 pub fn as_keyword_for_ref(self) -> &'static str {
24 match self {
25 Mutability::Shared => "",
26 Mutability::Mut => "mut ",
27 }
28 }
29
30 pub fn as_keyword_for_ptr(self) -> &'static str {
31 match self {
32 Mutability::Shared => "const ",
33 Mutability::Mut => "mut ",
34 }
35 }
36}
37
38/// Compare ty::Ty
39#[derive(Clone, PartialEq, Eq, Hash, Debug)]
40pub enum TypeRef {
41 Never,
42 Placeholder,
43 Tuple(Vec<TypeRef>),
44 Path(Path),
45 RawPtr(Box<TypeRef>, Mutability),
46 Reference(Box<TypeRef>, Mutability),
47 Array(Box<TypeRef> /*, Expr*/),
48 Slice(Box<TypeRef>),
49 /// A fn pointer. Last element of the vector is the return type.
50 Fn(Vec<TypeRef>),
51 // For
52 // ImplTrait,
53 // DynTrait,
54 Error,
55}
56
57impl TypeRef {
58 /// Converts an `ast::TypeRef` to a `hir::TypeRef`.
59 pub(crate) fn from_ast(node: ast::TypeRef) -> Self {
60 use ra_syntax::ast::TypeRef::*;
61 match node {
62 ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()),
63 TupleType(inner) => TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()),
64 NeverType(..) => TypeRef::Never,
65 PathType(inner) => inner
66 .path()
67 .and_then(Path::from_ast)
68 .map(TypeRef::Path)
69 .unwrap_or(TypeRef::Error),
70 PointerType(inner) => {
71 let inner_ty = TypeRef::from_ast_opt(inner.type_ref());
72 let mutability = Mutability::from_mutable(inner.is_mut());
73 TypeRef::RawPtr(Box::new(inner_ty), mutability)
74 }
75 ArrayType(inner) => TypeRef::Array(Box::new(TypeRef::from_ast_opt(inner.type_ref()))),
76 SliceType(inner) => TypeRef::Slice(Box::new(TypeRef::from_ast_opt(inner.type_ref()))),
77 ReferenceType(inner) => {
78 let inner_ty = TypeRef::from_ast_opt(inner.type_ref());
79 let mutability = Mutability::from_mutable(inner.is_mut());
80 TypeRef::Reference(Box::new(inner_ty), mutability)
81 }
82 PlaceholderType(_inner) => TypeRef::Placeholder,
83 FnPointerType(inner) => {
84 let ret_ty = TypeRef::from_ast_opt(inner.ret_type().and_then(|rt| rt.type_ref()));
85 let mut params = if let Some(pl) = inner.param_list() {
86 pl.params()
87 .map(|p| p.type_ref())
88 .map(TypeRef::from_ast_opt)
89 .collect()
90 } else {
91 Vec::new()
92 };
93 params.push(ret_ty);
94 TypeRef::Fn(params)
95 }
96 // for types are close enough for our purposes to the inner type for now...
97 ForType(inner) => TypeRef::from_ast_opt(inner.type_ref()),
98 ImplTraitType(_inner) => TypeRef::Error,
99 DynTraitType(_inner) => TypeRef::Error,
100 }
101 }
102
103 fn from_ast_opt(node: Option<ast::TypeRef>) -> Self {
104 if let Some(node) = node {
105 TypeRef::from_ast(node)
106 } else {
107 TypeRef::Error
108 }
109 }
110}