aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-04-20 11:34:36 +0100
committerFlorian Diebold <[email protected]>2019-05-04 17:18:30 +0100
commitb9c0c2abb79769852119dc9a595e63ee74eeba03 (patch)
tree39bf8f14438771f20337eaf57c421aebe3e7dfdb /crates/ra_hir/src/ty.rs
parent6269791d3626b9a9e5ea6a11c15e14470c0809a0 (diff)
Chalk integration
- add proper canonicalization logic - add conversions from/to Chalk IR
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs49
1 files changed, 48 insertions, 1 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 094de62a3..538148956 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -15,7 +15,7 @@ pub(crate) mod display;
15use std::sync::Arc; 15use std::sync::Arc;
16use std::{fmt, mem}; 16use std::{fmt, mem};
17 17
18use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait}; 18use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait, GenericParams};
19use display::{HirDisplay, HirFormatter}; 19use display::{HirDisplay, HirFormatter};
20 20
21pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig}; 21pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig};
@@ -118,6 +118,7 @@ pub enum Ty {
118 /// surrounding impl, then the current function). 118 /// surrounding impl, then the current function).
119 idx: u32, 119 idx: u32,
120 /// The name of the parameter, for displaying. 120 /// The name of the parameter, for displaying.
121 // FIXME get rid of this
121 name: Name, 122 name: Name,
122 }, 123 },
123 124
@@ -177,6 +178,30 @@ impl Substs {
177 } 178 }
178 &self.0[0] 179 &self.0[0]
179 } 180 }
181
182 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
183 pub fn identity(generic_params: &GenericParams) -> Substs {
184 Substs(
185 generic_params
186 .params_including_parent()
187 .into_iter()
188 .map(|p| Ty::Param { idx: p.idx, name: p.name.clone() })
189 .collect::<Vec<_>>()
190 .into(),
191 )
192 }
193
194 /// Return Substs that replace each parameter by a bound variable.
195 pub fn bound_vars(generic_params: &GenericParams) -> Substs {
196 Substs(
197 generic_params
198 .params_including_parent()
199 .into_iter()
200 .map(|p| Ty::Bound(p.idx))
201 .collect::<Vec<_>>()
202 .into(),
203 )
204 }
180} 205}
181 206
182impl From<Vec<Ty>> for Substs { 207impl From<Vec<Ty>> for Substs {
@@ -198,6 +223,14 @@ impl TraitRef {
198 pub fn self_ty(&self) -> &Ty { 223 pub fn self_ty(&self) -> &Ty {
199 &self.substs.0[0] 224 &self.substs.0[0]
200 } 225 }
226
227 pub fn subst(mut self, substs: &Substs) -> TraitRef {
228 self.substs.walk_mut(&mut |ty_mut| {
229 let ty = mem::replace(ty_mut, Ty::Unknown);
230 *ty_mut = ty.subst(substs);
231 });
232 self
233 }
201} 234}
202 235
203/// A function signature as seen by type inference: Several parameter types and 236/// A function signature as seen by type inference: Several parameter types and
@@ -376,6 +409,20 @@ impl Ty {
376 }) 409 })
377 } 410 }
378 411
412 /// Substitutes `Ty::Bound` vars (as opposed to type parameters).
413 pub fn subst_bound_vars(self, substs: &Substs) -> Ty {
414 self.fold(&mut |ty| match ty {
415 Ty::Bound(idx) => {
416 if (idx as usize) < substs.0.len() {
417 substs.0[idx as usize].clone()
418 } else {
419 Ty::Bound(idx)
420 }
421 }
422 ty => ty,
423 })
424 }
425
379 /// Returns the type parameters of this type if it has some (i.e. is an ADT 426 /// Returns the type parameters of this type if it has some (i.e. is an ADT
380 /// or function); so if `self` is `Option<u32>`, this returns the `u32`. 427 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
381 fn substs(&self) -> Option<Substs> { 428 fn substs(&self) -> Option<Substs> {