aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/type_ref.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/type_ref.rs')
-rw-r--r--crates/hir_def/src/type_ref.rs50
1 files changed, 39 insertions, 11 deletions
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs
index 1a78c1444..347ceabb9 100644
--- a/crates/hir_def/src/type_ref.rs
+++ b/crates/hir_def/src/type_ref.rs
@@ -1,6 +1,7 @@
1//! HIR for references to types. Paths in these are not yet resolved. They can 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. 2//! be directly created from an ast::TypeRef, without further queries.
3use syntax::ast::{self}; 3use hir_expand::name::Name;
4use syntax::{ast, SyntaxToken};
4 5
5use crate::{body::LowerCtx, path::Path}; 6use crate::{body::LowerCtx, path::Path};
6 7
@@ -58,7 +59,7 @@ pub enum TypeRef {
58 Tuple(Vec<TypeRef>), 59 Tuple(Vec<TypeRef>),
59 Path(Path), 60 Path(Path),
60 RawPtr(Box<TypeRef>, Mutability), 61 RawPtr(Box<TypeRef>, Mutability),
61 Reference(Box<TypeRef>, Mutability), 62 Reference(Box<TypeRef>, Option<LifetimeRef>, Mutability),
62 Array(Box<TypeRef> /*, Expr*/), 63 Array(Box<TypeRef> /*, Expr*/),
63 Slice(Box<TypeRef>), 64 Slice(Box<TypeRef>),
64 /// A fn pointer. Last element of the vector is the return type. 65 /// A fn pointer. Last element of the vector is the return type.
@@ -70,10 +71,29 @@ pub enum TypeRef {
70} 71}
71 72
72#[derive(Clone, PartialEq, Eq, Hash, Debug)] 73#[derive(Clone, PartialEq, Eq, Hash, Debug)]
74pub struct LifetimeRef {
75 pub name: Name,
76}
77
78impl LifetimeRef {
79 pub(crate) fn new_name(name: Name) -> Self {
80 LifetimeRef { name }
81 }
82
83 pub(crate) fn from_token(token: SyntaxToken) -> Self {
84 LifetimeRef { name: Name::new_lifetime(&token) }
85 }
86
87 pub fn missing() -> LifetimeRef {
88 LifetimeRef { name: Name::missing() }
89 }
90}
91
92#[derive(Clone, PartialEq, Eq, Hash, Debug)]
73pub enum TypeBound { 93pub enum TypeBound {
74 Path(Path), 94 Path(Path),
75 // also for<> bounds 95 // ForLifetime(Vec<LifetimeRef>, Path), FIXME ForLifetime
76 // also Lifetimes 96 Lifetime(LifetimeRef),
77 Error, 97 Error,
78} 98}
79 99
@@ -107,8 +127,9 @@ impl TypeRef {
107 } 127 }
108 ast::Type::RefType(inner) => { 128 ast::Type::RefType(inner) => {
109 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty()); 129 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty());
130 let lifetime = inner.lifetime_token().map(|t| LifetimeRef::from_token(t));
110 let mutability = Mutability::from_mutable(inner.mut_token().is_some()); 131 let mutability = Mutability::from_mutable(inner.mut_token().is_some());
111 TypeRef::Reference(Box::new(inner_ty), mutability) 132 TypeRef::Reference(Box::new(inner_ty), lifetime, mutability)
112 } 133 }
113 ast::Type::InferType(_inner) => TypeRef::Placeholder, 134 ast::Type::InferType(_inner) => TypeRef::Placeholder,
114 ast::Type::FnPtrType(inner) => { 135 ast::Type::FnPtrType(inner) => {
@@ -163,14 +184,14 @@ impl TypeRef {
163 types.iter().for_each(|t| go(t, f)) 184 types.iter().for_each(|t| go(t, f))
164 } 185 }
165 TypeRef::RawPtr(type_ref, _) 186 TypeRef::RawPtr(type_ref, _)
166 | TypeRef::Reference(type_ref, _) 187 | TypeRef::Reference(type_ref, ..)
167 | TypeRef::Array(type_ref) 188 | TypeRef::Array(type_ref)
168 | TypeRef::Slice(type_ref) => go(&type_ref, f), 189 | TypeRef::Slice(type_ref) => go(&type_ref, f),
169 TypeRef::ImplTrait(bounds) | TypeRef::DynTrait(bounds) => { 190 TypeRef::ImplTrait(bounds) | TypeRef::DynTrait(bounds) => {
170 for bound in bounds { 191 for bound in bounds {
171 match bound { 192 match bound {
172 TypeBound::Path(path) => go_path(path, f), 193 TypeBound::Path(path) => go_path(path, f),
173 TypeBound::Error => (), 194 TypeBound::Lifetime(_) | TypeBound::Error => (),
174 } 195 }
175 } 196 }
176 } 197 }
@@ -186,8 +207,12 @@ impl TypeRef {
186 for segment in path.segments().iter() { 207 for segment in path.segments().iter() {
187 if let Some(args_and_bindings) = segment.args_and_bindings { 208 if let Some(args_and_bindings) = segment.args_and_bindings {
188 for arg in &args_and_bindings.args { 209 for arg in &args_and_bindings.args {
189 let crate::path::GenericArg::Type(type_ref) = arg; 210 match arg {
190 go(type_ref, f); 211 crate::path::GenericArg::Type(type_ref) => {
212 go(type_ref, f);
213 }
214 crate::path::GenericArg::Lifetime(_) => {}
215 }
191 } 216 }
192 for binding in &args_and_bindings.bindings { 217 for binding in &args_and_bindings.bindings {
193 if let Some(type_ref) = &binding.type_ref { 218 if let Some(type_ref) = &binding.type_ref {
@@ -196,7 +221,7 @@ impl TypeRef {
196 for bound in &binding.bounds { 221 for bound in &binding.bounds {
197 match bound { 222 match bound {
198 TypeBound::Path(path) => go_path(path, f), 223 TypeBound::Path(path) => go_path(path, f),
199 TypeBound::Error => (), 224 TypeBound::Lifetime(_) | TypeBound::Error => (),
200 } 225 }
201 } 226 }
202 } 227 }
@@ -232,7 +257,10 @@ impl TypeBound {
232 }; 257 };
233 TypeBound::Path(path) 258 TypeBound::Path(path)
234 } 259 }
235 ast::TypeBoundKind::ForType(_) | ast::TypeBoundKind::Lifetime(_) => TypeBound::Error, 260 ast::TypeBoundKind::ForType(_) => TypeBound::Error, // FIXME ForType
261 ast::TypeBoundKind::Lifetime(lifetime) => {
262 TypeBound::Lifetime(LifetimeRef::from_token(lifetime))
263 }
236 } 264 }
237 } 265 }
238 266