Skip to content

Commit

Permalink
Implement a map from typed to parsed decl ids in the declaration engine.
Browse files Browse the repository at this point in the history
  • Loading branch information
tritao committed Jul 8, 2024
1 parent f81b6c2 commit 3e942ec
Show file tree
Hide file tree
Showing 17 changed files with 349 additions and 155 deletions.
141 changes: 114 additions & 27 deletions sway-core/src/decl_engine/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,20 @@ use sway_types::{Named, ProgramId, Spanned};

use crate::{
concurrent_slab::ConcurrentSlab,
decl_engine::parsed_id::ParsedDeclId,
decl_engine::*,
engine_threading::*,
language::ty::{
self, TyAbiDecl, TyConfigurableDecl, TyConstantDecl, TyEnumDecl, TyFunctionDecl,
TyImplTrait, TyStorageDecl, TyStructDecl, TyTraitDecl, TyTraitFn, TyTraitType,
TyTypeAliasDecl,
language::{
parsed::{
AbiDeclaration, ConfigurableDeclaration, ConstantDeclaration, EnumDeclaration,
FunctionDeclaration, ImplTrait, StorageDeclaration, StructDeclaration,
TraitDeclaration, TraitFn, TraitTypeDeclaration, TypeAliasDeclaration,
},
ty::{
self, TyAbiDecl, TyConfigurableDecl, TyConstantDecl, TyEnumDecl, TyFunctionDecl,
TyImplTrait, TyStorageDecl, TyStructDecl, TyTraitDecl, TyTraitFn, TyTraitType,
TyTypeAliasDecl,
},
},
};

Expand All @@ -34,6 +42,19 @@ pub struct DeclEngine {
enum_slab: ConcurrentSlab<TyEnumDecl>,
type_alias_slab: ConcurrentSlab<TyTypeAliasDecl>,

function_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyFunctionDecl>, ParsedDeclId<FunctionDeclaration>>>,
trait_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyTraitDecl>, ParsedDeclId<TraitDeclaration>>>,
trait_fn_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyTraitFn>, ParsedDeclId<TraitFn>>>,
trait_type_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyTraitType>, ParsedDeclId<TraitTypeDeclaration>>>,
impl_trait_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyImplTrait>, ParsedDeclId<ImplTrait>>>,
struct_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyStructDecl>, ParsedDeclId<StructDeclaration>>>,
storage_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyStorageDecl>, ParsedDeclId<StorageDeclaration>>>,
abi_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyAbiDecl>, ParsedDeclId<AbiDeclaration>>>,
constant_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyConstantDecl>, ParsedDeclId<ConstantDeclaration>>>,
configurable_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyConfigurableDecl>, ParsedDeclId<ConfigurableDeclaration>>>,
enum_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyEnumDecl>, ParsedDeclId<EnumDeclaration>>>,
type_alias_slab_parsed_decl_id_map: RwLock<HashMap<DeclId<TyTypeAliasDecl>, ParsedDeclId<TypeAliasDeclaration>>>,

parents: RwLock<HashMap<AssociatedItemDeclId, Vec<AssociatedItemDeclId>>>,
}

Expand All @@ -52,6 +73,18 @@ impl Clone for DeclEngine {
configurable_slab: self.configurable_slab.clone(),
enum_slab: self.enum_slab.clone(),
type_alias_slab: self.type_alias_slab.clone(),
function_slab_parsed_decl_id_map: RwLock::new(self.function_slab_parsed_decl_id_map.read().clone()),
trait_slab_parsed_decl_id_map: RwLock::new(self.trait_slab_parsed_decl_id_map.read().clone()),
trait_fn_slab_parsed_decl_id_map: RwLock::new(self.trait_fn_slab_parsed_decl_id_map.read().clone()),
trait_type_slab_parsed_decl_id_map: RwLock::new(self.trait_type_slab_parsed_decl_id_map.read().clone()),
impl_trait_slab_parsed_decl_id_map: RwLock::new(self.impl_trait_slab_parsed_decl_id_map.read().clone()),
struct_slab_parsed_decl_id_map: RwLock::new(self.struct_slab_parsed_decl_id_map.read().clone()),
storage_slab_parsed_decl_id_map: RwLock::new(self.storage_slab_parsed_decl_id_map.read().clone()),
abi_slab_parsed_decl_id_map: RwLock::new(self.abi_slab_parsed_decl_id_map.read().clone()),
constant_slab_parsed_decl_id_map: RwLock::new(self.constant_slab_parsed_decl_id_map.read().clone()),
configurable_slab_parsed_decl_id_map: RwLock::new(self.configurable_slab_parsed_decl_id_map.read().clone()),
enum_slab_parsed_decl_id_map: RwLock::new(self.enum_slab_parsed_decl_id_map.read().clone()),
type_alias_slab_parsed_decl_id_map: RwLock::new(self.type_alias_slab_parsed_decl_id_map.read().clone()),
parents: RwLock::new(self.parents.read().clone()),
}
}
Expand All @@ -61,26 +94,33 @@ pub trait DeclEngineGet<I, U> {
fn get(&self, index: &I) -> Arc<U>;
}

