Skip to content

Commit

Permalink
clean up index access
Browse files Browse the repository at this point in the history
  • Loading branch information
tserg committed Oct 23, 2023
1 parent 3eacf41 commit e2f1c8c
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 23 deletions.
17 changes: 17 additions & 0 deletions tests/parser/types/test_lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,23 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128:


def test_array_negative_accessor(get_contract_with_gas_estimation, assert_compile_failed):
array_negative_accessor = """
FOO: constant(int128) = -1
@external
def test_array(x: int128, y: int128, z: int128, w: int128) -> int128:
a: int128[4] = [0, 0, 0, 0]
a[0] = x
a[1] = y
a[2] = z
a[3] = w
return a[-4] * 1000 + a[-3] * 100 + a[-2] * 10 + a[FOO]
"""

assert_compile_failed(
lambda: get_contract_with_gas_estimation(array_negative_accessor), ArrayIndexException
)

array_negative_accessor = """
@external
def test_array(x: int128, y: int128, z: int128, w: int128) -> int128:
Expand Down
7 changes: 4 additions & 3 deletions vyper/semantics/types/subscriptable.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,11 @@ def validate_index_type(self, node):
# TODO break this cycle
from vyper.semantics.analysis.utils import validate_expected_type

if isinstance(node, vy_ast.Int):
if node.value < 0:
index_val = prefold(node)
if isinstance(index_val, int):
if index_val < 0:
raise ArrayIndexException("Vyper does not support negative indexing", node)
if node.value >= self.length:
if index_val >= self.length:
raise ArrayIndexException("Index out of range", node)

validate_expected_type(node, IntegerT.any())
Expand Down
21 changes: 1 addition & 20 deletions vyper/semantics/types/utils.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
from vyper import ast as vy_ast
from vyper.ast.pre_typecheck import prefold
from vyper.exceptions import (
ArrayIndexException,
InstantiationException,
InvalidType,
StructureException,
UnknownType,
)
from vyper.exceptions import ArrayIndexException, InstantiationException, InvalidType, UnknownType
from vyper.semantics.analysis.levenshtein_utils import get_levenshtein_error_suggestions
from vyper.semantics.data_locations import DataLocation
from vyper.semantics.namespace import get_namespace
Expand Down Expand Up @@ -146,22 +140,9 @@ def get_index_value(node: vy_ast.Index) -> int:
int
Literal integer value.
"""
# this is imported to improve error messages
# TODO: revisit this!
from vyper.semantics.analysis.utils import get_possible_types_from_node

val = prefold(node.value)

if not isinstance(val, int):
if hasattr(node, "value"):
# even though the subscript is an invalid type, first check if it's a valid _something_
# this gives a more accurate error in case of e.g. a typo in a constant variable name
try:
get_possible_types_from_node(node.value)
except StructureException:
# StructureException is a very broad error, better to raise InvalidType in this case
pass

raise InvalidType("Subscript must be a literal integer", node)

if val <= 0:
Expand Down

0 comments on commit e2f1c8c

Please sign in to comment.