Skip to content

Commit

Permalink
fix: public constant arrays (#3536)
Browse files Browse the repository at this point in the history
public getters for arrays would panic at codegen because type
information for the array members was not available. this is because
type annotation would occur before getter expansion. this commit moves
the type annotation phase to right before getter expansion, so that the
generated ast nodes will get annotated.

it also fixes a small bug when trying to deepcopy the nodes generated by
ast expansion - the generated nodes have no node_id and raise an
exception when deepcopy tries to perform `__eq__` between two of the
generated FunctionDefs.
  • Loading branch information
charles-cooper authored Jul 25, 2023
1 parent d48438e commit 2f39e69
Show file tree
Hide file tree
Showing 5 changed files with 6 additions and 3 deletions.
2 changes: 2 additions & 0 deletions tests/parser/globals/test_getters.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def test_getter_code(get_contract_with_gas_estimation_for_constants):
c: public(constant(uint256)) = 1
d: public(immutable(uint256))
e: public(immutable(uint256[2]))
f: public(constant(uint256[2])) = [3, 7]
@external
def __init__():
Expand Down Expand Up @@ -68,6 +69,7 @@ def __init__():
assert c.c() == 1
assert c.d() == 1729
assert c.e(0) == 2
assert [c.f(i) for i in range(2)] == [3, 7]


def test_getter_mutability(get_contract):
Expand Down
1 change: 0 additions & 1 deletion vyper/ast/expansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ def generate_public_variable_getters(vyper_module: vy_ast.Module) -> None:
# the base return statement is an `Attribute` node, e.g. `self.<var_name>`
# for each input type we wrap it in a `Subscript` to access a specific member
return_stmt = vy_ast.Attribute(value=vy_ast.Name(id="self"), attr=func_type.name)
return_stmt._metadata["type"] = node._metadata["type"]

for i, type_ in enumerate(input_types):
if not isinstance(annotation, vy_ast.Subscript):
Expand Down
2 changes: 1 addition & 1 deletion vyper/ast/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ def __hash__(self):
def __eq__(self, other):
if not isinstance(other, type(self)):
return False
if other.node_id != self.node_id:
if getattr(other, "node_id", None) != getattr(self, "node_id", None):
return False
for field_name in (i for i in self.get_fields() if i not in VyperNode.__slots__):
if getattr(self, field_name, None) != getattr(other, field_name, None):
Expand Down
1 change: 0 additions & 1 deletion vyper/compiler/phases.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ def generate_folded_ast(
vyper_module_folded = copy.deepcopy(vyper_module)
vy_ast.folding.fold(vyper_module_folded)
validate_semantics(vyper_module_folded, interface_codes)
vy_ast.expansion.expand_annotated_ast(vyper_module_folded)
symbol_tables = set_data_positions(vyper_module_folded, storage_layout_overrides)

return vyper_module_folded, symbol_tables
Expand Down
3 changes: 3 additions & 0 deletions vyper/semantics/analysis/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import vyper.ast as vy_ast

from .. import types # break a dependency cycle.
from ..namespace import get_namespace
from .local import validate_functions
Expand All @@ -11,4 +13,5 @@ def validate_semantics(vyper_ast, interface_codes):

with namespace.enter_scope():
add_module_namespace(vyper_ast, interface_codes)
vy_ast.expansion.expand_annotated_ast(vyper_ast)
validate_functions(vyper_ast)

0 comments on commit 2f39e69

Please sign in to comment.