Skip to content

Commit

Permalink
Add phantom types to sierra-gen. (#5382)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyalesokhin-starkware authored Apr 9, 2024
1 parent e375707 commit 997a731
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 3 deletions.
12 changes: 11 additions & 1 deletion crates/cairo-lang-semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use cairo_lang_defs::ids::{
};
use cairo_lang_diagnostics::{DiagnosticAdded, Maybe};
use cairo_lang_proc_macros::SemanticObject;
use cairo_lang_syntax::attribute::consts::MUST_USE_ATTR;
use cairo_lang_syntax::attribute::consts::{MUST_USE_ATTR, PHANTOM_ATTR};
use cairo_lang_syntax::node::ids::SyntaxStablePtrId;
use cairo_lang_syntax::node::{ast, TypedStablePtr, TypedSyntaxNode};
use cairo_lang_utils::{define_short_id, try_extract_matches, OptionFrom};
Expand Down Expand Up @@ -219,6 +219,16 @@ impl ConcreteTypeId {
)
}
}

/// Returns whether the type has the `#[phantom]` attribute.
pub fn is_phantom(&self, db: &dyn SemanticGroup) -> Maybe<bool> {
match self {
ConcreteTypeId::Struct(id) => id.has_attr(db, PHANTOM_ATTR),
ConcreteTypeId::Enum(id) => id.has_attr(db, PHANTOM_ATTR),
ConcreteTypeId::Extern(id) => id.has_attr(db, PHANTOM_ATTR),
}
}

/// Returns whether the type has the `#[must_use]` attribute.
pub fn is_must_use(&self, db: &dyn SemanticGroup) -> Maybe<bool> {
match self {
Expand Down
16 changes: 15 additions & 1 deletion crates/cairo-lang-sierra-generator/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub enum SierraGeneratorTypeLongId {
Regular(Arc<cairo_lang_sierra::program::ConcreteTypeLongId>),
/// The long id for cycle breakers, such as `Box` and `Nullable`.
CycleBreaker(semantic::TypeId),
/// This is a long id of a phantom type.
/// Phantom types have a one to one mapping from the semantic type to the sierra type.
Phantom(semantic::TypeId),
}

#[salsa::query_group(SierraGenDatabase)]
Expand Down Expand Up @@ -198,6 +201,16 @@ fn get_type_info(
zero_sized: false,
}));
}
SierraGeneratorTypeLongId::Phantom(ty) => {
let long_id = db.get_concrete_long_type_id(ty)?.as_ref().clone();
return Ok(Arc::new(cairo_lang_sierra::extensions::types::TypeInfo {
long_id,
storable: false,
droppable: false,
duplicatable: false,
zero_sized: false,
}));
}
};
let concrete_ty = cairo_lang_sierra::extensions::core::CoreType::specialize_by_id(
&SierraSignatureSpecializationContext(db),
Expand All @@ -219,6 +232,7 @@ pub fn sierra_concrete_long_id(
) -> Maybe<Arc<cairo_lang_sierra::program::ConcreteTypeLongId>> {
match db.lookup_intern_concrete_type(concrete_type_id) {
SierraGeneratorTypeLongId::Regular(long_id) => Ok(long_id),
SierraGeneratorTypeLongId::CycleBreaker(type_id) => db.get_concrete_long_type_id(type_id),
SierraGeneratorTypeLongId::Phantom(type_id)
| SierraGeneratorTypeLongId::CycleBreaker(type_id) => db.get_concrete_long_type_id(type_id),
}
}
3 changes: 2 additions & 1 deletion crates/cairo-lang-sierra-generator/src/replace_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ impl SierraIdReplacer for DebugReplacer<'_> {
id: &cairo_lang_sierra::ids::ConcreteTypeId,
) -> cairo_lang_sierra::ids::ConcreteTypeId {
match self.db.lookup_intern_concrete_type(id.clone()) {
SierraGeneratorTypeLongId::CycleBreaker(ty) => ty.format(self.db.upcast()).into(),
SierraGeneratorTypeLongId::Phantom(ty)
| SierraGeneratorTypeLongId::CycleBreaker(ty) => ty.format(self.db.upcast()).into(),
SierraGeneratorTypeLongId::Regular(long_id) => {
let mut long_id = long_id.as_ref().clone();
self.replace_generic_args(&mut long_id.generic_args);
Expand Down
7 changes: 7 additions & 0 deletions crates/cairo-lang-sierra-generator/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ pub fn get_concrete_type_id(
) if db.is_self_referential(type_id)? => {
Ok(db.intern_concrete_type(SierraGeneratorTypeLongId::CycleBreaker(type_id)))
}

semantic::TypeLongId::Concrete(concrete_type_id)
if concrete_type_id.is_phantom(db.upcast())? =>
{
Ok(db.intern_concrete_type(SierraGeneratorTypeLongId::Phantom(type_id)))
}

_ => Ok(db.intern_concrete_type(SierraGeneratorTypeLongId::Regular(
db.get_concrete_long_type_id(type_id)?,
))),
Expand Down

0 comments on commit 997a731

Please sign in to comment.