aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/utils.rs')
-rw-r--r--crates/hir_ty/src/utils.rs36
1 files changed, 28 insertions, 8 deletions
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 42d7af146..df0ea4368 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -2,13 +2,14 @@
2//! query, but can't be computed directly from `*Data` (ie, which need a `db`). 2//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use chalk_ir::DebruijnIndex; 5use chalk_ir::{BoundVar, DebruijnIndex};
6use hir_def::{ 6use hir_def::{
7 adt::VariantData, 7 adt::VariantData,
8 db::DefDatabase, 8 db::DefDatabase,
9 generics::{ 9 generics::{
10 GenericParams, TypeParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget, 10 GenericParams, TypeParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
11 }, 11 },
12 intern::Interned,
12 path::Path, 13 path::Path,
13 resolver::{HasResolver, TypeNs}, 14 resolver::{HasResolver, TypeNs},
14 type_ref::TypeRef, 15 type_ref::TypeRef,
@@ -16,7 +17,7 @@ use hir_def::{
16}; 17};
17use hir_expand::name::{name, Name}; 18use hir_expand::name::{name, Name};
18 19
19use crate::{db::HirDatabase, TraitRef, TypeWalk, WhereClause}; 20use crate::{db::HirDatabase, Interner, Substitution, TraitRef, TyKind, TypeWalk, WhereClause};
20 21
21fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { 22fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
22 let resolver = trait_.resolver(db); 23 let resolver = trait_.resolver(db);
@@ -32,11 +33,10 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
32 .filter_map(|pred| match pred { 33 .filter_map(|pred| match pred {
33 WherePredicate::ForLifetime { target, bound, .. } 34 WherePredicate::ForLifetime { target, bound, .. }
34 | WherePredicate::TypeBound { target, bound } => match target { 35 | WherePredicate::TypeBound { target, bound } => match target {
35 WherePredicateTypeTarget::TypeRef(TypeRef::Path(p)) 36 WherePredicateTypeTarget::TypeRef(type_ref) => match &**type_ref {
36 if p == &Path::from(name![Self]) => 37 TypeRef::Path(p) if p == &Path::from(name![Self]) => bound.as_path(),
37 { 38 _ => None,
38 bound.as_path() 39 },
39 }
40 WherePredicateTypeTarget::TypeParam(local_id) if Some(*local_id) == trait_self => { 40 WherePredicateTypeTarget::TypeParam(local_id) if Some(*local_id) == trait_self => {
41 bound.as_path() 41 bound.as_path()
42 } 42 }
@@ -159,7 +159,7 @@ pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
159#[derive(Debug)] 159#[derive(Debug)]
160pub(crate) struct Generics { 160pub(crate) struct Generics {
161 def: GenericDefId, 161 def: GenericDefId,
162 pub(crate) params: Arc<GenericParams>, 162 pub(crate) params: Interned<GenericParams>,
163 parent_generics: Option<Box<Generics>>, 163 parent_generics: Option<Box<Generics>>,
164} 164}
165 165
@@ -249,6 +249,26 @@ impl Generics {
249 self.parent_generics.as_ref().and_then(|g| g.find_param(param)) 249 self.parent_generics.as_ref().and_then(|g| g.find_param(param))
250 } 250 }
251 } 251 }
252
253 /// Returns a Substitution that replaces each parameter by a bound variable.
254 pub(crate) fn bound_vars_subst(&self, debruijn: DebruijnIndex) -> Substitution {
255 Substitution::from_iter(
256 &Interner,
257 self.iter()
258 .enumerate()
259 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
260 )
261 }
262
263 /// Returns a Substitution that replaces each parameter by itself (i.e. `Ty::Param`).
264 pub(crate) fn type_params_subst(&self, db: &dyn HirDatabase) -> Substitution {
265 Substitution::from_iter(
266 &Interner,
267 self.iter().map(|(id, _)| {
268 TyKind::Placeholder(crate::to_placeholder_idx(db, id)).intern(&Interner)
269 }),
270 )
271 }
252} 272}
253 273
254fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<GenericDefId> { 274fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<GenericDefId> {