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.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index ecf13fbc3..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;
@@ -145,6 +146,10 @@ impl Substs {
145 Substs(Arc::new([ty])) 146 Substs(Arc::new([ty]))
146 } 147 }
147 148
149 pub fn prefix(&self, n: usize) -> Substs {
150 Substs(self.0.iter().cloned().take(n).collect::<Vec<_>>().into())
151 }
152
148 pub fn iter(&self) -> impl Iterator<Item = &Ty> { 153 pub fn iter(&self) -> impl Iterator<Item = &Ty> {
149 self.0.iter() 154 self.0.iter()
150 } 155 }
@@ -170,6 +175,12 @@ impl Substs {
170 } 175 }
171} 176}
172 177
178impl From<Vec<Ty>> for Substs {
179 fn from(v: Vec<Ty>) -> Self {
180 Substs(v.into())
181 }
182}
183
173/// 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.
174/// Name to be bikeshedded: TraitBound? TraitImplements? 185/// Name to be bikeshedded: TraitBound? TraitImplements?
175#[derive(Clone, PartialEq, Eq, Debug, Hash)] 186#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -210,6 +221,14 @@ impl FnSig {
210 &self.params_and_return[self.params_and_return.len() - 1] 221 &self.params_and_return[self.params_and_return.len() - 1]
211 } 222 }
212 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
213 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)) {
214 // 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:
215 let mut v: Vec<_> = self.params_and_return.iter().cloned().collect(); 234 let mut v: Vec<_> = self.params_and_return.iter().cloned().collect();
@@ -309,6 +328,20 @@ impl Ty {
309 } 328 }
310 } 329 }
311 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
312 /// 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
313 /// 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
314 /// `self` is `Option<_>` and the substs contain `u32`, we'll have 347 /// `self` is `Option<_>` and the substs contain `u32`, we'll have