diff --git a/examples/sizes.txt b/examples/sizes.txt index a6ca214e45..0fbd989753 100644 --- a/examples/sizes.txt +++ b/examples/sizes.txt @@ -5,7 +5,7 @@ arc-28/EventEmitter 117 77 40 77 0 arc4_numeric_comparisons/UIntNOrdering 1220 908 312 908 0 arc4_types/Arc4Arrays 588 376 212 376 0 - arc4_types/Arc4BoolEval 731 19 712 19 0 + arc4_types/Arc4BoolEval 741 19 722 19 0 arc4_types/Arc4BoolType 329 57 272 57 0 arc4_types/Arc4DynamicBytes 247 128 119 128 0 arc4_types/Arc4DynamicStringArray 230 112 118 112 0 diff --git a/src/puya/awst_build/eb/arc4/bool.py b/src/puya/awst_build/eb/arc4/bool.py index f8c6df83d8..4d836a9aff 100644 --- a/src/puya/awst_build/eb/arc4/bool.py +++ b/src/puya/awst_build/eb/arc4/bool.py @@ -5,10 +5,7 @@ import structlog from puya.awst import wtypes -from puya.awst.nodes import ( - ARC4Encode, - Literal, -) +from puya.awst.nodes import ARC4Encode, BoolConstant, Expression, Literal from puya.awst_build.eb.arc4.base import ( ARC4ClassExpressionBuilder, ARC4EncodedExpressionBuilder, @@ -43,18 +40,21 @@ def call( location: SourceLocation, ) -> ExpressionBuilder: match args: + case []: + native_bool: Expression = BoolConstant(value=False, source_location=location) case [val]: - return var_expression( - ARC4Encode( - value=expect_operand_wtype(val, wtypes.bool_wtype), - source_location=location, - wtype=self.produces(), - ) - ) + native_bool = expect_operand_wtype(val, wtypes.bool_wtype) case _: raise CodeError( f"arc4.Bool expects exactly one parameter of type {wtypes.bool_wtype}" ) + return var_expression( + ARC4Encode( + value=native_bool, + source_location=location, + wtype=self.produces(), + ) + ) class ARC4BoolExpressionBuilder(ARC4EncodedExpressionBuilder): diff --git a/src/puyapy-stubs/arc4.pyi b/src/puyapy-stubs/arc4.pyi index e4beec4875..ce4e8b04ba 100644 --- a/src/puyapy-stubs/arc4.pyi +++ b/src/puyapy-stubs/arc4.pyi @@ -216,7 +216,7 @@ UInt512: typing.TypeAlias = BigUIntN[typing.Literal[512]] class Bool(_ABIEncoded): """An ARC4 encoded bool""" - def __init__(self, value: bool) -> None: ... # noqa: FBT001 + def __init__(self, value: bool = False, /) -> None: ... # noqa: FBT001 @property def native(self) -> bool: """Return the bool representation of the value after ARC4 decoding""" diff --git a/test_cases/arc4_types/bool_eval.py b/test_cases/arc4_types/bool_eval.py index ee2bad2ce8..1ce3ee67d0 100644 --- a/test_cases/arc4_types/bool_eval.py +++ b/test_cases/arc4_types/bool_eval.py @@ -67,6 +67,8 @@ def approval_program(self) -> bool: assert arc4.Tuple((arc4.Bool(False),)) + assert arc4.Bool() == arc4.Bool(False) + return True def clear_state_program(self) -> bool: diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.approval.mir b/test_cases/arc4_types/out/Arc4BoolEvalContract.approval.mir index 2a6187f5a2..f95ad17731 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.approval.mir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.approval.mir @@ -24,6 +24,6 @@ main_block@0: // virtual: store tmp%11#0 to l-stack (no copy) tmp%11#0 arc4.Address(Txn.sender) arc4_types/bool_eval.py:20 // virtual: load tmp%11#0 from l-stack (no copy) tmp%11#0 assert arc4.Address(Txn.sender) arc4_types/bool_eval.py:20 assert // assert arc4.Address(Txn.sender) arc4_types/bool_eval.py:20 - int 1 // 1 True arc4_types/bool_eval.py:70 - return // return True arc4_types/bool_eval.py:70 + int 1 // 1 True arc4_types/bool_eval.py:72 + return // return True arc4_types/bool_eval.py:72 diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.approval.teal b/test_cases/arc4_types/out/Arc4BoolEvalContract.approval.teal index 2ffff11432..be7bfba9d0 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.approval.teal +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.approval.teal @@ -13,7 +13,7 @@ test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program: global ZeroAddress != assert - // arc4_types/bool_eval.py:70 + // arc4_types/bool_eval.py:72 // return True int 1 return diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.clear.mir b/test_cases/arc4_types/out/Arc4BoolEvalContract.clear.mir index 753a8aa878..8cbd64c640 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.clear.mir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.clear.mir @@ -4,6 +4,6 @@ // test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: main_block@0: - int 1 // 1 True arc4_types/bool_eval.py:73 - return // return True arc4_types/bool_eval.py:73 + int 1 // 1 True arc4_types/bool_eval.py:75 + return // return True arc4_types/bool_eval.py:75 diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.clear.teal b/test_cases/arc4_types/out/Arc4BoolEvalContract.clear.teal index 7fedf3e7bd..57fcc16185 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.clear.teal +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program: - // arc4_types/bool_eval.py:73 + // arc4_types/bool_eval.py:75 // return True int 1 return diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.destructured.ir b/test_cases/arc4_types/out/Arc4BoolEvalContract.destructured.ir index 8bed4994f1..9263a3a5c3 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.destructured.ir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.destructured.ir @@ -14,5 +14,5 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.ir b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.ir index 98b28cd3ff..2fbf0cb52a 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.ir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.ir @@ -79,9 +79,13 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: let dynamic_arr#1: bytes = concat_result%42#0 let tmp%43#0: uint64 = (!= dynamic_arr#1 0x0000) (assert tmp%43#0) + let tmp%44#0: any = (setbit 0x00 0u 0u) + let tmp%45#0: any = (setbit 0x00 0u 0u) + let tmp%46#0: uint64 = (== tmp%44#0 tmp%45#0) + (assert tmp%46#0) return 1u program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_1.ir b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_1.ir index e46dc81017..05f1bfbdbd 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_1.ir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_1.ir @@ -76,9 +76,13 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: let dynamic_arr#1: bytes = (concat len_16_bit%41#0 concatenated%37#0) let tmp%43#0: uint64 = (!= dynamic_arr#1 0x0000) (assert tmp%43#0) + let tmp%44#0: any = 0x00 + let tmp%45#0: any = 0x00 + let tmp%46#0: uint64 = (== tmp%44#0 tmp%45#0) + (assert tmp%46#0) return 1u program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_2.ir b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_2.ir index 2814f2f06c..30e7b24fe1 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_2.ir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_2.ir @@ -22,9 +22,11 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: let dynamic_arr#1: bytes = (concat len_16_bit%41#0 concatenated%37#0) let tmp%43#0: uint64 = (!= dynamic_arr#1 0x0000) (assert tmp%43#0) + let tmp%46#0: uint64 = 1u + (assert tmp%46#0) return 1u program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_3.ir b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_3.ir index cec49b1096..6149d3b749 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_3.ir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_3.ir @@ -21,5 +21,5 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_4.ir b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_4.ir index bf086f7103..a1ea59f4ef 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_4.ir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_4.ir @@ -20,5 +20,5 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_5.ir b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_5.ir index 08c7e99608..e273bc76b3 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_5.ir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_5.ir @@ -18,5 +18,5 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_6.ir b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_6.ir index c5a7a545e6..5709c24851 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_6.ir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_6.ir @@ -17,5 +17,5 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_7.ir b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_7.ir index 0d980c8ced..933a4ad52d 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_7.ir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_7.ir @@ -16,5 +16,5 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_8.ir b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_8.ir index 8bed4994f1..9263a3a5c3 100644 --- a/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_8.ir +++ b/test_cases/arc4_types/out/Arc4BoolEvalContract.ssa.opt_pass_8.ir @@ -14,5 +14,5 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/out/bool_eval.awst b/test_cases/arc4_types/out/bool_eval.awst index c3e4d5f58f..10492ef8af 100644 --- a/test_cases/arc4_types/out/bool_eval.awst +++ b/test_cases/arc4_types/out/bool_eval.awst @@ -44,6 +44,7 @@ contract Arc4BoolEvalContract assert(reinterpret_cast(dynamic_arr) != hex<"0000">) assert(true) assert(true) + assert(reinterpret_cast(arc4_encode(false, puyapy.arc4.Bool)) == reinterpret_cast(arc4_encode(false, puyapy.arc4.Bool))) return true } diff --git a/test_cases/arc4_types/out_O2/Arc4BoolEvalContract.destructured.ir b/test_cases/arc4_types/out_O2/Arc4BoolEvalContract.destructured.ir index 8bed4994f1..9263a3a5c3 100644 --- a/test_cases/arc4_types/out_O2/Arc4BoolEvalContract.destructured.ir +++ b/test_cases/arc4_types/out_O2/Arc4BoolEvalContract.destructured.ir @@ -14,5 +14,5 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.approval.teal b/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.approval.teal index e71fdcdf2a..0f589c1ffc 100644 --- a/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.approval.teal +++ b/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.approval.teal @@ -205,6 +205,18 @@ test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program: != assert // arc4_types/bool_eval.py:70 + // assert arc4.Bool() == arc4.Bool(False) + byte 0x00 + int 0 + int 0 + setbit + byte 0x00 + int 0 + int 0 + setbit + == + assert + // arc4_types/bool_eval.py:72 // return True int 1 return diff --git a/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.clear.teal b/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.clear.teal index 7fedf3e7bd..57fcc16185 100644 --- a/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.clear.teal +++ b/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program: - // arc4_types/bool_eval.py:73 + // arc4_types/bool_eval.py:75 // return True int 1 return diff --git a/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.destructured.ir b/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.destructured.ir index 4e85a1078c..e8aebf1e47 100644 --- a/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.destructured.ir +++ b/test_cases/arc4_types/out_unoptimized/Arc4BoolEvalContract.destructured.ir @@ -79,9 +79,13 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract: let dynamic_arr#0: bytes = concat_result%42#0 let tmp%43#0: uint64 = (!= dynamic_arr#0 0x0000) (assert tmp%43#0) + let tmp%44#0: any = (setbit 0x00 0u 0u) + let tmp%45#0: any = (setbit 0x00 0u 0u) + let tmp%46#0: uint64 = (== tmp%44#0 tmp%45#0) + (assert tmp%46#0) return 1u program clear-state: subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program() -> uint64: - block@0: // L72 + block@0: // L74 return 1u \ No newline at end of file diff --git a/test_cases/arc4_types/puya.log b/test_cases/arc4_types/puya.log index 76227bcbf3..b9b5811646 100644 --- a/test_cases/arc4_types/puya.log +++ b/test_cases/arc4_types/puya.log @@ -437,8 +437,8 @@ arc4_types/bool_eval.py:59:9 warning: assertion is always true, ignoring arc4_types/bool_eval.py:66:9 warning: assertion is always true, ignoring arc4_types/bool_eval.py:68:9 warning: assertion is always true, ignoring debug: Terminated block@0: // L12 -debug: Sealing block@0: // L72 -debug: Terminated block@0: // L72 +debug: Sealing block@0: // L74 +debug: Terminated block@0: // L74 debug: Sealing block@0: // L10 debug: Terminated block@0: // L10 debug: Looking for 'item_index_internal%6' in an unsealed block creating an incomplete Phi: block@1: // for_header_L16 @@ -2499,6 +2499,8 @@ debug: Simplified (!= 0x00000000000000000000000000000000000000000000000000000000 debug: Simplified (== 0x0000 0x0000) to 1u debug: Simplified ((extract 2 0) 0x0000) to 0x debug: Simplified (concat 0x 0x0000000000000000) to 0x0000000000000000 +debug: Simplified (setbit 0x00 0u 0u) to 0x00 +debug: Simplified (setbit 0x00 0u 0u) to 0x00 debug: Optimizer: Remove Unused Variables debug: Removing unused variable dynamic_arr#0 debug: Removing unused variable data%36#0 @@ -2527,6 +2529,7 @@ debug: Optimizer: Intrinsic Simplifier debug: Simplified (== 0x00 0x00) to 1u debug: Simplified (!= 0x80 0x00) to 1u debug: Simplified (concat 0x 0x0000000000000000) to 0x0000000000000000 +debug: Simplified (== 0x00 0x00) to 1u debug: Optimizer: Remove Unused Variables debug: Removing unused variable tmp%0#0 debug: Removing unused variable tmp%2#0 @@ -2557,6 +2560,8 @@ debug: Removing unused variable tmp%33#0 debug: Removing unused variable tmp%34#0 debug: Removing unused variable expr_value_trimmed%35#0 debug: Removing unused variable data%36#1 +debug: Removing unused variable tmp%44#0 +debug: Removing unused variable tmp%45#0 debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump debug: Optimizer: Remove Empty Blocks @@ -2583,6 +2588,7 @@ debug: Optimizer: Remove Unused Variables debug: Removing unused variable tmp%1#0 debug: Removing unused variable tmp%3#0 debug: Removing unused variable concatenated%37#0 +debug: Removing unused variable tmp%46#0 debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump debug: Optimizer: Remove Empty Blocks