Skip to content

incorrect error message for immutable violation #4755

@cyberthirst

Description

@cyberthirst

Version Information

  • vyper Version (output of vyper --version): 34a9e08

What's your issue about?

@deploy
def __init__(a: uint256, b: DynArray[uint256, 10]):
    a = 10

yields:

vyper.exceptions.ImmutableViolation: Cannot write to calldata

  contract "tests/custom/test.vy:6", function "__init__", line 6:4 
       5 def __init__(a: uint256, b: DynArray[uint256, 10]):
  ---> 6     a = 10
  -----------^

but a doesn't come from calldata

this should be because the following line:

location, modifiability = (DataLocation.CALLDATA, Modifiability.RUNTIME_CONSTANT)

sets the location to CALLDATA even when the function is the constructor

i'm not sure whether the err msg is the only manifistation of the location assignment

How can it be fixed?

fixing just the error msg might involve smth like this

diff --git a/vyper/semantics/analysis/local.py b/vyper/semantics/analysis/local.py
index 70d8cbdd6..1bdca81f1 100644
--- a/vyper/semantics/analysis/local.py
+++ b/vyper/semantics/analysis/local.py
@@ -425,6 +425,13 @@ class FunctionAnalyzer(VyperNodeVisitorBase):
             )
 
         if info.location == DataLocation.CALLDATA:
+            if (
+                func_t.is_constructor
+                and info.var_info is not None
+                and isinstance(info.var_info.decl_node, vy_ast.arg)
+            ):
+                raise ImmutableViolation("Cannot assign to constructor argument")
+
             raise ImmutableViolation("Cannot write to calldata")
 
         if info.modifiability == Modifiability.RUNTIME_CONSTANT:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions