Skip to content

Commit

Permalink
fix[lang]: fix == and != bytesM folding (#4254)
Browse files Browse the repository at this point in the history
`bytesM` literals are not case-sensitive (they represent the same value
no matter if the literal is lower- or upper-case), but the folding
operation was case sensitive.

---------

Co-authored-by: Charles Cooper <[email protected]>
  • Loading branch information
trocher and charles-cooper committed Sep 26, 2024
1 parent 957c8ed commit d60d31f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
17 changes: 17 additions & 0 deletions tests/unit/ast/nodes/test_fold_compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,20 @@ def test_compare_type_mismatch(op):
old_node = vyper_ast.body[0].value
with pytest.raises(UnfoldableNode):
old_node.get_folded_value()


@pytest.mark.parametrize("op", ["==", "!="])
def test_compare_eq_bytes(get_contract, op):
left, right = "0xA1AAB33F", "0xa1aab33f"
source = f"""
@external
def foo(a: bytes4, b: bytes4) -> bool:
return a {op} b
"""
contract = get_contract(source)

vyper_ast = parse_and_fold(f"{left} {op} {right}")
old_node = vyper_ast.body[0].value
new_node = old_node.get_folded_value()

assert contract.foo(left, right) == new_node.value
7 changes: 5 additions & 2 deletions vyper/semantics/analysis/constant_folding.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,11 @@ def visit_Compare(self, node):
raise UnfoldableNode(
f"Invalid literal types for {node.op.description} comparison", node
)

value = node.op._op(left.value, right.value)
lvalue, rvalue = left.value, right.value
if isinstance(left, vy_ast.Hex):
# Hex values are str, convert to be case-unsensitive.
lvalue, rvalue = lvalue.lower(), rvalue.lower()
value = node.op._op(lvalue, rvalue)
return vy_ast.NameConstant.from_node(node, value=value)

def visit_List(self, node) -> vy_ast.ExprNode:
Expand Down

0 comments on commit d60d31f

Please sign in to comment.