Skip to content

Commit

Permalink
ImplTypeDefId/ImplTypeId distinction (starkware-libs#5245)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuvalsw authored Mar 12, 2024
1 parent 5988ee2 commit fdecbee
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 52 deletions.
2 changes: 1 addition & 1 deletion crates/cairo-lang-defs/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub trait DefsGroup:
#[salsa::interned]
fn intern_free_function(&self, id: FreeFunctionLongId) -> FreeFunctionId;
#[salsa::interned]
fn intern_impl_type(&self, id: ImplTypeLongId) -> ImplTypeId;
fn intern_impl_type_def(&self, id: ImplTypeDefLongId) -> ImplTypeDefId;
#[salsa::interned]
fn intern_impl_function(&self, id: ImplFunctionLongId) -> ImplFunctionId;
#[salsa::interned]
Expand Down
20 changes: 10 additions & 10 deletions crates/cairo-lang-defs/src/ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,21 +352,21 @@ define_top_level_language_element_id!(ImplDefId, ImplDefLongId, ast::ItemImpl, l

// --- Impl type items ---
define_named_language_element_id!(
ImplTypeId,
ImplTypeLongId,
ImplTypeDefId,
ImplTypeDefLongId,
ast::ItemTypeAlias,
lookup_intern_impl_type
lookup_intern_impl_type_def
);
impl ImplTypeId {
impl ImplTypeDefId {
pub fn impl_def_id(&self, db: &dyn DefsGroup) -> ImplDefId {
let ImplTypeLongId(module_file_id, ptr) = db.lookup_intern_impl_type(*self);
let ImplTypeDefLongId(module_file_id, ptr) = db.lookup_intern_impl_type_def(*self);

// Impl type ast lies 3 levels below the impl ast.
let impl_ptr = ast::ItemImplPtr(ptr.untyped().nth_parent(db.upcast(), 3));
db.intern_impl(ImplDefLongId(module_file_id, impl_ptr))
}
}
impl TopLevelLanguageElementId for ImplTypeId {
impl TopLevelLanguageElementId for ImplTypeDefId {
fn full_path(&self, db: &dyn DefsGroup) -> String {
format!("{}::{}", self.impl_def_id(db).name(db), self.name(db))
}
Expand Down Expand Up @@ -627,7 +627,7 @@ define_language_element_id_as_enum! {
#[toplevel]
/// The ID of a impl item with generic parameters.
pub enum GenericImplItemId {
Type(ImplTypeId),
Type(ImplTypeDefId),
}
}

Expand Down Expand Up @@ -732,8 +732,8 @@ impl GenericItemId {
)),
),
SyntaxKind::ImplItemList => {
GenericItemId::ImplItem(GenericImplItemId::Type(db.intern_impl_type(
ImplTypeLongId(module_file, ast::ItemTypeAliasPtr(stable_ptr)),
GenericItemId::ImplItem(GenericImplItemId::Type(db.intern_impl_type_def(
ImplTypeDefLongId(module_file, ast::ItemTypeAliasPtr(stable_ptr)),
)))
}
_ => panic!(),
Expand Down Expand Up @@ -917,7 +917,7 @@ define_language_element_id_as_enum! {
/// Id for direct children of an impl.
pub enum ImplItemId {
Function(ImplFunctionId),
Type(ImplTypeId),
Type(ImplTypeDefId),
}
}
impl ImplItemId {
Expand Down
31 changes: 17 additions & 14 deletions crates/cairo-lang-semantic/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use cairo_lang_defs::diagnostic_utils::StableLocation;
use cairo_lang_defs::ids::{
ConstantId, EnumId, ExternFunctionId, ExternTypeId, FreeFunctionId, FunctionTitleId,
FunctionWithBodyId, GenericParamId, GenericTypeId, ImplAliasId, ImplDefId, ImplFunctionId,
ImplTypeId, LookupItemId, ModuleId, ModuleItemId, ModuleTypeAliasId, StructId, TraitFunctionId,
TraitId, TraitTypeId, UseId, VariantId,
ImplTypeDefId, LookupItemId, ModuleId, ModuleItemId, ModuleTypeAliasId, StructId,
TraitFunctionId, TraitId, TraitTypeId, UseId, VariantId,
};
use cairo_lang_diagnostics::{Diagnostics, DiagnosticsBuilder, Maybe};
use cairo_lang_filesystem::db::{AsFilesGroupMut, FilesGroup};
Expand Down Expand Up @@ -586,20 +586,20 @@ pub trait SemanticGroup:
fn impl_types(
&self,
impl_def_id: ImplDefId,
) -> Maybe<Arc<OrderedHashMap<ImplTypeId, ast::ItemTypeAlias>>>;
) -> Maybe<Arc<OrderedHashMap<ImplTypeDefId, ast::ItemTypeAlias>>>;
/// Returns the ids of the type items in the impl.
#[salsa::invoke(items::imp::impl_type_ids)]
fn impl_type_ids(&self, impl_def_id: ImplDefId) -> Maybe<Arc<Vec<ImplTypeId>>>;
fn impl_type_ids(&self, impl_def_id: ImplDefId) -> Maybe<Arc<Vec<ImplTypeDefId>>>;
/// Returns the impl AST of the impl type that matches the given id, if exists.
#[salsa::invoke(items::imp::impl_type_by_id)]
fn impl_type_by_id(&self, impl_type_id: ImplTypeId) -> Maybe<Option<ast::ItemTypeAlias>>;
fn impl_type_by_id(&self, impl_type_id: ImplTypeDefId) -> Maybe<Option<ast::ItemTypeAlias>>;
/// Returns the impl type item that matches the given trait type item, if exists.
#[salsa::invoke(items::imp::impl_type_by_trait_type)]
fn impl_type_by_trait_type(
&self,
impl_def_id: ImplDefId,
trait_type_id: TraitTypeId,
) -> Maybe<Option<ImplTypeId>>;
) -> Maybe<Option<ImplTypeDefId>>;
/// Returns the functions in the impl.
#[salsa::invoke(items::imp::impl_functions)]
fn impl_functions(
Expand Down Expand Up @@ -629,34 +629,37 @@ pub trait SemanticGroup:
#[salsa::invoke(items::imp::impl_type_semantic_diagnostics)]
fn impl_type_semantic_diagnostics(
&self,
impl_type_id: ImplTypeId,
impl_type_id: ImplTypeDefId,
) -> Diagnostics<SemanticDiagnostic>;
/// Returns the resolved type of an impl item type.
#[salsa::invoke(items::imp::impl_type_resolved_type)]
fn impl_type_resolved_type(&self, impl_type_id: ImplTypeId) -> Maybe<TypeId>;
fn impl_type_resolved_type(&self, impl_type_id: ImplTypeDefId) -> Maybe<TypeId>;
/// Returns the generic parameters of an impl item type.
#[salsa::invoke(items::imp::impl_type_generic_params)]
fn impl_type_generic_params(&self, enum_id: ImplTypeId) -> Maybe<Vec<GenericParam>>;
fn impl_type_generic_params(&self, enum_id: ImplTypeDefId) -> Maybe<Vec<GenericParam>>;
/// Returns the attributes of an impl type.
#[salsa::invoke(items::imp::impl_type_attributes)]
fn impl_type_attributes(&self, impl_type_id: ImplTypeId) -> Maybe<Vec<Attribute>>;
fn impl_type_attributes(&self, impl_type_id: ImplTypeDefId) -> Maybe<Vec<Attribute>>;
/// Returns the resolution resolved_items of an impl item type.
#[salsa::invoke(items::imp::impl_type_resolver_data)]
fn impl_type_resolver_data(&self, impl_type_id: ImplTypeId) -> Maybe<Arc<ResolverData>>;
fn impl_type_resolver_data(&self, impl_type_id: ImplTypeDefId) -> Maybe<Arc<ResolverData>>;
/// Returns the trait type of an impl type.
#[salsa::invoke(items::imp::impl_type_trait_type)]
fn impl_type_trait_type(&self, impl_type_id: ImplTypeId) -> Maybe<TraitTypeId>;
fn impl_type_trait_type(&self, impl_type_id: ImplTypeDefId) -> Maybe<TraitTypeId>;

/// Private query to compute data about an impl item type.
#[salsa::invoke(items::imp::priv_impl_type_semantic_data)]
#[salsa::cycle(items::imp::priv_impl_type_semantic_data_cycle)]
fn priv_impl_type_semantic_data(
&self,
impl_type_id: ImplTypeId,
impl_type_id: ImplTypeDefId,
) -> Maybe<items::imp::ImplItemTypeData>;
/// Private query to compute data about the generic parameters of an impl item type.
#[salsa::invoke(items::imp::priv_impl_type_generic_params_data)]
fn priv_impl_type_generic_params_data(&self, enum_id: ImplTypeId) -> Maybe<GenericParamsData>;
fn priv_impl_type_generic_params_data(
&self,
enum_id: ImplTypeDefId,
) -> Maybe<GenericParamsData>;

// Impl function.
// ================
Expand Down
6 changes: 3 additions & 3 deletions crates/cairo-lang-semantic/src/items/attribute.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use cairo_lang_defs::ids::{
EnumId, FreeFunctionId, FunctionWithBodyId, ImplAliasId, ImplDefId, ImplFunctionId, ImplTypeId,
ModuleId, StructId, SubmoduleId, TraitFunctionId, TraitId, TraitTypeId,
EnumId, FreeFunctionId, FunctionWithBodyId, ImplAliasId, ImplDefId, ImplFunctionId,
ImplTypeDefId, ModuleId, StructId, SubmoduleId, TraitFunctionId, TraitId, TraitTypeId,
};
use cairo_lang_diagnostics::Maybe;
use cairo_lang_syntax::attribute::structured::Attribute;
Expand Down Expand Up @@ -135,7 +135,7 @@ impl SemanticQueryAttrs for TraitFunctionId {
}
}

impl SemanticQueryAttrs for ImplTypeId {
impl SemanticQueryAttrs for ImplTypeDefId {
fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
db.impl_type_attributes(*self)
}
Expand Down
12 changes: 12 additions & 0 deletions crates/cairo-lang-semantic/src/items/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,13 @@ use crate::{
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, SemanticObject)]
pub struct ImplGenericFunctionId {
// TODO(spapini): Consider making these private and enforcing invariants in the ctor.
/// The impl the function is in.
pub impl_id: ImplId,
/// The trait function this impl function implements.
pub function: TraitFunctionId,
}
impl ImplGenericFunctionId {
/// Gets the impl function language element, if self.impl_id is of a concrete impl.
pub fn impl_function(&self, db: &dyn SemanticGroup) -> Maybe<Option<ImplFunctionId>> {
match self.impl_id {
ImplId::Concrete(concrete_impl_id) => {
Expand Down Expand Up @@ -81,6 +84,15 @@ impl ImplGenericFunctionId {
format!("{}::{}", self.impl_id.name(db.upcast()), self.function.name(db.upcast())).into()
}
}
impl DebugWithDb<dyn SemanticGroup> for ImplGenericFunctionId {
fn fmt(
&self,
f: &mut std::fmt::Formatter<'_>,
db: &(dyn SemanticGroup + 'static),
) -> std::fmt::Result {
write!(f, "{}", self.format(db))
}
}

/// The ID of a generic function that can be concretized.
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, SemanticObject)]
Expand Down
51 changes: 31 additions & 20 deletions crates/cairo-lang-semantic/src/items/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use std::vec;
use cairo_lang_debug::DebugWithDb;
use cairo_lang_defs::ids::{
FunctionTitleId, FunctionWithBodyId, GenericKind, GenericParamId, ImplAliasId, ImplDefId,
ImplFunctionId, ImplFunctionLongId, ImplItemId, ImplTypeId, ImplTypeLongId, LanguageElementId,
LookupItemId, ModuleId, ModuleItemId, NamedLanguageElementId, NamedLanguageElementLongId,
TopLevelLanguageElementId, TraitFunctionId, TraitId, TraitOrImplContext, TraitTypeId,
ImplFunctionId, ImplFunctionLongId, ImplItemId, ImplTypeDefId, ImplTypeDefLongId,
LanguageElementId, LookupItemId, ModuleId, ModuleItemId, NamedLanguageElementId,
NamedLanguageElementLongId, TopLevelLanguageElementId, TraitFunctionId, TraitId,
TraitOrImplContext, TraitTypeId,
};
use cairo_lang_diagnostics::{
skip_diagnostic, Diagnostics, DiagnosticsBuilder, Maybe, ToMaybe, ToOption,
Expand Down Expand Up @@ -108,6 +109,13 @@ impl ConcreteImplId {
) -> Maybe<Option<ImplFunctionId>> {
db.impl_function_by_trait_function(self.impl_def_id(db), function)
}
pub fn get_impl_type_def(
&self,
db: &dyn SemanticGroup,
ty: TraitTypeId,
) -> Maybe<Option<ImplTypeDefId>> {
db.impl_type_by_trait_type(self.impl_def_id(db), ty)
}
pub fn name(&self, db: &dyn SemanticGroup) -> SmolStr {
self.impl_def_id(db).name(db.upcast())
}
Expand Down Expand Up @@ -427,7 +435,7 @@ pub struct ImplDefinitionData {
/// queries. Adding the items' diagnostics only after the whole computation breaks this cycle.
diagnostics: Diagnostics<SemanticDiagnostic>,
function_asts: OrderedHashMap<ImplFunctionId, ast::FunctionWithBody>,
item_type_asts: Arc<OrderedHashMap<ImplTypeId, ast::ItemTypeAlias>>,
item_type_asts: Arc<OrderedHashMap<ImplTypeDefId, ast::ItemTypeAlias>>,
}

// --- Selectors ---
Expand Down Expand Up @@ -493,22 +501,22 @@ pub fn impl_function_by_trait_function(
pub fn impl_types(
db: &dyn SemanticGroup,
impl_def_id: ImplDefId,
) -> Maybe<Arc<OrderedHashMap<ImplTypeId, ast::ItemTypeAlias>>> {
) -> Maybe<Arc<OrderedHashMap<ImplTypeDefId, ast::ItemTypeAlias>>> {
Ok(db.priv_impl_definition_data(impl_def_id)?.item_type_asts)
}

/// Query implementation of [crate::db::SemanticGroup::impl_type_ids].
pub fn impl_type_ids(
db: &dyn SemanticGroup,
impl_def_id: ImplDefId,
) -> Maybe<Arc<Vec<ImplTypeId>>> {
) -> Maybe<Arc<Vec<ImplTypeDefId>>> {
Ok(Arc::new(db.impl_types(impl_def_id)?.keys().copied().collect()))
}

/// Query implementation of [crate::db::SemanticGroup::impl_type_by_id].
pub fn impl_type_by_id(
db: &dyn SemanticGroup,
impl_type_id: ImplTypeId,
impl_type_id: ImplTypeDefId,
) -> Maybe<Option<ast::ItemTypeAlias>> {
let impl_types = db.impl_types(impl_type_id.impl_def_id(db.upcast()))?;
Ok(impl_types.get(&impl_type_id).cloned())
Expand All @@ -519,11 +527,11 @@ pub fn impl_type_by_trait_type(
db: &dyn SemanticGroup,
impl_def_id: ImplDefId,
trait_type_id: TraitTypeId,
) -> Maybe<Option<ImplTypeId>> {
) -> Maybe<Option<ImplTypeDefId>> {
let defs_db = db.upcast();
let name = trait_type_id.name(defs_db);
for impl_type_id in db.priv_impl_definition_data(impl_def_id)?.item_type_asts.keys() {
if db.lookup_intern_impl_type(*impl_type_id).name(defs_db) == name {
if db.lookup_intern_impl_type_def(*impl_type_id).name(defs_db) == name {
return Ok(Some(*impl_type_id));
}
}
Expand Down Expand Up @@ -618,7 +626,7 @@ pub fn priv_impl_definition_data(
}
ImplItem::Type(ty) => {
let impl_type_id =
db.intern_impl_type(ImplTypeLongId(module_file_id, ty.stable_ptr()));
db.intern_impl_type_def(ImplTypeDefLongId(module_file_id, ty.stable_ptr()));
let name_node = ty.name(syntax_db);
let name = name_node.text(syntax_db);
if !impl_item_names.insert(name.clone()) {
Expand Down Expand Up @@ -1155,44 +1163,47 @@ pub struct ImplItemTypeData {
/// Query implementation of [crate::db::SemanticGroup::impl_type_semantic_diagnostics].
pub fn impl_type_semantic_diagnostics(
db: &dyn SemanticGroup,
impl_type_id: ImplTypeId,
impl_type_id: ImplTypeDefId,
) -> Diagnostics<SemanticDiagnostic> {
db.priv_impl_type_semantic_data(impl_type_id).map(|data| data.diagnostics).unwrap_or_default()
}

/// Query implementation of [crate::db::SemanticGroup::impl_type_resolved_type].
pub fn impl_type_resolved_type(db: &dyn SemanticGroup, impl_type_id: ImplTypeId) -> Maybe<TypeId> {
pub fn impl_type_resolved_type(
db: &dyn SemanticGroup,
impl_type_id: ImplTypeDefId,
) -> Maybe<TypeId> {
db.priv_impl_type_semantic_data(impl_type_id)?.type_alias_data.resolved_type
}

/// Query implementation of [crate::db::SemanticGroup::impl_type_generic_params].
pub fn impl_type_generic_params(
db: &dyn SemanticGroup,
impl_type_id: ImplTypeId,
impl_type_id: ImplTypeDefId,
) -> Maybe<Vec<GenericParam>> {
Ok(db.priv_impl_type_generic_params_data(impl_type_id)?.generic_params)
}

/// Query implementation of [crate::db::SemanticGroup::impl_type_attributes].
pub fn impl_type_attributes(
db: &dyn SemanticGroup,
impl_type_id: ImplTypeId,
impl_type_id: ImplTypeDefId,
) -> Maybe<Vec<Attribute>> {
Ok(db.priv_impl_type_semantic_data(impl_type_id)?.type_alias_data.attributes)
}

/// Query implementation of [crate::db::SemanticGroup::impl_type_resolver_data].
pub fn impl_type_resolver_data(
db: &dyn SemanticGroup,
impl_type_id: ImplTypeId,
impl_type_id: ImplTypeDefId,
) -> Maybe<Arc<ResolverData>> {
Ok(db.priv_impl_type_semantic_data(impl_type_id)?.type_alias_data.resolver_data)
}

/// Query implementation of [crate::db::SemanticGroup::impl_type_trait_type].
pub fn impl_type_trait_type(
db: &dyn SemanticGroup,
impl_type_id: ImplTypeId,
impl_type_id: ImplTypeDefId,
) -> Maybe<TraitTypeId> {
db.priv_impl_type_semantic_data(impl_type_id)?.trait_type_id
}
Expand All @@ -1202,7 +1213,7 @@ pub fn impl_type_trait_type(
/// Query implementation of [crate::db::SemanticGroup::priv_impl_type_semantic_data].
pub fn priv_impl_type_semantic_data(
db: &dyn SemanticGroup,
impl_type_id: ImplTypeId,
impl_type_id: ImplTypeDefId,
) -> Maybe<ImplItemTypeData> {
let module_file_id = impl_type_id.module_file_id(db.upcast());
let mut diagnostics = SemanticDiagnostics::new(module_file_id.file_id(db.upcast())?);
Expand Down Expand Up @@ -1230,7 +1241,7 @@ pub fn priv_impl_type_semantic_data(
pub fn priv_impl_type_semantic_data_cycle(
db: &dyn SemanticGroup,
_cycle: &[String],
impl_type_id: &ImplTypeId,
impl_type_id: &ImplTypeDefId,
) -> Maybe<ImplItemTypeData> {
let module_file_id = impl_type_id.module_file_id(db.upcast());
let mut diagnostics = SemanticDiagnostics::new(module_file_id.file_id(db.upcast())?);
Expand All @@ -1257,7 +1268,7 @@ pub fn priv_impl_type_semantic_data_cycle(
/// Query implementation of [crate::db::SemanticGroup::priv_impl_type_generic_params_data].
pub fn priv_impl_type_generic_params_data(
db: &dyn SemanticGroup,
impl_type_id: ImplTypeId,
impl_type_id: ImplTypeDefId,
) -> Maybe<GenericParamsData> {
let defs_db = db.upcast();
let module_file_id = impl_type_id.module_file_id(defs_db);
Expand All @@ -1278,7 +1289,7 @@ pub fn priv_impl_type_generic_params_data(
fn validate_impl_item_type(
db: &dyn SemanticGroup,
diagnostics: &mut SemanticDiagnostics,
impl_type_id: ImplTypeId,
impl_type_id: ImplTypeDefId,
impl_type_ast: &ast::ItemTypeAlias,
) -> Maybe<TraitTypeId> {
let defs_db = db.upcast();
Expand Down
4 changes: 2 additions & 2 deletions crates/cairo-lang-semantic/src/lookup_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::sync::Arc;

use cairo_lang_defs::ids::{
ConstantId, EnumId, ExternFunctionId, ExternTypeId, FileIndex, FreeFunctionId,
FunctionWithBodyId, ImplAliasId, ImplDefId, ImplFunctionId, ImplItemId, ImplTypeId,
FunctionWithBodyId, ImplAliasId, ImplDefId, ImplFunctionId, ImplItemId, ImplTypeDefId,
LanguageElementId, LookupItemId, ModuleFileId, ModuleId, ModuleItemId, ModuleTypeAliasId,
StructId, SubmoduleId, TraitFunctionId, TraitId, TraitItemId, TraitTypeId, UseId,
};
Expand Down Expand Up @@ -203,7 +203,7 @@ impl HasResolverData for ImplItemId {
}
}

impl HasResolverData for ImplTypeId {
impl HasResolverData for ImplTypeDefId {
fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
db.impl_type_resolver_data(*self)
}
Expand Down
Loading

0 comments on commit fdecbee

Please sign in to comment.