Repository: vyperlang/vyper

Issue:
Immutable variables used in the constructor
### Version Information

* vyper Version (output of `vyper --version`): 0.3.1
* OS: macOS
* Python Version (output of `python --version`): 3.8.9

### What's your issue about?

If you use immutable variables in the constructor the variable fills with garbage(in this simplified example it remains 0).

```py
# @version 0.3.1


A: immutable(uint256)
a: public(uint256)


@external
def __init__(_a: uint256):
    A = _a
    self.a = _a  # breaks with A


@external
@view
def a1() -> uint256:
    return A
```


### How can it be fixed?

1) Immutable variables usage in constructor could be restricted by the compiler or
2) somehow set the right value.


Discussion:

Patch:
diff --git a/vyper/codegen/expr.py b/vyper/codegen/expr.py
index 23ee166d..5e1e3674 100644
--- a/vyper/codegen/expr.py
+++ b/vyper/codegen/expr.py
@@ -326,7 +326,7 @@ class Expr:
             is_constructor = self.expr.get_ancestor(vy_ast.FunctionDef).get("name") == "__init__"
             if is_constructor:
                 # store memory position for later access in module.py in the variable record
-                memory_loc = self.context.new_variable(f"#immutable_{self.expr.id}", var.typ)
+                memory_loc = self.context.new_variable(self.expr.id, var.typ)
                 self.context.global_ctx._globals[self.expr.id].pos = memory_loc
                 # store the data offset in the variable record as well for accessing
                 data_offset = self.expr._metadata["type"].position.offset


Test patch:
diff --git a/tests/parser/features/test_immutable.py b/tests/parser/features/test_immutable.py
index 0162f80b..8d711844 100644
--- a/tests/parser/features/test_immutable.py
+++ b/tests/parser/features/test_immutable.py
@@ -32,6 +32,29 @@ def get_value() -> {typ}:
     assert c.get_value() == value
 
 
+@pytest.mark.parametrize("val", [0, 1, 2 ** 256 - 1])
+def test_usage_in_constructor(get_contract, val):
+    code = """
+A: immutable(uint256)
+a: public(uint256)
+
+
+@external
+def __init__(_a: uint256):
+    A = _a
+    self.a = A
+
+
+@external
+@view
+def a1() -> uint256:
+    return A
+    """
+
+    c = get_contract(code, val)
+    assert c.a1() == c.a() == val
+
+
 def test_multiple_immutable_values(get_contract):
     code = """
 a: immutable(uint256)