Use chalk_ir::PlaceholderIndex

This commit is contained in:
Florian Diebold 2021-03-13 19:47:34 +01:00
parent 2d69eb131f
commit 1bf6b7360c
8 changed files with 53 additions and 44 deletions

View File

@ -1384,7 +1384,7 @@ impl TypeParam {
pub fn ty(self, db: &dyn HirDatabase) -> Type {
let resolver = self.id.parent.resolver(db.upcast());
let krate = self.id.parent.module(db.upcast()).krate();
let ty = TyKind::Placeholder(self.id).intern(&Interner);
let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx(db, self.id)).intern(&Interner);
Type::new_with_resolver_inner(db, krate, &resolver, ty)
}

View File

@ -81,7 +81,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
#[salsa::interned]
fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId;
#[salsa::interned]
fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId;
fn intern_type_param_id(&self, param_id: TypeParamId) -> InternedTypeParamId;
#[salsa::interned]
fn intern_impl_trait_id(&self, id: OpaqueTyId) -> InternedOpaqueTyId;
#[salsa::interned]
@ -149,8 +149,8 @@ fn hir_database_is_object_safe() {
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct GlobalTypeParamId(salsa::InternId);
impl_intern_key!(GlobalTypeParamId);
pub struct InternedTypeParamId(salsa::InternId);
impl_intern_key!(InternedTypeParamId);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct InternedOpaqueTyId(salsa::InternId);

View File

@ -11,10 +11,10 @@ use hir_def::{
use hir_expand::name::Name;
use crate::{
db::HirDatabase, from_assoc_type_id, from_foreign_def_id, primitive, to_assoc_type_id,
traits::chalk::from_chalk, utils::generics, AdtId, AliasTy, CallableDefId, CallableSig,
GenericPredicate, Interner, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar,
Substs, TraitRef, Ty, TyKind,
db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasTy, CallableDefId,
CallableSig, GenericPredicate, Interner, Lifetime, Obligation, OpaqueTy, OpaqueTyId,
ProjectionTy, Scalar, Substs, TraitRef, Ty, TyKind,
};
pub struct HirFormatter<'a> {
@ -541,7 +541,8 @@ impl HirDisplay for Ty {
write!(f, "{{closure}}")?;
}
}
TyKind::Placeholder(id) => {
TyKind::Placeholder(idx) => {
let id = from_placeholder_idx(f.db, *idx);
let generics = generics(f.db.upcast(), id.parent);
let param_data = &generics.params.types[id.local_id];
match param_data.provenance {
@ -549,8 +550,8 @@ impl HirDisplay for Ty {
write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
}
TypeParamProvenance::ArgumentImplTrait => {
let bounds = f.db.generic_predicates_for_param(*id);
let substs = Substs::type_params_for_generics(&generics);
let bounds = f.db.generic_predicates_for_param(id);
let substs = Substs::type_params_for_generics(f.db, &generics);
write_bounds_like_dyn_trait_with_prefix(
"impl",
&bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(),

View File

@ -454,7 +454,7 @@ impl<'a> InferenceContext<'a> {
}
TypeNs::SelfType(impl_id) => {
let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
let substs = Substs::type_params_for_generics(&generics);
let substs = Substs::type_params_for_generics(self.db, &generics);
let ty = self.db.impl_self_ty(impl_id).subst(&substs);
match unresolved {
None => {

View File

@ -79,7 +79,7 @@ impl<'a> InferenceContext<'a> {
}
ValueNs::ImplSelf(impl_id) => {
let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
let substs = Substs::type_params_for_generics(&generics);
let substs = Substs::type_params_for_generics(self.db, &generics);
let ty = self.db.impl_self_ty(impl_id).subst(&substs);
if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
let ty = self.db.value_ty(struct_id.into()).subst(&substs);

View File

@ -54,6 +54,7 @@ pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
pub type FnDefId = chalk_ir::FnDefId<Interner>;
pub type ClosureId = chalk_ir::ClosureId<Interner>;
pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub enum Lifetime {
@ -220,7 +221,7 @@ pub enum TyKind {
/// {}` when we're type-checking the body of that function. In this
/// situation, we know this stands for *some* type, but don't know the exact
/// type.
Placeholder(TypeParamId),
Placeholder(PlaceholderIndex),
/// A bound type variable. This is used in various places: when representing
/// some polymorphic type like the type of function `fn f<T>`, the type
@ -310,11 +311,14 @@ impl Substs {
}
/// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
pub(crate) fn type_params_for_generics(generic_params: &Generics) -> Substs {
pub(crate) fn type_params_for_generics(
db: &dyn HirDatabase,
generic_params: &Generics,
) -> Substs {
Substs(
generic_params
.iter()
.map(|(id, _)| TyKind::Placeholder(id).intern(&Interner))
.map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner))
.collect(),
)
}
@ -322,7 +326,7 @@ impl Substs {
/// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substs {
let params = generics(db.upcast(), def.into());
Substs::type_params_for_generics(&params)
Substs::type_params_for_generics(db, &params)
}
/// Return Substs that replace each parameter by a bound variable.
@ -909,13 +913,14 @@ impl Ty {
predicates.map(|it| it.value)
}
TyKind::Placeholder(id) => {
TyKind::Placeholder(idx) => {
let id = from_placeholder_idx(db, *idx);
let generic_params = db.generic_params(id.parent);
let param_data = &generic_params.types[id.local_id];
match param_data.provenance {
hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
let predicates = db
.generic_predicates_for_param(*id)
.generic_predicates_for_param(id)
.into_iter()
.map(|pred| pred.value.clone())
.collect_vec();
@ -1148,3 +1153,17 @@ pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId {
pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId {
salsa::InternKey::from_intern_id(id.0)
}
pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId {
assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
db.lookup_intern_type_param_id(interned_id)
}
pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex {
let interned_id = db.intern_type_param_id(id);
PlaceholderIndex {
ui: chalk_ir::UniverseIndex::ROOT,
idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(),
}
}

View File

@ -27,7 +27,7 @@ use stdx::impl_from;
use crate::{
db::HirDatabase,
to_assoc_type_id,
to_assoc_type_id, to_placeholder_idx,
traits::chalk::{Interner, ToChalk},
utils::{
all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
@ -249,7 +249,9 @@ impl Ty {
data.provenance == TypeParamProvenance::ArgumentImplTrait
})
.nth(idx as usize)
.map_or(TyKind::Unknown, |(id, _)| TyKind::Placeholder(id));
.map_or(TyKind::Unknown, |(id, _)| {
TyKind::Placeholder(to_placeholder_idx(ctx.db, id))
});
param.intern(&Interner)
} else {
TyKind::Unknown.intern(&Interner)
@ -384,7 +386,9 @@ impl Ty {
ctx.resolver.generic_def().expect("generics in scope"),
);
match ctx.type_param_mode {
TypeParamLoweringMode::Placeholder => TyKind::Placeholder(param_id),
TypeParamLoweringMode::Placeholder => {
TyKind::Placeholder(to_placeholder_idx(ctx.db, param_id))
}
TypeParamLoweringMode::Variable => {
let idx = generics.param_idx(param_id).expect("matching generics");
TyKind::BoundVar(BoundVar::new(ctx.in_binders, idx))
@ -396,7 +400,7 @@ impl Ty {
let generics = generics(ctx.db.upcast(), impl_id.into());
let substs = match ctx.type_param_mode {
TypeParamLoweringMode::Placeholder => {
Substs::type_params_for_generics(&generics)
Substs::type_params_for_generics(ctx.db, &generics)
}
TypeParamLoweringMode::Variable => {
Substs::bound_vars(&generics, ctx.in_binders)
@ -408,7 +412,7 @@ impl Ty {
let generics = generics(ctx.db.upcast(), adt.into());
let substs = match ctx.type_param_mode {
TypeParamLoweringMode::Placeholder => {
Substs::type_params_for_generics(&generics)
Substs::type_params_for_generics(ctx.db, &generics)
}
TypeParamLoweringMode::Variable => {
Substs::bound_vars(&generics, ctx.in_binders)
@ -689,8 +693,9 @@ impl GenericPredicate {
let generics = generics(ctx.db.upcast(), generic_def);
let param_id =
hir_def::TypeParamId { parent: generic_def, local_id: *param_id };
let placeholder = to_placeholder_idx(ctx.db, param_id);
match ctx.type_param_mode {
TypeParamLoweringMode::Placeholder => TyKind::Placeholder(param_id),
TypeParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
TypeParamLoweringMode::Variable => {
let idx = generics.param_idx(param_id).expect("matching generics");
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))

View File

@ -3,10 +3,7 @@
//! Chalk (in both directions); plus some helper functions for more specialized
//! conversions.
use chalk_ir::{
cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex,
UniverseIndex,
};
use chalk_ir::{cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData};
use chalk_solve::rust_ir;
use base_db::salsa::InternKey;
@ -91,14 +88,7 @@ impl ToChalk for Ty {
.cast(&Interner)
.intern(&Interner)
}
TyKind::Placeholder(id) => {
let interned_id = db.intern_type_param_id(id);
PlaceholderIndex {
ui: UniverseIndex::ROOT,
idx: interned_id.as_intern_id().as_usize(),
}
.to_ty::<Interner>(&Interner)
}
TyKind::Placeholder(idx) => idx.to_ty::<Interner>(&Interner),
TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"),
TyKind::Dyn(predicates) => {
@ -128,13 +118,7 @@ impl ToChalk for Ty {
match chalk.data(&Interner).kind.clone() {
chalk_ir::TyKind::Error => TyKind::Unknown,
chalk_ir::TyKind::Array(ty, _size) => TyKind::Array(Substs::single(from_chalk(db, ty))),
chalk_ir::TyKind::Placeholder(idx) => {
assert_eq!(idx.ui, UniverseIndex::ROOT);
let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
crate::salsa::InternId::from(idx.idx),
);
TyKind::Placeholder(db.lookup_intern_type_param_id(interned_id))
}
chalk_ir::TyKind::Placeholder(idx) => TyKind::Placeholder(idx),
chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => {
let associated_ty = proj.associated_ty_id;
let parameters = from_chalk(db, proj.substitution);