diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 20e55d92d..12e10c751 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -5,6 +5,7 @@ mod autoderef; | |||
5 | pub(crate) mod primitive; | 5 | pub(crate) mod primitive; |
6 | #[cfg(test)] | 6 | #[cfg(test)] |
7 | mod tests; | 7 | mod tests; |
8 | pub(crate) mod traits; | ||
8 | pub(crate) mod method_resolution; | 9 | pub(crate) mod method_resolution; |
9 | mod op; | 10 | mod op; |
10 | mod lower; | 11 | mod lower; |
@@ -15,10 +16,11 @@ use std::sync::Arc; | |||
15 | use std::{fmt, mem}; | 16 | use std::{fmt, mem}; |
16 | 17 | ||
17 | use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait}; | 18 | use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait}; |
19 | use display::{HirDisplay, HirFormatter}; | ||
18 | 20 | ||
19 | pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field, callable_item_sig}; | 21 | pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig}; |
20 | pub(crate) use infer::{infer, InferenceResult, InferTy}; | 22 | pub(crate) use infer::{infer, InferenceResult, InferTy}; |
21 | use display::{HirDisplay, HirFormatter}; | 23 | pub use lower::CallableDef; |
22 | 24 | ||
23 | /// A type constructor or type name: this might be something like the primitive | 25 | /// A type constructor or type name: this might be something like the primitive |
24 | /// type `bool`, a struct like `Vec`, or things like function pointers or | 26 | /// type `bool`, a struct like `Vec`, or things like function pointers or |
@@ -144,6 +146,10 @@ impl Substs { | |||
144 | Substs(Arc::new([ty])) | 146 | Substs(Arc::new([ty])) |
145 | } | 147 | } |
146 | 148 | ||
149 | pub fn prefix(&self, n: usize) -> Substs { | ||
150 | Substs(self.0.iter().cloned().take(n).collect::<Vec<_>>().into()) | ||
151 | } | ||
152 | |||
147 | pub fn iter(&self) -> impl Iterator<Item = &Ty> { | 153 | pub fn iter(&self) -> impl Iterator<Item = &Ty> { |
148 | self.0.iter() | 154 | self.0.iter() |
149 | } | 155 | } |
@@ -169,6 +175,12 @@ impl Substs { | |||
169 | } | 175 | } |
170 | } | 176 | } |
171 | 177 | ||
178 | impl From<Vec<Ty>> for Substs { | ||
179 | fn from(v: Vec<Ty>) -> Self { | ||
180 | Substs(v.into()) | ||
181 | } | ||
182 | } | ||
183 | |||
172 | /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. | 184 | /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. |
173 | /// Name to be bikeshedded: TraitBound? TraitImplements? | 185 | /// Name to be bikeshedded: TraitBound? TraitImplements? |
174 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 186 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
@@ -209,6 +221,14 @@ impl FnSig { | |||
209 | &self.params_and_return[self.params_and_return.len() - 1] | 221 | &self.params_and_return[self.params_and_return.len() - 1] |
210 | } | 222 | } |
211 | 223 | ||
224 | /// Applies the given substitutions to all types in this signature and | ||
225 | /// returns the result. | ||
226 | pub fn subst(&self, substs: &Substs) -> FnSig { | ||
227 | let result: Vec<_> = | ||
228 | self.params_and_return.iter().map(|ty| ty.clone().subst(substs)).collect(); | ||
229 | FnSig { params_and_return: result.into() } | ||
230 | } | ||
231 | |||
212 | pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | 232 | pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { |
213 | // Without an Arc::make_mut_slice, we can't avoid the clone here: | 233 | // Without an Arc::make_mut_slice, we can't avoid the clone here: |
214 | let mut v: Vec<_> = self.params_and_return.iter().cloned().collect(); | 234 | let mut v: Vec<_> = self.params_and_return.iter().cloned().collect(); |
@@ -288,6 +308,15 @@ impl Ty { | |||
288 | } | 308 | } |
289 | } | 309 | } |
290 | 310 | ||
311 | pub fn as_callable(&self) -> Option<(CallableDef, &Substs)> { | ||
312 | match self { | ||
313 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(callable_def), parameters }) => { | ||
314 | Some((*callable_def, parameters)) | ||
315 | } | ||
316 | _ => None, | ||
317 | } | ||
318 | } | ||
319 | |||
291 | fn builtin_deref(&self) -> Option<Ty> { | 320 | fn builtin_deref(&self) -> Option<Ty> { |
292 | match self { | 321 | match self { |
293 | Ty::Apply(a_ty) => match a_ty.ctor { | 322 | Ty::Apply(a_ty) => match a_ty.ctor { |
@@ -299,6 +328,20 @@ impl Ty { | |||
299 | } | 328 | } |
300 | } | 329 | } |
301 | 330 | ||
331 | fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> { | ||
332 | match self { | ||
333 | Ty::Apply(a_ty) => match a_ty.ctor { | ||
334 | TypeCtor::FnPtr => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)), | ||
335 | TypeCtor::FnDef(def) => { | ||
336 | let sig = db.callable_item_signature(def); | ||
337 | Some(sig.subst(&a_ty.parameters)) | ||
338 | } | ||
339 | _ => None, | ||
340 | }, | ||
341 | _ => None, | ||
342 | } | ||
343 | } | ||
344 | |||
302 | /// If this is a type with type parameters (an ADT or function), replaces | 345 | /// If this is a type with type parameters (an ADT or function), replaces |
303 | /// the `Substs` for these type parameters with the given ones. (So e.g. if | 346 | /// the `Substs` for these type parameters with the given ones. (So e.g. if |
304 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have | 347 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have |