Skip to content

Commit

Permalink
Add phantom attribute. (#5381)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyalesokhin-starkware authored Apr 9, 2024
1 parent f0858e6 commit e375707
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 1 deletion.
3 changes: 2 additions & 1 deletion crates/cairo-lang-defs/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use cairo_lang_filesystem::ids::{CrateId, Directory, FileId, FileKind, FileLongI
use cairo_lang_parser::db::ParserGroup;
use cairo_lang_syntax::attribute::consts::{
FEATURE_ATTR, FMT_SKIP_ATTR, IMPLICIT_PRECEDENCE_ATTR, INLINE_ATTR, MUST_USE_ATTR,
STARKNET_INTERFACE_ATTR, UNSTABLE_ATTR,
PHANTOM_ATTR, STARKNET_INTERFACE_ATTR, UNSTABLE_ATTR,
};
use cairo_lang_syntax::node::ast::MaybeModuleBody;
use cairo_lang_syntax::node::db::SyntaxGroup;
Expand Down Expand Up @@ -227,6 +227,7 @@ fn allowed_attributes(db: &dyn DefsGroup) -> Arc<OrderedHashSet<String>> {
MUST_USE_ATTR.into(),
UNSTABLE_ATTR.into(),
FEATURE_ATTR.into(),
PHANTOM_ATTR.into(),
IMPLICIT_PRECEDENCE_ATTR.into(),
FMT_SKIP_ATTR.into(),
// TODO(orizi): Remove this once `starknet` is removed from corelib.
Expand Down
4 changes: 4 additions & 0 deletions crates/cairo-lang-semantic/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,9 @@ impl DiagnosticEntry for SemanticDiagnostic {
SemanticDiagnosticKind::SelfMustBeFirst => {
"`Self` can only be the first segment of a path.".into()
}
SemanticDiagnosticKind::CannotCreateInstancesOfPhantomTypes => {
"Can not create instances of phantom types.".into()
}
}
}

Expand Down Expand Up @@ -817,6 +820,7 @@ pub enum SemanticDiagnosticKind {
},
UnexpectedGenericArgs,
UnknownMember,
CannotCreateInstancesOfPhantomTypes,
MemberSpecifiedMoreThanOnce,
StructBaseStructExpressionNotLast,
StructBaseStructExpressionNoEffect,
Expand Down
9 changes: 9 additions & 0 deletions crates/cairo-lang-semantic/src/expr/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use cairo_lang_defs::ids::{
};
use cairo_lang_diagnostics::{DiagnosticAdded, Maybe, ToOption};
use cairo_lang_filesystem::ids::{FileKind, FileLongId, VirtualFile};
use cairo_lang_syntax::attribute::consts::PHANTOM_ATTR;
use cairo_lang_syntax::node::ast::{
BlockOrIf, ExprPtr, PatternListOr, PatternStructParam, UnaryOperator,
};
Expand Down Expand Up @@ -52,6 +53,7 @@ use crate::diagnostic::{
ElementKind, NotFoundItemType, SemanticDiagnostics, TraitInferenceErrors,
UnsupportedOutsideOfFunctionFeatureName,
};
use crate::items::attribute::SemanticQueryAttrs;
use crate::items::constant::ConstValue;
use crate::items::enm::SemanticEnumEx;
use crate::items::feature_kind::extract_item_allowed_features;
Expand Down Expand Up @@ -721,6 +723,9 @@ fn compute_expr_function_call_semantic(
return Err(diag_added);
}
let concrete_enum_id = concrete_variant.concrete_enum_id;
if concrete_enum_id.has_attr(db, PHANTOM_ATTR)? {
ctx.diagnostics.report(syntax, CannotCreateInstancesOfPhantomTypes);
}
Ok(semantic::Expr::EnumVariantCtor(semantic::ExprEnumVariantCtor {
variant: concrete_variant,
value_expr: arg.id,
Expand Down Expand Up @@ -1839,6 +1844,10 @@ fn struct_ctor_expr(
.and_then(|c| try_extract_matches!(c, ConcreteTypeId::Struct))
.ok_or_else(|| ctx.diagnostics.report(&path, NotAStruct))?;

if concrete_struct_id.has_attr(db, PHANTOM_ATTR)? {
ctx.diagnostics.report(ctor_syntax, CannotCreateInstancesOfPhantomTypes);
}

let members = db.concrete_struct_members(concrete_struct_id)?;
let mut member_exprs: OrderedHashMap<MemberId, Option<ExprId>> = OrderedHashMap::default();
let mut base_struct = None;
Expand Down
2 changes: 2 additions & 0 deletions crates/cairo-lang-semantic/src/expr/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ cairo_lang_test_utils::test_file_test!(
cairo_lang_test_utils::test_file_test!(
expr_diagnostics,
"src/expr/test_data",

{
assignment: "assignment",
attributes: "attributes",
constant: "constant",
constructor: "constructor",
coupon: "coupon",
Expand Down
33 changes: 33 additions & 0 deletions crates/cairo-lang-semantic/src/expr/test_data/attributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! > Test instantiation.

//! > test_runner_name
test_function_diagnostics(expect_diagnostics: true)

//! > function
fn foo() {
MyStruct {};
MyEnum::a(3);
}

//! > function_name
foo

//! > module_code
#[phantom]
struct MyStruct {}

#[phantom]
enum MyEnum {
a: felt252
}

//! > expected_diagnostics
error: Can not create instances of phantom types.
--> lib.cairo:9:5
MyStruct {};
^*********^

error: Can not create instances of phantom types.
--> lib.cairo:10:5
MyEnum::a(3);
^**********^
4 changes: 4 additions & 0 deletions crates/cairo-lang-syntax/src/attribute/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ pub const IMPLICIT_PRECEDENCE_ATTR: &str = "implicit_precedence";
/// corelib.
/// TODO(Gil): Remove this once `starknet` is removed from corelib.
pub const STARKNET_INTERFACE_ATTR: &str = "starknet::interface";

/// An attribute to define a type as a phantom type, phantom types cannot be created at run time and
/// are typically used for meta-programming.
pub const PHANTOM_ATTR: &str = "phantom";

0 comments on commit e375707

Please sign in to comment.