Repository: vyperlang/vyper

Issue:
`TypeError` when iterating on an empty literal array
### Version Information

* vyper Version (output of `vyper --version`): 0.3.8+commit.6020b8bb
* OS: OSX
* Python Version (output of `python --version`): 3.8.0

### What's your issue about?

Although it is completely useless, trying to iterate over an empty literal array lead the compiler to output the following error `TypeError: cannot pickle 'module' object`.

For example, trying to compile the following contract with `vyper --verbose -f abi,ir,bytecode  foo.vy` will fail with the given error.
```Vyper
@external
def test():
    for i in []:
        pass
```
```
Error compiling: tests/customs/code.vy
Traceback (most recent call last):
  File "/Users/trocher/Documents/thesis/vyper/venv/bin/vyper", line 11, in <module>
    load_entry_point('vyper==0.3.8', 'console_scripts', 'vyper')()
  File "/Users/trocher/Documents/thesis/vyper/vyper/cli/vyper_compile.py", line 57, in _parse_cli_args
    return _parse_args(sys.argv[1:])
  File "/Users/trocher/Documents/thesis/vyper/vyper/cli/vyper_compile.py", line 154, in _parse_args
    compiled = compile_files(
  File "/Users/trocher/Documents/thesis/vyper/vyper/cli/vyper_compile.py", line 294, in compile_files
    compiler_data = vyper.compile_codes(
  File "/Users/trocher/Documents/thesis/vyper/vyper/evm/opcodes.py", line 226, in _wrapper
    return fn(*args, **kwargs)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/__init__.py", line 141, in compile_codes
    exc_handler(contract_name, exc)
  File "/Users/trocher/Documents/thesis/vyper/vyper/cli/vyper_compile.py", line 189, in exc_handler
    raise exception
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/__init__.py", line 138, in compile_codes
    out[contract_name][output_format] = OUTPUT_FORMATS[output_format](compiler_data)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/output.py", line 145, in build_abi_output
    abi = compiler_data.vyper_module_folded._metadata["type"].to_abi_dict()
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 107, in vyper_module_folded
    module, storage_layout = self._folded_module
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/functools.py", line 966, in __get__
    val = self.func(instance)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 101, in _folded_module
    return generate_folded_ast(
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 229, in generate_folded_ast
    validate_semantics(vyper_module_folded, interface_codes)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/validation/__init__.py", line 11, in validate_semantics
    validate_functions(vyper_ast)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/validation/local.py", line 62, in validate_functions
    FunctionNodeVisitor(vy_module, node, namespace)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/validation/local.py", line 181, in __init__
    self.visit(node)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/validation/local.py", line 224, in visit
    super().visit(node)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/validation/base.py", line 20, in visit
    visitor_fn(node, *args)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/validation/local.py", line 436, in visit_For
    type_ = copy.deepcopy(type_)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/copy.py", line 161, in deepcopy
    rv = reductor(4)
TypeError: cannot pickle 'module' object

```
### How can it be fixed?

When the compiler is trying to type check the for loop body using each possible type for iterator value, in this case, as there is no restriction on the type, it even try to assign the type `event` to the iterator, leading to the call to `copy.deepcopy` to fail as it is a `module`
https://github.com/vyperlang/vyper/blob/6020b8bbf66b062d299d87bc7e4eddc4c9d1c157/vyper/semantics/validation/local.py#L435-L436
Note that in version `0.3.6` the deepcopy would succeed but the compiler would fail during the very next instruction as `event` does not have a field `is_constant`.


Discussion:

Resolving patch:
diff --git a/vyper/semantics/analysis/local.py b/vyper/semantics/analysis/local.py
--- a/vyper/semantics/analysis/local.py
+++ b/vyper/semantics/analysis/local.py
@@ -383,6 +383,9 @@ def visit_For(self, node):
 
         else:
             # iteration over a variable or literal list
+            if isinstance(node.iter, vy_ast.List) and len(node.iter.elements) == 0:
+                raise StructureException("For loop must have at least 1 iteration", node.iter)
+
             type_list = [
                 i.value_type
                 for i in get_possible_types_from_node(node.iter)


Test patch:
diff --git a/tests/parser/features/iteration/test_for_in_list.py b/tests/parser/features/iteration/test_for_in_list.py
--- a/tests/parser/features/iteration/test_for_in_list.py
+++ b/tests/parser/features/iteration/test_for_in_list.py
@@ -658,6 +658,20 @@ def foo():
     for i in range(0):
         pass
     """,
+    """
+@external
+def foo():
+    for i in []:
+        pass
+    """,
+    """
+FOO: constant(DynArray[uint256, 3]) = []
+
+@external
+def foo():
+    for i in FOO:
+        pass
+    """,
     (
         """
 @external