Repository: vyperlang/vyper

Issue:
Unhandled error in my code
### Version Information

* vyper Version (output of `vyper --version`): 0.2.4
* Compiler: online (not local)

### What's your issue about?

I have the code below for one of my assignments which gives an unhandled error.
```
# @version ^0.2.4
owner: public(address)
target: public(uint256)
endTime: public(uint256)

Idx: public(uint256)
struct Contributor:
    userAddress: address
    contribution: uint256
contributors: Contributor[100]

@external
@payable
def __init__(_target: uint256, _duration: uint256):
    self.owner = msg.sender
    self.target = _target
    self.endTime = block.timestamp + _duration

@external
@payable
def contribute():
    assert block.timestamp < self.endTime, "Time to contribute is up!"
    self.contributors[self.Idx] = Contributor({userAddress: msg.sender, contribution: msg.value})
    self.Idx = self.Idx + 1
    
@external
def collect():
    assert self.balance >= self.target, "Target is not met, yet!"
    assert msg.sender == self.owner, "Only the owner can collect the fund."
    selfdestruct(self.owner)
    
@external
def refund():
    assert block.timestamp > self.endTime, "Money won't be refunded within the contract duration."
    assert self.balance < self.target, "Target is met and the fund is waiting to be collected."
    for contributor in self.contributors:
        send(contributor.userAddress,contributor.contribution)

@view
@external
def show_balance()-> uint256: 
    return self.balance
```
Remix won't return anything useful. Using etherscan online compiler I see this:
```
Err. RefID: vyper-in-bMRb4j8v94XWZgU.vy
vyper.exceptions.TypeCheckFailure: Statement node did not produce LLL

This is an unhandled internal compiler error. Please create an issue on Github to notify the developers.
https://github.com/vyperlang/vyper/issues/new?template=bug.md
```


### How can it be fixed?

I haven't found the issue of my code, yet!


Discussion:
hey @domrany64, your issue is likely with the following line in `refund()`:
```python
    for contributor in self.contributors:
        send(contributor.userAddress,contributor.contribution)
```

It's not possible to iterate over a static list of a complex type yet, our type checking didn't catch this condition to report it properly. This should work for you:
```python
    for i in range(LEN_CONTRIBUTORS):  # Note: use this constant above too (instead of `100`)
        send(self.contributors[i].userAddress, self.contributors[i].contribution)
```

---

We will work on the error message, and eventually add the ability to do this type of iteration
Wow, that was an easy fix.
Thank you for your help.

I hope the report has been helpful to you, too.
It was! Thank you for reporting!


Resolving patch:
diff --git a/vyper/context/validation/local.py b/vyper/context/validation/local.py
--- a/vyper/context/validation/local.py
+++ b/vyper/context/validation/local.py
@@ -20,6 +20,7 @@
     TupleDefinition,
 )
 from vyper.context.types.meta.event import Event
+from vyper.context.types.meta.struct import StructDefinition
 from vyper.context.types.utils import get_type_from_annotation
 from vyper.context.types.value.boolean import BoolDefinition
 from vyper.context.types.value.numeric import Uint256Definition
@@ -323,6 +324,9 @@ def visit_For(self, node):
         if next((i for i in type_list if isinstance(i, ArrayDefinition)), False):
             raise StructureException("Cannot iterate over a nested list", node.iter)
 
+        if next((i for i in type_list if isinstance(i, StructDefinition)), False):
+            raise StructureException("Cannot iterate over a list of structs", node.iter)
+
         if isinstance(node.iter, (vy_ast.Name, vy_ast.Attribute)):
             # check for references to the iterated value within the body of the loop
             assign = _check_iterator_assign(node.iter, node)


Test patch:
diff --git a/tests/parser/syntax/test_nested_list.py b/tests/parser/syntax/test_nested_list.py
--- a/tests/parser/syntax/test_nested_list.py
+++ b/tests/parser/syntax/test_nested_list.py
@@ -69,6 +69,21 @@ def foo() -> int128[3]:
     """,
         StructureException,
     ),
+    (
+        """
+# for loops only allowed on base types
+struct Baz:
+    a: uint256
+bar: Baz[3]
+
+@external
+def foo():
+    for x in self.bar:
+        pass
+
+    """,
+        StructureException,
+    ),
 ]