diff --git a/vyper/semantics/validation/annotation.py b/vyper/semantics/validation/annotation.py index 0a76f3e9e3..990f0805ff 100644 --- a/vyper/semantics/validation/annotation.py +++ b/vyper/semantics/validation/annotation.py @@ -2,6 +2,7 @@ from vyper.exceptions import StructureException from vyper.semantics.types import ArrayDefinition from vyper.semantics.types.bases import BaseTypeDefinition +from vyper.semantics.types.indexable.sequence import DynamicArrayFunctionDefinition from vyper.semantics.types.function import ContractFunction from vyper.semantics.types.user.event import Event from vyper.semantics.types.user.struct import StructPrimitive @@ -125,9 +126,9 @@ def visit_BoolOp(self, node, type_): def visit_Call(self, node, type_): call_type = get_exact_type_from_node(node.func) - node._metadata["type"] = type_ or call_type.fetch_call_return(node) + node_type = type_ or call_type.fetch_call_return(node) + node._metadata["type"] = node_type self.visit(node.func) - if isinstance(call_type, (Event, ContractFunction)): # events and internal function calls for arg, arg_type in zip(node.args, list(call_type.arguments.values())): @@ -136,6 +137,9 @@ def visit_Call(self, node, type_): # literal structs for value, arg_type in zip(node.args[0].values, list(call_type.members.values())): self.visit(value, arg_type) + elif isinstance(call_type, DynamicArrayFunctionDefinition): + for arg in node.args: + self.visit(arg, node_type.value_type) elif node.func.id not in ("empty", "range"): # builtin functions for arg in node.args: diff --git a/vyper/semantics/validation/local.py b/vyper/semantics/validation/local.py index 3bda158f98..f52f8a84c8 100644 --- a/vyper/semantics/validation/local.py +++ b/vyper/semantics/validation/local.py @@ -29,6 +29,7 @@ from vyper.semantics.types.indexable.sequence import ( ArrayDefinition, DynamicArrayDefinition, + DynamicArrayFunctionDefinition, TupleDefinition, ) from vyper.semantics.types.user.event import Event @@ -444,7 +445,6 @@ def visit_For(self, node): def visit_Expr(self, node): if not isinstance(node.value, vy_ast.Call): raise StructureException("Expressions without assignment are disallowed", node) - fn_type = get_exact_type_from_node(node.value.func) if isinstance(fn_type, Event): raise StructureException("To call an event you must use the `log` statement", node) @@ -463,9 +463,9 @@ def visit_Expr(self, node): raise StateAccessViolation( f"Cannot call any function from a {self.func.mutability.value} function", node ) - return_value = fn_type.fetch_call_return(node.value) - if return_value and not isinstance(fn_type, ContractFunction): + if return_value and not isinstance(fn_type, DynamicArrayFunctionDefinition) and \ + not isinstance(fn_type, ContractFunction): raise StructureException( f"Function '{fn_type._id}' cannot be called without assigning the result", node )