Repository: vyperlang/vyper

Issue:
Unable to copy hashmap
### Version Information

* vyper Version (output of `vyper --version`): 0.3.2

### What's your issue about?

```
m1: HashMap[uint8, uint8]
m2: HashMap[uint8, uint8]

@external
def __init__():
    self.m1 = self.m2
```

```
vyper.exceptions.TypeMismatch: Given reference has type HashMap[uint8, uint8], expected HashMap[uint8, uint8]
  contract "lisa.vy", function "__init__", line 6:14 
       5 def __init__():
  ---> 6     self.m1 = self.m2
  ---------------------^
       7 # ====

[27002] Failed to execute script 'vyper_compile' due to unhandled exception!
```


Discussion:
i don't think you should be able to copy hashmaps (since their size is unknown). this could have a better error message though

Resolving patch:
diff --git a/vyper/semantics/types/indexable/mapping.py b/vyper/semantics/types/indexable/mapping.py
--- a/vyper/semantics/types/indexable/mapping.py
+++ b/vyper/semantics/types/indexable/mapping.py
@@ -47,7 +47,11 @@ def from_annotation(
             or len(node.slice.value.elements) != 2
         ):
             raise StructureException(
-                "HashMap must be defined with a key type and a value type", node
+                (
+                    "HashMap must be defined with a key type and a value type, "
+                    "e.g. my_hashmap: HashMap[k, v]"
+                ),
+                node,
             )
         if location != DataLocation.STORAGE or is_immutable:
             raise StructureException("HashMap can only be declared as a storage variable", node)
diff --git a/vyper/semantics/validation/local.py b/vyper/semantics/validation/local.py
--- a/vyper/semantics/validation/local.py
+++ b/vyper/semantics/validation/local.py
@@ -29,6 +29,7 @@
     MemberFunctionDefinition,
     StateMutability,
 )
+from vyper.semantics.types.indexable.mapping import MappingDefinition
 from vyper.semantics.types.indexable.sequence import (
     ArrayDefinition,
     DynamicArrayDefinition,
@@ -231,6 +232,10 @@ def visit_Assign(self, node):
             raise StructureException("Right-hand side of assignment cannot be a tuple", node.value)
 
         target = get_exact_type_from_node(node.target)
+        if isinstance(target, MappingDefinition):
+            raise StructureException(
+                "Left-hand side of assignment cannot be a HashMap without a key", node
+            )
 
         validate_expected_type(node.value, target)
         target.validate_modification(node, self.func.mutability)


Test patch:
diff --git a/tests/parser/exceptions/test_structure_exception.py b/tests/parser/exceptions/test_structure_exception.py
--- a/tests/parser/exceptions/test_structure_exception.py
+++ b/tests/parser/exceptions/test_structure_exception.py
@@ -80,6 +80,39 @@ def foo():
 def foo():
     true: int128 = 3
     """,
+    """
+n: HashMap[uint256, bool][3]
+    """,
+    """
+a: constant(uint256) = 3
+n: public(HashMap[uint256, Y][a])
+    """,
+    """
+a: immutable(uint256)
+n: public(HashMap[uint256, bool][a])
+
+@external
+def __init__():
+    a = 3
+    """,
+    """
+n: HashMap[uint256, bool][3][3]
+    """,
+    """
+m1: HashMap[uint8, uint8]
+m2: HashMap[uint8, uint8]
+
+@external
+def __init__():
+    self.m1 = self.m2
+    """,
+    """
+m1: HashMap[uint8, uint8]
+
+@external
+def __init__():
+    self.m1 = 234
+    """,
 ]