Repository: vyperlang/vyper

Issue:
`AttributeError` when using invalid expression as loop's iterator
### Version Information

* vyper Version (output of `vyper --version`): 0.3.8+commit.4ae2527f
* OS: OSX
* Python Version (output of `python --version`): 3.8.0

### What's your issue about?

Trying to use something else than a `Name` as the iterator of a `For` loop leads the compiler to output an `AttributeError`.
Bug similar to #3239 but as an `id` field is expected in the iterator's node and `Name` is the only kind of node with such field, it shouldn't be possible to compile invalid code, the issue is only about the unclear displayed error I think.

```Vyper
@external
def foo():
    for a[1] in [1,2]:
        pass
```
```Bash
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 248, in build_bytecode_output
    return f"0x{compiler_data.bytecode.hex()}"
  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 150, in bytecode
    self.assembly, is_runtime=False, no_bytecode_metadata=self.no_bytecode_metadata
  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 141, in assembly
    return generate_assembly(self.ir_nodes, self.no_optimize)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 126, in ir_nodes
    ir, ir_runtime, sigs = self._ir_output
  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 122, in _ir_output
    return generate_ir_nodes(self.global_ctx, self.no_optimize)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 117, in global_ctx
    return GlobalContext(self.vyper_module_folded)
  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/analysis/__init__.py", line 13, in validate_semantics
    validate_functions(vyper_ast)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/local.py", line 59, in validate_functions
    FunctionNodeVisitor(vy_module, node, namespace)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/local.py", line 179, in __init__
    self.visit(node)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/local.py", line 222, in visit
    super().visit(node)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/common.py", line 20, in visit
    visitor_fn(node, *args)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/local.py", line 438, in visit_For
    iter_name = node.target.id
AttributeError: 'Subscript' object has no attribute 'id'
```


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
@@ -434,6 +434,9 @@ def visit_For(self, node):
                         )
         self.expr_visitor.visit(node.iter)
 
+        if not isinstance(node.target, vy_ast.Name):
+            raise StructureException("Invalid syntax for loop iterator", node.target)
+
         for_loop_exceptions = []
         iter_name = node.target.id
         for type_ in type_list:


Test patch:
diff --git a/tests/parser/syntax/test_for_range.py b/tests/parser/syntax/test_for_range.py
--- a/tests/parser/syntax/test_for_range.py
+++ b/tests/parser/syntax/test_for_range.py
@@ -1,6 +1,26 @@
 import pytest
 
 from vyper import compiler
+from vyper.exceptions import StructureException
+
+fail_list = [
+    (
+        """
+@external
+def foo():
+    for a[1] in range(10):
+        pass
+    """,
+        StructureException,
+    )
+]
+
+
+@pytest.mark.parametrize("bad_code", fail_list)
+def test_range_fail(bad_code):
+    with pytest.raises(bad_code[1]):
+        compiler.compile_code(bad_code[0])
+
 
 valid_list = [
     """