diff --git a/tests/parser/syntax/test_for_range.py b/tests/parser/syntax/test_for_range.py index b2a9491058..e6f35c1d2d 100644 --- a/tests/parser/syntax/test_for_range.py +++ b/tests/parser/syntax/test_for_range.py @@ -12,7 +12,26 @@ def foo(): pass """, StructureException, - ) + ), + ( + """ +@external +def bar(): + for i in range(1,2,bound=2): + pass + """, + StructureException, + ), + ( + """ +@external +def bar(): + x:uint256 = 1 + for i in range(x,x+1,bound=2): + pass + """, + StructureException, + ), ] diff --git a/vyper/semantics/analysis/local.py b/vyper/semantics/analysis/local.py index c0c05325f2..c10df3b8fd 100644 --- a/vyper/semantics/analysis/local.py +++ b/vyper/semantics/analysis/local.py @@ -346,10 +346,11 @@ def visit_For(self, node): raise IteratorException( "Cannot iterate over the result of a function call", node.iter ) - validate_call_args(node.iter, (1, 2), kwargs=["bound"]) + range_ = node.iter + validate_call_args(range_, (1, 2), kwargs=["bound"]) - args = node.iter.args - kwargs = {s.arg: s.value for s in node.iter.keywords or []} + args = range_.args + kwargs = {s.arg: s.value for s in range_.keywords or []} if len(args) == 1: # range(CONSTANT) n = args[0] @@ -371,6 +372,13 @@ def visit_For(self, node): type_list = get_common_types(n, bound) else: + if range_.keywords: + raise StructureException( + "Keyword arguments are not supported for `range(N, M)` and" + "`range(x, x + N)` expressions", + range_.keywords[0], + ) + validate_expected_type(args[0], IntegerT.any()) type_list = get_common_types(*args) if not isinstance(args[0], vy_ast.Constant):