diff --git a/tests/functional/codegen/features/iteration/test_for_in_list.py b/tests/functional/codegen/features/iteration/test_for_in_list.py index 9ff50d09f6..036e7c0647 100644 --- a/tests/functional/codegen/features/iteration/test_for_in_list.py +++ b/tests/functional/codegen/features/iteration/test_for_in_list.py @@ -914,3 +914,19 @@ def foo() -> DynArray[uint256, 10]: """ c = get_contract(code) assert c.foo() == [1, 2, 3, 4] + + +def test_iterator_modification_func_arg(get_contract): + code = """ +@internal +def boo(a: DynArray[uint256, 12] = [], b: DynArray[uint256, 12] = []) -> DynArray[uint256, 12]: + for i: uint256 in a: + b.append(i) + return b + +@external +def foo() -> DynArray[uint256, 12]: + return self.boo([1, 2, 3]) + """ + c = get_contract(code) + assert c.foo() == [1, 2, 3] diff --git a/vyper/semantics/analysis/base.py b/vyper/semantics/analysis/base.py index 026e0626e7..65bc8df3ab 100644 --- a/vyper/semantics/analysis/base.py +++ b/vyper/semantics/analysis/base.py @@ -257,7 +257,10 @@ def to_dict(self): # map SUBSCRIPT_ACCESS to `"$subscript_access"` (which is an identifier # which can't be constructed by the user) path = ["$subscript_access" if s is self.SUBSCRIPT_ACCESS else s for s in self.path] - varname = var.decl_node.target.id + if isinstance(var.decl_node, vy_ast.arg): + varname = var.decl_node.arg + else: + varname = var.decl_node.target.id decl_node = var.decl_node.get_id_dict() ret = {"name": varname, "decl_node": decl_node, "access_path": path} diff --git a/vyper/semantics/analysis/local.py b/vyper/semantics/analysis/local.py index b6ea4f04df..b5292b1dad 100644 --- a/vyper/semantics/analysis/local.py +++ b/vyper/semantics/analysis/local.py @@ -317,7 +317,7 @@ def analyze(self): for arg in self.func.arguments: self.namespace[arg.name] = VarInfo( - arg.typ, location=location, modifiability=modifiability, decl_node=arg + arg.typ, location=location, modifiability=modifiability, decl_node=arg.ast_source ) for node in self.fn_node.body: