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.rs47
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;
5pub(crate) mod primitive; 5pub(crate) mod primitive;
6#[cfg(test)] 6#[cfg(test)]
7mod tests; 7mod tests;
8pub(crate) mod traits;
8pub(crate) mod method_resolution; 9pub(crate) mod method_resolution;
9mod op; 10mod op;
10mod lower; 11mod lower;
@@ -15,10 +16,11 @@ use std::sync::Arc;
15use std::{fmt, mem}; 16use std::{fmt, mem};
16 17
17use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait}; 18use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait};
19use display::{HirDisplay, HirFormatter};
18 20
19pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field, callable_item_sig}; 21pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig};
20pub(crate) use infer::{infer, InferenceResult, InferTy}; 22pub(crate) use infer::{infer, InferenceResult, InferTy};
21use display::{HirDisplay, HirFormatter}; 23pub 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
178impl 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