diff --git a/corelib/src/lib.cairo b/corelib/src/lib.cairo index 3c1de4a3a3f..700802e1f82 100644 --- a/corelib/src/lib.cairo +++ b/corelib/src/lib.cairo @@ -354,7 +354,7 @@ pub fn panic_with_felt252(err_code: felt252) -> never { /// assert(false, 'error message'); /// ``` #[inline] -pub fn assert(cond: bool, err_code: felt252) { +pub const fn assert(cond: bool, err_code: felt252) { if !cond { panic_with_felt252(err_code) } diff --git a/crates/cairo-lang-semantic/src/expr/test_data/constant b/crates/cairo-lang-semantic/src/expr/test_data/constant index cedd505165a..61de8ad3644 100644 --- a/crates/cairo-lang-semantic/src/expr/test_data/constant +++ b/crates/cairo-lang-semantic/src/expr/test_data/constant @@ -62,20 +62,14 @@ const FAILING_CALC: felt252 = if true { 70 }; -const FUNC_CALC_SUCCESS: () = panic_if_true(false); -const FUNC_CALC_FAILURE: () = panic_if_true(true); -const VALID_EQ: () = panic_if_true(1 == 2); -const VALID_NE: () = panic_if_true(1 != 1); -const VALID_LT: () = panic_if_true(1_usize < 1); -const VALID_LE: () = panic_if_true(2_usize <= 1); -const VALID_GT: () = panic_if_true(1_usize > 1); -const VALID_GE: () = panic_if_true(1_usize >= 2); - -const fn panic_if_true(cond: bool) { - if cond { - core::panic_with_felt252('assertion failed') - } -} +const FUNC_CALC_SUCCESS: () = assert(true, 'works'); +const FUNC_CALC_FAILURE: () = assert(false, 'does not work'); +const VALID_EQ: () = assert(1 == 1, '1 == 1'); +const VALID_NE: () = assert(1 != 2, '1 != 1'); +const VALID_LT: () = assert(1_usize < 2, '1 < 2'); +const VALID_LE: () = assert(1_usize <= 1, '1 <= 1'); +const VALID_GT: () = assert(2_usize > 1, '2 > 1'); +const VALID_GE: () = assert(1_usize >= 1, '1 >= 1'); const FUNC_CALC_SUCCESS_OPTION: felt252 = Option::Some(5).unwrap(); const FUNC_CALC_FAILURE_OPTION: felt252 = Option::None.unwrap(); @@ -123,15 +117,15 @@ error: Failed to calculate constant. error: Failed to calculate constant. --> lib.cairo:23:31 -const FUNC_CALC_FAILURE: () = panic_if_true(true); - ^^^^^^^^^^^^^^^^^^^ -note: In `test::panic_if_true`: - --> lib.cairo:33:9 - core::panic_with_felt252('assertion failed') - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +const FUNC_CALC_FAILURE: () = assert(false, 'does not work'); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: In `core::assert`: + --> /home/ori/rust/cairo-ws/corelib/src/lib.cairo:359:9 + panic_with_felt252(err_code) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Failed to calculate constant. - --> lib.cairo:38:43 + --> lib.cairo:32:43 const FUNC_CALC_FAILURE_OPTION: felt252 = Option::None.unwrap(); ^^^^^^^^^^^^^^^^^^^^^ note: In `core::option::OptionTraitImpl::::expect`: @@ -144,7 +138,7 @@ note: In `core::option::OptionTraitImpl::::unwrap`: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Failed to calculate constant. - --> lib.cairo:40:44 + --> lib.cairo:34:44 const FUNC_CALC_FAILURE_RESULT1: felt252 = Result::Err(5).unwrap(); ^^^^^^^^^^^^^^^^^^^^^^^ note: In `core::result::ResultTraitImpl::::expect::>>`: @@ -157,7 +151,7 @@ note: In `core::result::ResultTraitImpl::::unwrap: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Failed to calculate constant. - --> lib.cairo:42:44 + --> lib.cairo:36:44 const FUNC_CALC_FAILURE_RESULT2: felt252 = Result::Ok(5).unwrap_err(); ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: In `core::result::ResultTraitImpl::::expect_err::<+PanicDestruct>`: @@ -170,7 +164,7 @@ note: In `core::result::ResultTraitImpl::::unwrap_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Constant calculation depth exceeded. - --> lib.cairo:44:43 + --> lib.cairo:38:43 const FUNC_CALC_STACK_EXCEEDED: felt252 = call_myself(); ^^^^^^^^^^^^^ diff --git a/crates/cairo-lang-semantic/src/items/constant.rs b/crates/cairo-lang-semantic/src/items/constant.rs index 82cc6e8230e..ed6ef9d022d 100644 --- a/crates/cairo-lang-semantic/src/items/constant.rs +++ b/crates/cairo-lang-semantic/src/items/constant.rs @@ -762,7 +762,7 @@ impl ConstantEvaluateContext<'_> { } else if let Some(else_block) = expr.else_block { self.evaluate(else_block) } else { - ConstValue::Struct(vec![], unit_ty(self.db)) + self.unit_const.clone() } } crate::Condition::Let(id, patterns) => { @@ -786,7 +786,7 @@ impl ConstantEvaluateContext<'_> { if let Some(else_block) = expr.else_block { self.evaluate(else_block) } else { - ConstValue::Struct(vec![], unit_ty(self.db)) + self.unit_const.clone() } } }, @@ -822,16 +822,15 @@ impl ConstantEvaluateContext<'_> { let imp = extract_matches!(concrete_function.generic_function, GenericFunctionId::Impl); let bool_value = |condition: bool| { - ConstValue::Enum( - if condition { true_variant(db) } else { false_variant(db) }, - ConstValue::Struct(vec![], unit_ty(db)).into(), - ) + if condition { self.true_const.clone() } else { self.false_const.clone() } }; if imp.function == self.eq_fn { return bool_value(args[0] == args[1]); } else if imp.function == self.ne_fn { return bool_value(args[0] != args[1]); + } else if imp.function == self.not_fn { + return bool_value(args[0] == self.false_const); } let args = match args @@ -1123,42 +1122,50 @@ pub struct ConstCalcInfo { /// Traits that are allowed for consts if their impls is in the corelib. const_traits: UnorderedHashSet, /// The trait function for `Neg::neg`. - pub neg_fn: TraitFunctionId, + neg_fn: TraitFunctionId, /// The trait function for `Add::add`. - pub add_fn: TraitFunctionId, + add_fn: TraitFunctionId, /// The trait function for `Sub::sub`. - pub sub_fn: TraitFunctionId, + sub_fn: TraitFunctionId, /// The trait function for `Mul::mul`. - pub mul_fn: TraitFunctionId, + mul_fn: TraitFunctionId, /// The trait function for `Div::div`. - pub div_fn: TraitFunctionId, + div_fn: TraitFunctionId, /// The trait function for `Rem::rem`. - pub rem_fn: TraitFunctionId, + rem_fn: TraitFunctionId, /// The trait function for `BitAnd::bitand`. - pub bit_and_fn: TraitFunctionId, + bit_and_fn: TraitFunctionId, /// The trait function for `BitOr::bitor`. - pub bit_or_fn: TraitFunctionId, + bit_or_fn: TraitFunctionId, /// The trait function for `BitXor::bitxor`. - pub bit_xor_fn: TraitFunctionId, + bit_xor_fn: TraitFunctionId, /// The trait function for `PartialEq::eq`. - pub eq_fn: TraitFunctionId, + eq_fn: TraitFunctionId, /// The trait function for `PartialEq::ne`. - pub ne_fn: TraitFunctionId, + ne_fn: TraitFunctionId, /// The trait function for `PartialOrd::lt`. - pub lt_fn: TraitFunctionId, + lt_fn: TraitFunctionId, /// The trait function for `PartialOrd::le`. - pub le_fn: TraitFunctionId, + le_fn: TraitFunctionId, /// The trait function for `PartialOrd::gt`. - pub gt_fn: TraitFunctionId, + gt_fn: TraitFunctionId, /// The trait function for `PartialOrd::ge`. - pub ge_fn: TraitFunctionId, + ge_fn: TraitFunctionId, + /// The trait function for `Not::not`. + not_fn: TraitFunctionId, + /// The const value for the unit type `()`. + unit_const: ConstValue, + /// The const value for `true`. + true_const: ConstValue, + /// The const value for `false`. + false_const: ConstValue, /// The function for panicking with a felt252. - pub panic_with_felt252: FunctionId, + panic_with_felt252: FunctionId, } impl ConstCalcInfo { /// Creates a new ConstCalcInfo. - pub fn new(db: &dyn SemanticGroup) -> Self { + fn new(db: &dyn SemanticGroup) -> Self { let neg_trait = get_core_trait(db, CoreTraitContext::TopLevel, "Neg".into()); let add_trait = get_core_trait(db, CoreTraitContext::TopLevel, "Add".into()); let sub_trait = get_core_trait(db, CoreTraitContext::TopLevel, "Sub".into()); @@ -1170,9 +1177,11 @@ impl ConstCalcInfo { let bit_xor_trait = get_core_trait(db, CoreTraitContext::TopLevel, "BitXor".into()); let partial_eq_trait = get_core_trait(db, CoreTraitContext::TopLevel, "PartialEq".into()); let partial_ord_trait = get_core_trait(db, CoreTraitContext::TopLevel, "PartialOrd".into()); + let not_trait = get_core_trait(db, CoreTraitContext::TopLevel, "Not".into()); let trait_fn = |trait_id, name: &str| { db.trait_function_by_name(trait_id, name.into()).unwrap().unwrap() }; + let unit_const = ConstValue::Struct(vec![], unit_ty(db)); Self { const_traits: [ neg_trait, @@ -1186,6 +1195,7 @@ impl ConstCalcInfo { bit_xor_trait, partial_eq_trait, partial_ord_trait, + not_trait, ] .into_iter() .collect(), @@ -1204,6 +1214,10 @@ impl ConstCalcInfo { le_fn: trait_fn(partial_ord_trait, "le"), gt_fn: trait_fn(partial_ord_trait, "gt"), ge_fn: trait_fn(partial_ord_trait, "ge"), + not_fn: trait_fn(not_trait, "not"), + true_const: ConstValue::Enum(true_variant(db), unit_const.clone().into()), + false_const: ConstValue::Enum(false_variant(db), unit_const.clone().into()), + unit_const, panic_with_felt252: get_core_function_id(db, "panic_with_felt252".into(), vec![]), } }