pub trait DeclEngineInsert<T>
pub trait DeclEngineGetParsedDeclId<I, U> {
fn get_parsed_decl_id(&self, decl_id: &I) -> Option<ParsedDeclId<U>>;
}

pub trait DeclEngineInsert<T, PT>
where
T: Named + Spanned,
{
fn insert(&self, decl: T) -> DeclRef<DeclId<T>>;
fn insert(&self, decl: T, parsed_decl_id: Option<&ParsedDeclId<PT>>) -> DeclRef<DeclId<T>>;
}

pub trait DeclEngineInsertArc<T>
pub trait DeclEngineInsertArc<T, PT>
where
T: Named + Spanned,
{
fn insert_arc(&self, decl: Arc<T>) -> DeclRef<DeclId<T>>;
fn insert_arc(
&self,
decl: Arc<T>,
parsed_decl_id: Option<&ParsedDeclId<PT>>,
) -> DeclRef<DeclId<T>>;
}

pub trait DeclEngineReplace<T> {
fn replace(&self, index: DeclId<T>, decl: T);
}

pub trait DeclEngineIndex<T>:
DeclEngineGet<DeclId<T>, T> + DeclEngineInsert<T> + DeclEngineReplace<T>
pub trait DeclEngineIndex<T>: DeclEngineGet<DeclId<T>, T> + DeclEngineReplace<T>
where
T: Named + Spanned,
{
Expand Down Expand Up @@ -115,9 +155,13 @@ decl_engine_get!(enum_slab, ty::TyEnumDecl);
decl_engine_get!(type_alias_slab, ty::TyTypeAliasDecl);

macro_rules! decl_engine_insert {
($slab:ident, $decl:ty) => {
impl DeclEngineInsert<$decl> for DeclEngine {
fn insert(&self, decl: $decl) -> DeclRef<DeclId<$decl>> {
($slab:ident, $decl:ty, $parsed_decl:ty) => {
impl DeclEngineInsert<$decl, $parsed_decl> for DeclEngine {
fn insert(
&self,
decl: $decl,
_parsed_decl_id: Option<&ParsedDeclId<$parsed_decl>>,
) -> DeclRef<DeclId<$decl>> {
let span = decl.span();
DeclRef::new(
decl.name().clone(),
Expand All @@ -126,8 +170,12 @@ macro_rules! decl_engine_insert {
)
}
}
impl DeclEngineInsertArc<$decl> for DeclEngine {
fn insert_arc(&self, decl: Arc<$decl>) -> DeclRef<DeclId<$decl>> {
impl DeclEngineInsertArc<$decl, $parsed_decl> for DeclEngine {
fn insert_arc(
&self,
decl: Arc<$decl>,
_parsed_decl_id: Option<&ParsedDeclId<$parsed_decl>>,
) -> DeclRef<DeclId<$decl>> {
let span = decl.span();
DeclRef::new(
decl.name().clone(),
Expand All @@ -138,18 +186,57 @@ macro_rules! decl_engine_insert {
}
};
}
decl_engine_insert!(function_slab, ty::TyFunctionDecl);
decl_engine_insert!(trait_slab, ty::TyTraitDecl);
decl_engine_insert!(trait_fn_slab, ty::TyTraitFn);
decl_engine_insert!(trait_type_slab, ty::TyTraitType);
decl_engine_insert!(impl_trait_slab, ty::TyImplTrait);
decl_engine_insert!(struct_slab, ty::TyStructDecl);
decl_engine_insert!(storage_slab, ty::TyStorageDecl);
decl_engine_insert!(abi_slab, ty::TyAbiDecl);
decl_engine_insert!(constant_slab, ty::TyConstantDecl);
decl_engine_insert!(configurable_slab, ty::TyConfigurableDecl);
decl_engine_insert!(enum_slab, ty::TyEnumDecl);
decl_engine_insert!(type_alias_slab, ty::TyTypeAliasDecl);
decl_engine_insert!(function_slab, ty::TyFunctionDecl, FunctionDeclaration);
decl_engine_insert!(trait_slab, ty::TyTraitDecl, TraitDeclaration);
decl_engine_insert!(trait_fn_slab, ty::TyTraitFn, TraitFn);
decl_engine_insert!(trait_type_slab, ty::TyTraitType, TraitTypeDeclaration);
decl_engine_insert!(impl_trait_slab, ty::TyImplTrait, ImplTrait);
decl_engine_insert!(struct_slab, ty::TyStructDecl, StructDeclaration);
decl_engine_insert!(storage_slab, ty::TyStorageDecl, StorageDeclaration);
decl_engine_insert!(abi_slab, ty::TyAbiDecl, AbiDeclaration);
decl_engine_insert!(constant_slab, ty::TyConstantDecl, ConstantDeclaration);
decl_engine_insert!(
configurable_slab,
ty::TyConfigurableDecl,
ConfigurableDeclaration
);
decl_engine_insert!(enum_slab, ty::TyEnumDecl, EnumDeclaration);
decl_engine_insert!(type_alias_slab, ty::TyTypeAliasDecl, TypeAliasDeclaration);

macro_rules! decl_engine_parsed_decl_id {
($slab:ident, $decl:ty, $parsed_decl:ty) => {
impl DeclEngineGetParsedDeclId<DeclId<$decl>, $parsed_decl> for DeclEngine {
fn get_parsed_decl_id(
&self,
decl_id: &DeclId<$decl>,
) -> Option<ParsedDeclId<$parsed_decl>> {
let parsed_decl_id_map = self.$slab.read();
if let Some(parsed_decl_id) = parsed_decl_id_map.get(&decl_id) {
return Some(parsed_decl_id.clone());
} else {
None
}
}
}
};
}

decl_engine_parsed_decl_id!(function_slab_parsed_decl_id_map, ty::TyFunctionDecl, FunctionDeclaration);
decl_engine_parsed_decl_id!(trait_slab_parsed_decl_id_map, ty::TyTraitDecl, TraitDeclaration);
decl_engine_parsed_decl_id!(trait_fn_slab_parsed_decl_id_map, ty::TyTraitFn, TraitFn);
decl_engine_parsed_decl_id!(trait_type_slab_parsed_decl_id_map, ty::TyTraitType, TraitTypeDeclaration);
decl_engine_parsed_decl_id!(impl_trait_slab_parsed_decl_id_map, ty::TyImplTrait, ImplTrait);
decl_engine_parsed_decl_id!(struct_slab_parsed_decl_id_map, ty::TyStructDecl, StructDeclaration);
decl_engine_parsed_decl_id!(storage_slab_parsed_decl_id_map, ty::TyStorageDecl, StorageDeclaration);
decl_engine_parsed_decl_id!(abi_slab_parsed_decl_id_map, ty::TyAbiDecl, AbiDeclaration);
decl_engine_parsed_decl_id!(constant_slab_parsed_decl_id_map, ty::TyConstantDecl, ConstantDeclaration);
decl_engine_parsed_decl_id!(
configurable_slab_parsed_decl_id_map,
ty::TyConfigurableDecl,
ConfigurableDeclaration
);
decl_engine_parsed_decl_id!(enum_slab_parsed_decl_id_map, ty::TyEnumDecl, EnumDeclaration);
decl_engine_parsed_decl_id!(type_alias_slab_parsed_decl_id_map, ty::TyTypeAliasDecl, TypeAliasDeclaration);

macro_rules! decl_engine_replace {
($slab:ident, $decl:ty) => {
Expand Down
6 changes: 3 additions & 3 deletions sway-core/src/decl_engine/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,9 @@ impl SubstTypes for DeclId<TyTraitType> {
}
}

impl<T> DeclId<T>
impl<T, U> DeclId<T>
where
DeclEngine: DeclEngineIndex<T>,
DeclEngine: DeclEngineIndex<T> + DeclEngineGetParsedDeclId<T, U>,
T: Named + Spanned + SubstTypes + Clone,
{
pub(crate) fn subst_types_and_insert_new(
Expand All @@ -242,7 +242,7 @@ where
let decl_engine = engines.de();
let mut decl = (*decl_engine.get(self)).clone();
if decl.subst(type_mapping, engines).has_changes() {
Some(decl_engine.insert(decl))
Some(decl_engine.insert(decl, decl_engine.get_parsed_decl_id(self).as_ref()))
} else {
None
}
Expand Down
4 changes: 2 additions & 2 deletions sway-core/src/decl_engine/ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl<T> DeclRef<DeclId<T>> {

impl<T> DeclRef<DeclId<T>>
where
DeclEngine: DeclEngineIndex<T>,
DeclEngine: DeclEngineIndex<T> + DeclEngineGetParsedDeclId<T>,
T: Named + Spanned + SubstTypes + Clone,
{
pub(crate) fn subst_types_and_insert_new(
Expand All @@ -107,7 +107,7 @@ where
let decl_engine = engines.de();
let mut decl = (*decl_engine.get(&self.id)).clone();
if decl.subst(type_mapping, engines).has_changes() {
Some(decl_engine.insert(decl))
Some(decl_engine.insert(decl, decl_engine.get_parsed_decl_id(&self.id).as_ref()))
} else {
None
}
Expand Down
48 changes: 30 additions & 18 deletions sway-core/src/semantic_analysis/ast_node/declaration/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use sway_error::error::CompileError;
use sway_types::{Ident, Named, Span, Spanned};

use crate::{
decl_engine::{DeclEngineInsert, DeclEngineInsertArc, DeclId},
decl_engine::{DeclEngineGetParsedDeclId, DeclEngineInsert, DeclEngineInsertArc, DeclId},
language::ty::TyAbiDecl,
namespace::{IsExtendingExistingImpl, IsImplSelf, TryInsertingTraitImplOnFailure},
semantic_analysis::{
Expand Down Expand Up @@ -119,15 +119,16 @@ impl ty::TyAbiDecl {
}
}
new_interface_surface.push(ty::TyTraitInterfaceItem::TraitFn(
ctx.engines.de().insert(method.clone()),
ctx.engines.de().insert(method.clone(), Some(&decl_id)),
));
method.name.clone()
}
TraitItem::Constant(decl_id) => {
let const_decl = engines.pe().get_constant(&decl_id).as_ref().clone();
let const_decl =
ty::TyConstantDecl::type_check(handler, ctx.by_ref(), const_decl)?;
let decl_ref = ctx.engines.de().insert(const_decl.clone());
let decl_ref =
ctx.engines.de().insert(const_decl.clone(), Some(&decl_id));
new_interface_surface
.push(ty::TyTraitInterfaceItem::Constant(decl_ref.clone()));

Expand All @@ -150,7 +151,8 @@ impl ty::TyAbiDecl {

let type_decl =
ty::TyTraitType::type_check(handler, ctx.by_ref(), type_decl)?;
let decl_ref = ctx.engines().de().insert(type_decl.clone());
let decl_ref =
ctx.engines().de().insert(type_decl.clone(), Some(&decl_id));
new_interface_surface
.push(ty::TyTraitInterfaceItem::Type(decl_ref.clone()));

Expand Down Expand Up @@ -197,7 +199,9 @@ impl ty::TyAbiDecl {
span: method.name.span(),
});
}
new_items.push(TyTraitItem::Fn(ctx.engines.de().insert(method)));
new_items.push(TyTraitItem::Fn(
ctx.engines.de().insert(method, Some(&method_id)),
));
}

// Compared to regular traits, we do not insert recursively methods of ABI supertraits
Expand Down Expand Up @@ -288,12 +292,14 @@ impl ty::TyAbiDecl {
}
}
all_items.push(TyImplItem::Fn(
ctx.engines
.de()
.insert(method.to_dummy_func(
AbiMode::ImplAbiFn(self.name.clone(), Some(self_decl_id)),
Some(type_id),
))
decl_engine
.insert(
method.to_dummy_func(
AbiMode::ImplAbiFn(self.name.clone(), Some(self_decl_id)),
Some(type_id),
),
None,
)
.with_parent(ctx.engines.de(), (*decl_ref.id()).into()),
));
}
Expand Down Expand Up @@ -349,21 +355,27 @@ impl ty::TyAbiDecl {
}
}
all_items.push(TyImplItem::Fn(
ctx.engines
.de()
.insert_arc(method)
decl_engine
.insert_arc(
method,
decl_engine.get_parsed_decl_id(decl_ref.id()).as_ref(),
)
.with_parent(ctx.engines.de(), (*decl_ref.id()).into()),
));
}
ty::TyTraitItem::Constant(decl_ref) => {
let const_decl = decl_engine.get_constant(decl_ref);
all_items.push(TyImplItem::Constant(
ctx.engines.de().insert_arc(const_decl),
));
all_items.push(TyImplItem::Constant(decl_engine.insert_arc(
const_decl,
decl_engine.get_parsed_decl_id(decl_ref.id()).as_ref(),
)));
}
ty::TyTraitItem::Type(decl_ref) => {
let type_decl = decl_engine.get_type(decl_ref);
all_items.push(TyImplItem::Type(ctx.engines.de().insert_arc(type_decl)));
all_items.push(TyImplItem::Type(decl_engine.insert_arc(
type_decl,
decl_engine.get_parsed_decl_id(decl_ref.id()).as_ref(),
)));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use sway_error::{
use sway_types::{style::is_screaming_snake_case, Spanned};

use crate::{
decl_engine::{DeclEngineInsert, ReplaceDecls},
decl_engine::{DeclEngineGetParsedDeclId, DeclEngineInsert, ReplaceDecls},
language::{
parsed::*,
ty::{self, TyConfigurableDecl},
Expand Down Expand Up @@ -124,7 +124,8 @@ impl ty::TyConfigurableDecl {
})?;
let (decode_fn_ref, _, _): (crate::decl_engine::DeclRefFunction, _, _) = r?;

let mut decode_fn_decl = (*engines.de().get_function(&decode_fn_ref)).clone();
let decode_fn_id = *decode_fn_ref.id();
let mut decode_fn_decl = (*engines.de().get_function(&decode_fn_id)).clone();
let decl_mapping = crate::TypeParameter::gather_decl_mapping_from_trait_constraints(
handler,
ctx.by_ref(),
Expand All @@ -135,8 +136,11 @@ impl ty::TyConfigurableDecl {
decode_fn_decl.replace_decls(&decl_mapping, handler, &mut ctx)?;
let decode_fn_ref = engines
.de()
.insert(decode_fn_decl)
.with_parent(engines.de(), (*decode_fn_ref.id()).into());
.insert(
decode_fn_decl,
engines.de().get_parsed_decl_id(&decode_fn_id).as_ref(),
)
.with_parent(engines.de(), decode_fn_id.into());

(value, Some(decode_fn_ref))
} else {
Expand Down
Loading

0 comments on commit 3e942ec

Please sign in to comment.