Repository: vyperlang/vyper

Issue:
Return ListType is not properly implememted
### What's your issue about?
```
@public
def foo() -> decimal[2][2]:
    a = [[1,2],[3,4]]
    return a
```
will be rejected by the compiler, but
```
@public
def foo() -> decimal[2][2]:
    return [[1,2],[3,4]]
```
is accepted. 

### How can it be fixed?
In `parse_return` function, first remove the check `if sub_base_type != ret_base_type and sub.value != 'multi': ...` And you can directly return a memory address only when `sub_base_type == return_base_type` and `sub.value != "multi"`. Otherwise, it needs to go through make_setter function to do the conversion.

#### Cute Animal Picture

![image](https://user-images.githubusercontent.com/5641590/33740127-2d07419c-db65-11e7-9259-dcb4d483cacf.png)




Discussion:

Resolving patch:
diff --git a/vyper/parser/stmt.py b/vyper/parser/stmt.py
--- a/vyper/parser/stmt.py
+++ b/vyper/parser/stmt.py
@@ -427,14 +427,14 @@ def parse_return(self):
         elif isinstance(sub.typ, ListType):
             sub_base_type = re.split(r'\(|\[', str(sub.typ.subtype))[0]
             ret_base_type = re.split(r'\(|\[', str(self.context.return_type.subtype))[0]
-            if sub_base_type != ret_base_type and sub.value != 'multi':
+            if sub_base_type != ret_base_type:
                 raise TypeMismatchException(
                     "List return type %r does not match specified return type, expecting %r" % (
                         sub_base_type, ret_base_type
                     ),
                     self.stmt
                 )
-            if sub.location == "memory" and sub.value != "multi":
+            elif sub.location == "memory" and sub.value != "multi":
                 return LLLnode.from_list(['return', sub, get_size_of_type(self.context.return_type) * 32],
                                             typ=None, pos=getpos(self.stmt))
             else:


Test patch:
diff --git a/tests/parser/syntax/test_list.py b/tests/parser/syntax/test_list.py
--- a/tests/parser/syntax/test_list.py
+++ b/tests/parser/syntax/test_list.py
@@ -159,12 +159,12 @@ def foo():
     """
 @public
 def foo() -> int128[2][2]:
-    return [[1,2],[3,4]]
+    return [[1,2], [3,4]]
     """,
     """
 @public
 def foo() -> decimal[2][2]:
-    return [[1,2],[3,4]]
+    return [[1.0, 2.0], [3.0, 4.0]]
     """,
     """
 @public
diff --git a/tests/parser/types/test_lists.py b/tests/parser/types/test_lists.py
--- a/tests/parser/types/test_lists.py
+++ b/tests/parser/types/test_lists.py
@@ -71,7 +71,7 @@ def joo() -> int128[2]:
 
 @public
 def koo() -> int128[2][2]:
-    return [[1,2],[3,4]]
+    return [[1, 2], [3, 4]]
 
 @public
 def loo() -> int128[2][2]:
@@ -93,11 +93,11 @@ def poo(inp: int128[2][2]) -> int128[2][2]:
 
 @public
 def qoo(inp: int128[2]) -> int128[2][2]:
-    return [inp,[3,4]]
+    return [inp, [3,4]]
 
 @public
-def roo(inp: int128[2]) -> decimal[2][2]:
-    return [inp,[3,4]]
+def roo(inp: decimal[2]) -> decimal[2][2]:
+    return [inp, [3.0, 4.0]]
     """
 
     c = get_contract_with_gas_estimation(list_output_tester_code)
@@ -148,3 +148,32 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128:
     c = get_contract_with_gas_estimation(two_d_array_accessor)
     assert c.test_array(2, 7, 1, 8) == 2718
     print('Passed complex array accessor test')
+
+
+def test_returns_lists(get_contract_with_gas_estimation):
+    code = """
+@public
+def test_array_num_return() -> int128[2][2]:
+    a: int128[2][2] = [[1, 2], [3, 4]]
+    return a
+
+@public
+def test_array_decimal_return1() -> decimal[2][2]:
+    a: decimal[2][2] = [[1.0, 2.0], [3.0, 4.0]]
+    return a
+
+@public
+def test_array_decimal_return2() -> decimal[2][2]:
+    return [[1.0, 2.0], [3.0, 4.0]]
+
+@public
+def test_array_decimal_return3() -> decimal[2][2]:
+    a: decimal[2][2] = [[1.0, 2.0], [3.0, 4.0]]
+    return a
+"""
+
+    c = get_contract_with_gas_estimation(code)
+    assert c.test_array_num_return() == [[1, 2], [3, 4]]
+    assert c.test_array_decimal_return1() == [[1.0, 2.0], [3.0, 4.0]]
+    assert c.test_array_decimal_return2() == [[1.0, 2.0], [3.0, 4.0]]
+    assert c.test_array_decimal_return3() == [[1.0, 2.0], [3.0, 4.0]]