Skip to content

Commit

Permalink
[WIP][ty] Update salsa
Browse files Browse the repository at this point in the history
  • Loading branch information
Y-Nak committed Jun 27, 2024
1 parent 6cb360a commit 59b3a79
Show file tree
Hide file tree
Showing 23 changed files with 1,013 additions and 923 deletions.
22 changes: 11 additions & 11 deletions crates/hir-analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,27 @@ pub struct Jar(
name_resolution::traits_in_scope::available_traits_in_scope_impl,
name_resolution::traits_in_scope::TraitScope<'_>,
// Type system.
ty::ty_def::TyId,
ty::ty_def::TyId<'_>,
ty::ty_def::ty_kind,
ty::ty_def::pretty_print_ty,
ty::ty_def::decompose_ty_app,
ty::ty_def::ty_flags,
// Adt types.
ty::adt_def::AdtDef,
ty::adt_def::AdtRefId,
ty::adt_def::AdtDef<'_>,
ty::adt_def::AdtRefId<'_>,
ty::adt_def::lower_adt,
// Func type.
ty::func_def::FuncDef,
ty::func_def::FuncDef<'_>,
ty::func_def::lower_func,
// Const types.
ty::const_ty::ConstTyId,
ty::const_ty::ConstTyId<'_>,
ty::const_ty::evaluate_const_ty,
// Type lowering.
ty::ty_lower::lower_hir_ty,
ty::ty_lower::lower_type_alias,
ty::ty_lower::collect_generic_params,
ty::ty_lower::GenericParamOwnerId,
ty::ty_lower::GenericParamTypeSet,
ty::ty_lower::GenericParamOwnerId<'_>,
ty::ty_lower::GenericParamTypeSet<'_>,
ty::ty_lower::evaluate_params_precursor,
// Trait lowering.
ty::trait_lower::lower_trait,
Expand All @@ -50,9 +50,9 @@ pub struct Jar(
ty::def_analysis::analyze_impl_trait,
ty::def_analysis::analyze_func,
// Trait system.
ty::trait_def::TraitDef,
ty::trait_def::TraitInstId,
ty::trait_def::Implementor,
ty::trait_def::TraitDef<'_>,
ty::trait_def::TraitInstId<'_>,
ty::trait_def::Implementor<'_>,
ty::trait_def::ingot_trait_env,
ty::trait_def::impls_for_trait,
ty::trait_def::impls_for_ty,
Expand All @@ -65,7 +65,7 @@ pub struct Jar(
ty::trait_resolution::constraint::collect_func_def_constraints,
ty::trait_resolution::constraint::collect_func_def_constraints_impl,
ty::trait_resolution::constraint::ty_constraints,
ty::trait_resolution::PredicateListId,
ty::trait_resolution::PredicateListId<'_>,
ty::trait_resolution::is_goal_satisfiable,
ty::trait_resolution::check_ty_wf,
ty::trait_resolution::check_trait_inst_wf,
Expand Down
99 changes: 51 additions & 48 deletions crates/hir-analysis/src/ty/adt_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,52 +15,52 @@ use crate::HirAnalysisDb;

/// Lower HIR ADT definition(`struct/enum/contract`) to [`AdtDef`].
#[salsa::tracked]
pub fn lower_adt(db: &dyn HirAnalysisDb, adt: AdtRefId) -> AdtDef {
pub fn lower_adt<'db>(db: &'db dyn HirAnalysisDb, adt: AdtRefId<'db>) -> AdtDef<'db> {
AdtTyBuilder::new(db, adt).build()
}

/// Represents a ADT type definition.
#[salsa::tracked]
pub struct AdtDef {
pub adt_ref: AdtRefId,
pub struct AdtDef<'db> {
pub adt_ref: AdtRefId<'db>,

/// Type parameters of the ADT.
#[return_ref]
pub param_set: GenericParamTypeSet,
pub param_set: GenericParamTypeSet<'db>,

/// Fields of the ADT, if the ADT is an enum, this represents variants.
/// Otherwise, `fields[0]` represents all fields of the struct.
#[return_ref]
pub fields: Vec<AdtField>,
pub fields: Vec<AdtField<'db>>,
}

impl AdtDef {
pub(crate) fn name(self, db: &dyn HirAnalysisDb) -> IdentId {
impl<'db> AdtDef<'db> {
pub(crate) fn name(self, db: &'db dyn HirAnalysisDb) -> IdentId<'db> {
self.adt_ref(db).name(db)
}

pub(crate) fn params(self, db: &dyn HirAnalysisDb) -> &[TyId] {
pub(crate) fn params(self, db: &'db dyn HirAnalysisDb) -> &[TyId<'db>] {
self.param_set(db).params(db)
}

pub(crate) fn original_params(self, db: &dyn HirAnalysisDb) -> &[TyId] {
pub(crate) fn original_params(self, db: &'db dyn HirAnalysisDb) -> &[TyId] {
self.param_set(db).explicit_params(db)
}

pub(crate) fn is_struct(self, db: &dyn HirAnalysisDb) -> bool {
matches!(self.adt_ref(db).data(db), AdtRef::Struct(_))
}

pub fn scope(self, db: &dyn HirAnalysisDb) -> ScopeId {
pub fn scope(self, db: &'db dyn HirAnalysisDb) -> ScopeId<'db> {
self.adt_ref(db).scope(db)
}

pub(crate) fn variant_ty_span(
self,
db: &dyn HirAnalysisDb,
db: &'db dyn HirAnalysisDb,
field_idx: usize,
ty_idx: usize,
) -> DynLazySpan {
) -> DynLazySpan<'db> {
match self.adt_ref(db).data(db) {
AdtRef::Enum(e) => {
let span = e.lazy_span().variants_moved().variant_moved(field_idx);
Expand Down Expand Up @@ -89,7 +89,7 @@ impl AdtDef {
}
}

pub(crate) fn ingot(self, db: &dyn HirAnalysisDb) -> IngotId {
pub(crate) fn ingot(self, db: &'db dyn HirAnalysisDb) -> IngotId<'db> {
let hir_db = db.as_hir_db();
match self.adt_ref(db).data(db) {
AdtRef::Enum(e) => e.top_mod(hir_db).ingot(hir_db),
Expand All @@ -100,28 +100,28 @@ impl AdtDef {

pub(crate) fn as_generic_param_owner(
self,
db: &dyn HirAnalysisDb,
) -> Option<GenericParamOwnerId> {
db: &'db dyn HirAnalysisDb,
) -> Option<GenericParamOwnerId<'db>> {
self.adt_ref(db).generic_owner_id(db)
}
}

/// This struct represents a field of an ADT. If the ADT is an enum, this
/// represents a variant.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct AdtField {
#[derive(Debug, Clone, PartialEq, Eq, Hash, salsa::Update)]
pub struct AdtField<'db> {
/// Fields of the variant.
/// If the adt is an struct or contract,
/// the length of the vector is always 1.
///
/// To allow recursive types, the type of the field is represented as a HIR
/// type and.
tys: Vec<Partial<HirTyId>>,
tys: Vec<Partial<HirTyId<'db>>>,

scope: ScopeId,
scope: ScopeId<'db>,
}
impl AdtField {
pub fn ty(&self, db: &dyn HirAnalysisDb, i: usize) -> Binder<TyId> {
impl<'db> AdtField<'db> {
pub fn ty(&self, db: &'db dyn HirAnalysisDb, i: usize) -> Binder<TyId<'db>> {
let ty = if let Some(ty) = self.tys[i].to_opt() {
lower_hir_ty(db, ty, self.scope)
} else {
Expand All @@ -134,39 +134,39 @@ impl AdtField {
/// Iterates all fields types of the `field`.
pub fn iter_types<'a>(
&'a self,
db: &'a dyn HirAnalysisDb,
) -> impl Iterator<Item = Binder<TyId>> + 'a {
db: &'db dyn HirAnalysisDb,
) -> impl Iterator<Item = Binder<TyId<'db>>> + 'a {
(0..self.num_types()).map(|i| self.ty(db, i))
}

pub fn num_types(&self) -> usize {
self.tys.len()
}

pub(super) fn new(tys: Vec<Partial<HirTyId>>, scope: ScopeId) -> Self {
pub(super) fn new(tys: Vec<Partial<HirTyId<'db>>>, scope: ScopeId<'db>) -> Self {
Self { tys, scope }
}
}

#[salsa::interned]
pub struct AdtRefId {
pub data: AdtRef,
pub struct AdtRefId<'db> {
pub data: AdtRef<'db>,
}

impl AdtRefId {
pub fn scope(self, db: &dyn HirAnalysisDb) -> ScopeId {
impl<'db> AdtRefId<'db> {
pub fn scope(self, db: &'db dyn HirAnalysisDb) -> ScopeId<'db> {
self.data(db).scope()
}

pub fn as_item(self, db: &dyn HirAnalysisDb) -> ItemKind {
pub fn as_item(self, db: &'db dyn HirAnalysisDb) -> ItemKind<'db> {
match self.data(db) {
AdtRef::Enum(e) => e.into(),
AdtRef::Struct(s) => s.into(),
AdtRef::Contract(c) => c.into(),
}
}

pub fn name(self, db: &dyn HirAnalysisDb) -> IdentId {
pub fn name(self, db: &'db dyn HirAnalysisDb) -> IdentId<'db> {
let hir_db = db.as_hir_db();
match self.data(db) {
AdtRef::Enum(e) => e.name(hir_db),
Expand All @@ -181,25 +181,28 @@ impl AdtRefId {
self.as_item(db).kind_name()
}

pub fn name_span(self, db: &dyn HirAnalysisDb) -> DynLazySpan {
pub fn name_span(self, db: &'db dyn HirAnalysisDb) -> DynLazySpan<'db> {
self.scope(db)
.name_span(db.as_hir_db())
.unwrap_or_else(DynLazySpan::invalid)
}

pub fn from_enum(db: &dyn HirAnalysisDb, enum_: Enum) -> Self {
pub fn from_enum(db: &'db dyn HirAnalysisDb, enum_: Enum<'db>) -> Self {
Self::new(db, AdtRef::Enum(enum_))
}

pub fn from_struct(db: &dyn HirAnalysisDb, struct_: Struct) -> Self {
pub fn from_struct(db: &'db dyn HirAnalysisDb, struct_: Struct<'db>) -> Self {
Self::new(db, AdtRef::Struct(struct_))
}

pub fn from_contract(db: &dyn HirAnalysisDb, contract: Contract) -> Self {
pub fn from_contract(db: &'db dyn HirAnalysisDb, contract: Contract<'db>) -> Self {
Self::new(db, AdtRef::Contract(contract))
}

pub(crate) fn generic_owner_id(self, db: &dyn HirAnalysisDb) -> Option<GenericParamOwnerId> {
pub(crate) fn generic_owner_id(
self,
db: &'db dyn HirAnalysisDb,
) -> Option<GenericParamOwnerId> {
match self.data(db) {
AdtRef::Enum(e) => Some(GenericParamOwnerId::new(db, e.into())),
AdtRef::Struct(s) => Some(GenericParamOwnerId::new(db, s.into())),
Expand All @@ -209,14 +212,14 @@ impl AdtRefId {
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, derive_more::From)]
pub enum AdtRef {
Enum(Enum),
Struct(Struct),
Contract(Contract),
pub enum AdtRef<'db> {
Enum(Enum<'db>),
Struct(Struct<'db>),
Contract(Contract<'db>),
}

impl AdtRef {
pub fn scope(self) -> ScopeId {
impl<'db> AdtRef<'db> {
pub fn scope(self) -> ScopeId<'db> {
match self {
Self::Enum(e) => e.scope(),
Self::Struct(s) => s.scope(),
Expand All @@ -227,13 +230,13 @@ impl AdtRef {

struct AdtTyBuilder<'db> {
db: &'db dyn HirAnalysisDb,
adt: AdtRefId,
params: GenericParamTypeSet,
variants: Vec<AdtField>,
adt: AdtRefId<'db>,
params: GenericParamTypeSet<'db>,
variants: Vec<AdtField<'db>>,
}

impl<'db> AdtTyBuilder<'db> {
fn new(db: &'db dyn HirAnalysisDb, adt: AdtRefId) -> Self {
fn new(db: &'db dyn HirAnalysisDb, adt: AdtRefId<'db>) -> Self {
Self {
db,
adt,
Expand All @@ -242,7 +245,7 @@ impl<'db> AdtTyBuilder<'db> {
}
}

fn build(mut self) -> AdtDef {
fn build(mut self) -> AdtDef<'db> {
self.collect_generic_params();
self.collect_variants();
AdtDef::new(self.db, self.adt, self.params, self.variants)
Expand Down Expand Up @@ -275,7 +278,7 @@ impl<'db> AdtTyBuilder<'db> {
};
}

fn collect_field_types(&mut self, fields: FieldDefListId) {
fn collect_field_types(&mut self, fields: FieldDefListId<'db>) {
let scope = self.adt.scope(self.db);

let fields = fields
Expand All @@ -287,7 +290,7 @@ impl<'db> AdtTyBuilder<'db> {
self.variants.push(AdtField::new(fields, scope));
}

fn collect_enum_variant_types(&mut self, variants: VariantDefListId) {
fn collect_enum_variant_types(&mut self, variants: VariantDefListId<'db>) {
let scope = self.adt.scope(self.db);

variants
Expand Down
18 changes: 9 additions & 9 deletions crates/hir-analysis/src/ty/binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::HirAnalysisDb;
///
/// # Type Parameters
/// - `T`: The type being bound within the `Binder`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa::Update)]
pub struct Binder<T> {
value: T,
}
Expand Down Expand Up @@ -65,7 +65,7 @@ where
/// # Returns
/// A new instance of the type contained within the binder with the
/// arguments applied.
pub fn instantiate(self, db: &'db dyn HirAnalysisDb, args: &[TyId]) -> T {
pub fn instantiate(self, db: &'db dyn HirAnalysisDb, args: &[TyId<'db>]) -> T {
let mut folder = InstantiateFolder { db, args };
self.value.fold_with(&mut folder)
}
Expand All @@ -85,7 +85,7 @@ where
/// function applied.
pub fn instantiate_with<F>(self, db: &'db dyn HirAnalysisDb, f: F) -> T
where
F: FnMut(TyId) -> TyId,
F: FnMut(TyId<'db>) -> TyId<'db>,
{
let mut folder = InstantiateWithFolder {
db,
Expand All @@ -98,15 +98,15 @@ where

struct InstantiateFolder<'db, 'a> {
db: &'db dyn HirAnalysisDb,
args: &'a [TyId],
args: &'a [TyId<'db>],
}

impl<'db, 'a> TyFolder<'db> for InstantiateFolder<'db, 'a> {
fn db(&self) -> &'db dyn HirAnalysisDb {
self.db
}

fn fold_ty(&mut self, ty: TyId) -> TyId {
fn fold_ty(&mut self, ty: TyId<'db>) -> TyId<'db> {
match ty.data(self.db) {
TyData::TyParam(param) => return self.args[param.idx],
TyData::ConstTy(const_ty) => {
Expand All @@ -124,22 +124,22 @@ impl<'db, 'a> TyFolder<'db> for InstantiateFolder<'db, 'a> {

struct InstantiateWithFolder<'db, F>
where
F: FnMut(TyId) -> TyId,
F: FnMut(TyId<'db>) -> TyId<'db>,
{
db: &'db dyn HirAnalysisDb,
f: F,
params: FxHashMap<usize, TyId>,
params: FxHashMap<usize, TyId<'db>>,
}

impl<'db, F> TyFolder<'db> for InstantiateWithFolder<'db, F>
where
F: FnMut(TyId) -> TyId,
F: FnMut(TyId<'db>) -> TyId<'db>,
{
fn db(&self) -> &'db dyn HirAnalysisDb {
self.db
}

fn fold_ty(&mut self, ty: TyId) -> TyId {
fn fold_ty(&mut self, ty: TyId<'db>) -> TyId<'db> {
match ty.data(self.db) {
TyData::TyParam(param) => {
match self.params.entry(param.idx) {
Expand Down
Loading

0 comments on commit 59b3a79

Please sign in to comment.