aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs238
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
20pub(crate) use infer::{infer, InferenceResult, InferTy}; 20pub(crate) use infer::{infer, InferenceResult, InferTy};
21use display::{HirDisplay, HirFormatter}; 21use display::{HirDisplay, HirFormatter};
22 22
23#[derive(Copy, Clone, PartialEq, Eq, Debug)] 23#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
24pub enum TypeName { 24pub 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)]
98pub enum Ty { 98pub 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
258impl Ty { 193impl 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, "_")?,