From 90e8dbffc35c1df2323a9b7d0d3de106c79457c1 Mon Sep 17 00:00:00 2001 From: Ori Ziv Date: Wed, 1 Jan 2025 19:15:58 +0200 Subject: [PATCH] Added support for basic panic in const calculation. commit-id:3405e803 --- crates/cairo-lang-semantic/src/corelib.rs | 57 +++++++++++++++++++ crates/cairo-lang-semantic/src/diagnostic.rs | 4 ++ .../src/expr/test_data/constant | 11 ++++ .../cairo-lang-semantic/src/items/constant.rs | 17 +++++- 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/crates/cairo-lang-semantic/src/corelib.rs b/crates/cairo-lang-semantic/src/corelib.rs index c023830e9f6..fd996d065a0 100644 --- a/crates/cairo-lang-semantic/src/corelib.rs +++ b/crates/cairo-lang-semantic/src/corelib.rs @@ -256,6 +256,63 @@ pub fn option_none_variant(db: &dyn SemanticGroup, ty: TypeId) -> ConcreteVarian ) } +/// Generates a ConcreteVariant instance for `Result::Ok`. +pub fn result_ok_variant(db: &dyn SemanticGroup, ok_ty: TypeId, err_ty: TypeId) -> ConcreteVariant { + get_enum_concrete_variant( + db, + core_submodule(db, "result"), + "Result", + vec![GenericArgumentId::Type(ok_ty), GenericArgumentId::Type(err_ty)], + "Ok", + ) +} + +/// Generates a ConcreteVariant instance for `Result::Err`. +pub fn result_err_variant( + db: &dyn SemanticGroup, + ok_ty: TypeId, + err_ty: TypeId, +) -> ConcreteVariant { + get_enum_concrete_variant( + db, + core_submodule(db, "result"), + "Result", + vec![GenericArgumentId::Type(ok_ty), GenericArgumentId::Type(err_ty)], + "Err", + ) +} + +/// Generates a ConcreteVariant instance for `SignedIntegerResult::InRange`. +pub fn signed_int_result_in_range_variant(db: &dyn SemanticGroup, ty: TypeId) -> ConcreteVariant { + get_enum_concrete_variant( + db, + core_submodule(db, "integer"), + "SignedIntegerResult", + vec![GenericArgumentId::Type(ty)], + "InRange", + ) +} +/// Generates a ConcreteVariant instance for `SignedIntegerResult::Underflow`. +pub fn signed_int_result_underflow_variant(db: &dyn SemanticGroup, ty: TypeId) -> ConcreteVariant { + get_enum_concrete_variant( + db, + core_submodule(db, "integer"), + "SignedIntegerResult", + vec![GenericArgumentId::Type(ty)], + "Underflow", + ) +} +/// Generates a ConcreteVariant instance for `SignedIntegerResult::Overflow`. +pub fn signed_int_result_overflow_variant(db: &dyn SemanticGroup, ty: TypeId) -> ConcreteVariant { + get_enum_concrete_variant( + db, + core_submodule(db, "integer"), + "SignedIntegerResult", + vec![GenericArgumentId::Type(ty)], + "Overflow", + ) +} + /// Gets a semantic expression of the literal `false`. Uses the given `stable_ptr` in the returned /// semantic expression. pub fn false_literal_expr( diff --git a/crates/cairo-lang-semantic/src/diagnostic.rs b/crates/cairo-lang-semantic/src/diagnostic.rs index 76729327c1d..d65e8a378c3 100644 --- a/crates/cairo-lang-semantic/src/diagnostic.rs +++ b/crates/cairo-lang-semantic/src/diagnostic.rs @@ -738,6 +738,9 @@ impl DiagnosticEntry for SemanticDiagnostic { SemanticDiagnosticKind::UnsupportedConstant => { "This expression is not supported as constant.".into() } + SemanticDiagnosticKind::FailedConstantCalculation => { + "Failed to calculate constant.".into() + } SemanticDiagnosticKind::DivisionByZero => "Division by zero.".into(), SemanticDiagnosticKind::ExternTypeWithImplGenericsNotSupported => { "Extern types with impl generics are not supported.".into() @@ -1309,6 +1312,7 @@ pub enum SemanticDiagnosticKind { }, UnsupportedOutsideOfFunction(UnsupportedOutsideOfFunctionFeatureName), UnsupportedConstant, + FailedConstantCalculation, DivisionByZero, ExternTypeWithImplGenericsNotSupported, MissingSemicolon, diff --git a/crates/cairo-lang-semantic/src/expr/test_data/constant b/crates/cairo-lang-semantic/src/expr/test_data/constant index 80bb4a42a2e..6cdbf673778 100644 --- a/crates/cairo-lang-semantic/src/expr/test_data/constant +++ b/crates/cairo-lang-semantic/src/expr/test_data/constant @@ -56,6 +56,12 @@ impl Felt252Div of Div { } const CALCULATION_NOT_CORELIB_IMPL: felt252 = 8 / 4; +const FAILING_CALC: felt252 = if true { + core::panic_with_felt252('this should fail') +} else { + 70 +}; + //! > expected_diagnostics error: Type not found. --> lib.cairo:1:17 @@ -82,6 +88,11 @@ error: This expression is not supported as constant. const CALCULATION_NOT_CORELIB_IMPL: felt252 = 8 / 4; ^^^^^ +error: Failed to calculate constant. + --> lib.cairo:17:5 + core::panic_with_felt252('this should fail') + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + //! > ========================================================================== //! > Const of wrong type. diff --git a/crates/cairo-lang-semantic/src/items/constant.rs b/crates/cairo-lang-semantic/src/items/constant.rs index ea50ea34f1d..1d62546bf05 100644 --- a/crates/cairo-lang-semantic/src/items/constant.rs +++ b/crates/cairo-lang-semantic/src/items/constant.rs @@ -23,8 +23,9 @@ use smol_str::SmolStr; use super::functions::{GenericFunctionId, GenericFunctionWithBodyId}; use super::imp::ImplId; use crate::corelib::{ - CoreTraitContext, LiteralError, core_box_ty, core_nonzero_ty, false_variant, get_core_trait, - get_core_ty_by_name, true_variant, try_extract_nz_wrapped_type, unit_ty, validate_literal, + CoreTraitContext, LiteralError, core_box_ty, core_nonzero_ty, false_variant, + get_core_function_id, get_core_trait, get_core_ty_by_name, true_variant, + try_extract_nz_wrapped_type, unit_ty, validate_literal, }; use crate::db::SemanticGroup; use crate::diagnostic::{SemanticDiagnosticKind, SemanticDiagnostics, SemanticDiagnosticsBuilder}; @@ -582,6 +583,9 @@ impl ConstantEvaluateContext<'_> { /// Returns true if the given function is allowed to be called in constant context. fn is_function_const(&self, function_id: FunctionId) -> bool { + if function_id == self.panic_with_felt252 { + return true; + } let db = self.db; let concrete_function = function_id.get_concrete(db); let Ok(Some(body)) = concrete_function.body(db) else { return false }; @@ -820,6 +824,12 @@ impl ConstantEvaluateContext<'_> { Ok(args) => args, Err(err) => return ConstValue::Missing(err), }; + if expr.function == self.panic_with_felt252 { + return ConstValue::Missing(self.diagnostics.report( + expr.stable_ptr.untyped(), + SemanticDiagnosticKind::FailedConstantCalculation, + )); + } let imp = extract_matches!( expr.function.get_concrete(db.upcast()).generic_function, @@ -1035,6 +1045,8 @@ pub struct ConstCalcInfo { pub bit_or_trait: TraitId, /// The trait for bitwise xor. pub bit_xor_trait: TraitId, + /// The function for panicking with a felt252. + pub panic_with_felt252: FunctionId, } impl ConstCalcInfo { @@ -1050,6 +1062,7 @@ impl ConstCalcInfo { bit_and_trait: get_core_trait(db, CoreTraitContext::TopLevel, "BitAnd".into()), bit_or_trait: get_core_trait(db, CoreTraitContext::TopLevel, "BitOr".into()), bit_xor_trait: get_core_trait(db, CoreTraitContext::TopLevel, "BitXor".into()), + panic_with_felt252: get_core_function_id(db, "panic_with_felt252".into(), vec![]), } } }