diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 238 |
1 files changed, 41 insertions, 197 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index e63775f03..0bb716569 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -20,7 +20,7 @@ pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field, ca | |||
20 | pub(crate) use infer::{infer, InferenceResult, InferTy}; | 20 | pub(crate) use infer::{infer, InferenceResult, InferTy}; |
21 | use display::{HirDisplay, HirFormatter}; | 21 | use display::{HirDisplay, HirFormatter}; |
22 | 22 | ||
23 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] | 23 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
24 | pub enum TypeName { | 24 | pub enum TypeName { |
25 | /// The primitive boolean type. Written as `bool`. | 25 | /// The primitive boolean type. Written as `bool`. |
26 | Bool, | 26 | Bool, |
@@ -96,80 +96,11 @@ pub struct ApplicationTy { | |||
96 | /// This should be cheap to clone. | 96 | /// This should be cheap to clone. |
97 | #[derive(Clone, PartialEq, Eq, Debug)] | 97 | #[derive(Clone, PartialEq, Eq, Debug)] |
98 | pub enum Ty { | 98 | pub enum Ty { |
99 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | ||
100 | /// type like `bool`, a struct, tuple, function pointer, reference or | ||
101 | /// several other things. | ||
99 | Apply(ApplicationTy), | 102 | Apply(ApplicationTy), |
100 | 103 | ||
101 | /// The primitive boolean type. Written as `bool`. | ||
102 | Bool, | ||
103 | |||
104 | /// The primitive character type; holds a Unicode scalar value | ||
105 | /// (a non-surrogate code point). Written as `char`. | ||
106 | Char, | ||
107 | |||
108 | /// A primitive integer type. For example, `i32`. | ||
109 | Int(primitive::UncertainIntTy), | ||
110 | |||
111 | /// A primitive floating-point type. For example, `f64`. | ||
112 | Float(primitive::UncertainFloatTy), | ||
113 | |||
114 | /// Structures, enumerations and unions. | ||
115 | Adt { | ||
116 | /// The definition of the struct/enum. | ||
117 | def_id: AdtDef, | ||
118 | /// Substitutions for the generic parameters of the type. | ||
119 | substs: Substs, | ||
120 | }, | ||
121 | |||
122 | /// The pointee of a string slice. Written as `str`. | ||
123 | Str, | ||
124 | |||
125 | /// The pointee of an array slice. Written as `[T]`. | ||
126 | Slice(Arc<Ty>), | ||
127 | |||
128 | /// An array with the given length. Written as `[T; n]`. | ||
129 | Array(Arc<Ty>), | ||
130 | |||
131 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
132 | RawPtr(Arc<Ty>, Mutability), | ||
133 | |||
134 | /// A reference; a pointer with an associated lifetime. Written as | ||
135 | /// `&'a mut T` or `&'a T`. | ||
136 | Ref(Arc<Ty>, Mutability), | ||
137 | |||
138 | /// The anonymous type of a function declaration/definition. Each | ||
139 | /// function has a unique type, which is output (for a function | ||
140 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
141 | /// | ||
142 | /// This includes tuple struct / enum variant constructors as well. | ||
143 | /// | ||
144 | /// For example the type of `bar` here: | ||
145 | /// | ||
146 | /// ```rust | ||
147 | /// fn foo() -> i32 { 1 } | ||
148 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
149 | /// ``` | ||
150 | FnDef { | ||
151 | /// The definition of the function / constructor. | ||
152 | def: CallableDef, | ||
153 | /// Substitutions for the generic parameters of the type | ||
154 | substs: Substs, | ||
155 | }, | ||
156 | |||
157 | /// A pointer to a function. Written as `fn() -> i32`. | ||
158 | /// | ||
159 | /// For example the type of `bar` here: | ||
160 | /// | ||
161 | /// ```rust | ||
162 | /// fn foo() -> i32 { 1 } | ||
163 | /// let bar: fn() -> i32 = foo; | ||
164 | /// ``` | ||
165 | FnPtr(Substs), | ||
166 | |||
167 | /// The never type `!`. | ||
168 | Never, | ||
169 | |||
170 | /// A tuple type. For example, `(i32, bool)`. | ||
171 | Tuple(Substs), | ||
172 | |||
173 | /// A type parameter; for example, `T` in `fn f<T>(x: T) {} | 104 | /// A type parameter; for example, `T` in `fn f<T>(x: T) {} |
174 | Param { | 105 | Param { |
175 | /// The index of the parameter (starting with parameters from the | 106 | /// The index of the parameter (starting with parameters from the |
@@ -200,6 +131,10 @@ impl Substs { | |||
200 | Substs(Arc::new([])) | 131 | Substs(Arc::new([])) |
201 | } | 132 | } |
202 | 133 | ||
134 | pub fn single(ty: Ty) -> Substs { | ||
135 | Substs(Arc::new([ty])) | ||
136 | } | ||
137 | |||
203 | pub fn iter(&self) -> impl Iterator<Item = &Ty> { | 138 | pub fn iter(&self) -> impl Iterator<Item = &Ty> { |
204 | self.0.iter() | 139 | self.0.iter() |
205 | } | 140 | } |
@@ -256,6 +191,12 @@ impl FnSig { | |||
256 | } | 191 | } |
257 | 192 | ||
258 | impl Ty { | 193 | impl Ty { |
194 | pub fn simple(name: TypeName) -> Ty { | ||
195 | Ty::Apply(ApplicationTy { name, parameters: Substs::empty() }) | ||
196 | } | ||
197 | pub fn apply_one(name: TypeName, param: Ty) -> Ty { | ||
198 | Ty::Apply(ApplicationTy { name, parameters: Substs::single(param) }) | ||
199 | } | ||
259 | pub fn apply(name: TypeName, parameters: Substs) -> Ty { | 200 | pub fn apply(name: TypeName, parameters: Substs) -> Ty { |
260 | Ty::Apply(ApplicationTy { name, parameters }) | 201 | Ty::Apply(ApplicationTy { name, parameters }) |
261 | } | 202 | } |
@@ -270,38 +211,7 @@ impl Ty { | |||
270 | t.walk(f); | 211 | t.walk(f); |
271 | } | 212 | } |
272 | } | 213 | } |
273 | Ty::Slice(t) | Ty::Array(t) => t.walk(f), | 214 | Ty::Param { .. } | Ty::Infer(_) | Ty::Unknown => {} |
274 | Ty::RawPtr(t, _) => t.walk(f), | ||
275 | Ty::Ref(t, _) => t.walk(f), | ||
276 | Ty::Tuple(ts) => { | ||
277 | for t in ts.iter() { | ||
278 | t.walk(f); | ||
279 | } | ||
280 | } | ||
281 | Ty::FnPtr(sig) => { | ||
282 | for t in sig.iter() { | ||
283 | t.walk(f); | ||
284 | } | ||
285 | } | ||
286 | Ty::FnDef { substs, .. } => { | ||
287 | for t in substs.0.iter() { | ||
288 | t.walk(f); | ||
289 | } | ||
290 | } | ||
291 | Ty::Adt { substs, .. } => { | ||
292 | for t in substs.0.iter() { | ||
293 | t.walk(f); | ||
294 | } | ||
295 | } | ||
296 | Ty::Bool | ||
297 | | Ty::Char | ||
298 | | Ty::Int(_) | ||
299 | | Ty::Float(_) | ||
300 | | Ty::Str | ||
301 | | Ty::Never | ||
302 | | Ty::Param { .. } | ||
303 | | Ty::Infer(_) | ||
304 | | Ty::Unknown => {} | ||
305 | } | 215 | } |
306 | f(self); | 216 | f(self); |
307 | } | 217 | } |
@@ -311,30 +221,7 @@ impl Ty { | |||
311 | Ty::Apply(a_ty) => { | 221 | Ty::Apply(a_ty) => { |
312 | a_ty.parameters.walk_mut(f); | 222 | a_ty.parameters.walk_mut(f); |
313 | } | 223 | } |
314 | Ty::Slice(t) | Ty::Array(t) => Arc::make_mut(t).walk_mut(f), | 224 | Ty::Param { .. } | Ty::Infer(_) | Ty::Unknown => {} |
315 | Ty::RawPtr(t, _) => Arc::make_mut(t).walk_mut(f), | ||
316 | Ty::Ref(t, _) => Arc::make_mut(t).walk_mut(f), | ||
317 | Ty::Tuple(ts) => { | ||
318 | ts.walk_mut(f); | ||
319 | } | ||
320 | Ty::FnPtr(sig) => { | ||
321 | sig.walk_mut(f); | ||
322 | } | ||
323 | Ty::FnDef { substs, .. } => { | ||
324 | substs.walk_mut(f); | ||
325 | } | ||
326 | Ty::Adt { substs, .. } => { | ||
327 | substs.walk_mut(f); | ||
328 | } | ||
329 | Ty::Bool | ||
330 | | Ty::Char | ||
331 | | Ty::Int(_) | ||
332 | | Ty::Float(_) | ||
333 | | Ty::Str | ||
334 | | Ty::Never | ||
335 | | Ty::Param { .. } | ||
336 | | Ty::Infer(_) | ||
337 | | Ty::Unknown => {} | ||
338 | } | 225 | } |
339 | f(self); | 226 | f(self); |
340 | } | 227 | } |
@@ -347,6 +234,31 @@ impl Ty { | |||
347 | self | 234 | self |
348 | } | 235 | } |
349 | 236 | ||
237 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | ||
238 | match self { | ||
239 | Ty::Apply(ApplicationTy { name: TypeName::Ref(mutability), parameters }) => { | ||
240 | Some((parameters.as_single(), *mutability)) | ||
241 | } | ||
242 | _ => None, | ||
243 | } | ||
244 | } | ||
245 | |||
246 | pub fn as_adt(&self) -> Option<(AdtDef, &Substs)> { | ||
247 | match self { | ||
248 | Ty::Apply(ApplicationTy { name: TypeName::Adt(adt_def), parameters }) => { | ||
249 | Some((*adt_def, parameters)) | ||
250 | } | ||
251 | _ => None, | ||
252 | } | ||
253 | } | ||
254 | |||
255 | pub fn as_tuple(&self) -> Option<&Substs> { | ||
256 | match self { | ||
257 | Ty::Apply(ApplicationTy { name: TypeName::Tuple, parameters }) => Some(parameters), | ||
258 | _ => None, | ||
259 | } | ||
260 | } | ||
261 | |||
350 | fn builtin_deref(&self) -> Option<Ty> { | 262 | fn builtin_deref(&self) -> Option<Ty> { |
351 | match self { | 263 | match self { |
352 | Ty::Apply(a_ty) => match a_ty.name { | 264 | Ty::Apply(a_ty) => match a_ty.name { |
@@ -354,8 +266,6 @@ impl Ty { | |||
354 | TypeName::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())), | 266 | TypeName::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())), |
355 | _ => None, | 267 | _ => None, |
356 | }, | 268 | }, |
357 | Ty::Ref(t, _) => Some(Ty::clone(t)), | ||
358 | Ty::RawPtr(t, _) => Some(Ty::clone(t)), | ||
359 | _ => None, | 269 | _ => None, |
360 | } | 270 | } |
361 | } | 271 | } |
@@ -369,8 +279,6 @@ impl Ty { | |||
369 | Ty::Apply(ApplicationTy { name, .. }) => { | 279 | Ty::Apply(ApplicationTy { name, .. }) => { |
370 | Ty::Apply(ApplicationTy { name, parameters: substs }) | 280 | Ty::Apply(ApplicationTy { name, parameters: substs }) |
371 | } | 281 | } |
372 | Ty::Adt { def_id, .. } => Ty::Adt { def_id, substs }, | ||
373 | Ty::FnDef { def, .. } => Ty::FnDef { def, substs }, | ||
374 | _ => self, | 282 | _ => self, |
375 | } | 283 | } |
376 | } | 284 | } |
@@ -396,7 +304,6 @@ impl Ty { | |||
396 | fn substs(&self) -> Option<Substs> { | 304 | fn substs(&self) -> Option<Substs> { |
397 | match self { | 305 | match self { |
398 | Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), | 306 | Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), |
399 | Ty::Adt { substs, .. } | Ty::FnDef { substs, .. } => Some(substs.clone()), | ||
400 | _ => None, | 307 | _ => None, |
401 | } | 308 | } |
402 | } | 309 | } |
@@ -487,69 +394,6 @@ impl HirDisplay for Ty { | |||
487 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | 394 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { |
488 | match self { | 395 | match self { |
489 | Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, | 396 | Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, |
490 | Ty::Bool => write!(f, "bool")?, | ||
491 | Ty::Char => write!(f, "char")?, | ||
492 | Ty::Int(t) => write!(f, "{}", t)?, | ||
493 | Ty::Float(t) => write!(f, "{}", t)?, | ||
494 | Ty::Str => write!(f, "str")?, | ||
495 | Ty::Slice(t) | Ty::Array(t) => { | ||
496 | write!(f, "[{}]", t.display(f.db))?; | ||
497 | } | ||
498 | Ty::RawPtr(t, m) => { | ||
499 | write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?; | ||
500 | } | ||
501 | Ty::Ref(t, m) => { | ||
502 | write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?; | ||
503 | } | ||
504 | Ty::Never => write!(f, "!")?, | ||
505 | Ty::Tuple(ts) => { | ||
506 | if ts.0.len() == 1 { | ||
507 | write!(f, "({},)", ts.0[0].display(f.db))?; | ||
508 | } else { | ||
509 | write!(f, "(")?; | ||
510 | f.write_joined(&*ts.0, ", ")?; | ||
511 | write!(f, ")")?; | ||
512 | } | ||
513 | } | ||
514 | Ty::FnPtr(sig) => { | ||
515 | let sig = FnSig::from_fn_ptr_substs(sig); | ||
516 | write!(f, "fn(")?; | ||
517 | f.write_joined(sig.params(), ", ")?; | ||
518 | write!(f, ") -> {}", sig.ret().display(f.db))?; | ||
519 | } | ||
520 | Ty::FnDef { def, substs, .. } => { | ||
521 | let sig = f.db.callable_item_signature(*def); | ||
522 | let name = match def { | ||
523 | CallableDef::Function(ff) => ff.name(f.db), | ||
524 | CallableDef::Struct(s) => s.name(f.db).unwrap_or_else(Name::missing), | ||
525 | CallableDef::EnumVariant(e) => e.name(f.db).unwrap_or_else(Name::missing), | ||
526 | }; | ||
527 | match def { | ||
528 | CallableDef::Function(_) => write!(f, "fn {}", name)?, | ||
529 | CallableDef::Struct(_) | CallableDef::EnumVariant(_) => write!(f, "{}", name)?, | ||
530 | } | ||
531 | if substs.0.len() > 0 { | ||
532 | write!(f, "<")?; | ||
533 | f.write_joined(&*substs.0, ", ")?; | ||
534 | write!(f, ">")?; | ||
535 | } | ||
536 | write!(f, "(")?; | ||
537 | f.write_joined(sig.params(), ", ")?; | ||
538 | write!(f, ") -> {}", sig.ret().display(f.db))?; | ||
539 | } | ||
540 | Ty::Adt { def_id, substs, .. } => { | ||
541 | let name = match def_id { | ||
542 | AdtDef::Struct(s) => s.name(f.db), | ||
543 | AdtDef::Enum(e) => e.name(f.db), | ||
544 | } | ||
545 | .unwrap_or_else(Name::missing); | ||
546 | write!(f, "{}", name)?; | ||
547 | if substs.0.len() > 0 { | ||
548 | write!(f, "<")?; | ||
549 | f.write_joined(&*substs.0, ", ")?; | ||
550 | write!(f, ">")?; | ||
551 | } | ||
552 | } | ||
553 | Ty::Param { name, .. } => write!(f, "{}", name)?, | 397 | Ty::Param { name, .. } => write!(f, "{}", name)?, |
554 | Ty::Unknown => write!(f, "{{unknown}}")?, | 398 | Ty::Unknown => write!(f, "{{unknown}}")?, |
555 | Ty::Infer(..) => write!(f, "_")?, | 399 | Ty::Infer(..) => write!(f, "_")?, |