Repository: numba/numba

Issue:
Cannot initialize an empty list using `list()`
In [helping someone on stackoverflow](https://stackoverflow.com/a/51459101/392949), I noticed that you cannot initialize a variable as an empty list using `list()` (initializing the variable as `[]` works). I couldn't find a relevant issue that was already open (apologies if I missed it).

Using python 3.6 and numba 0.39.0:

```
import numba as nb

@nb.jit(nopython=True)
def test(x):
    y = list()   # y = [] works
    y.append(x)
    return x
```

Running the above function (e.g. `test(10)`) results in the following error:

```python
In [5]: test(10)
---------------------------------------------------------------------------
TypingError                               Traceback (most recent call last)
<ipython-input-5-7eed2ba0ee61> in <module>()
----> 1 test_nb(10)

~/anaconda/envs/numba3.6/lib/python3.6/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
    347                 e.patch_message(msg)
    348
--> 349             error_rewrite(e, 'typing')
    350         except errors.UnsupportedError as e:
    351             # Something unsupported is present in the user code, add help info

~/anaconda/envs/numba3.6/lib/python3.6/site-packages/numba/dispatcher.py in error_rewrite(e, issue_type)
    314                 raise e
    315             else:
--> 316                 reraise(type(e), e, None)
    317
    318         argtypes = []

~/anaconda/envs/numba3.6/lib/python3.6/site-packages/numba/six.py in reraise(tp, value, tb)
    656             value = tp()
    657         if value.__traceback__ is not tb:
--> 658             raise value.with_traceback(tb)
    659         raise value
    660

TypingError: Failed at nopython (nopython frontend)
Invalid usage of Function(<class 'list'>) with parameters ()
 * parameterized
In definition 0:
    All templates rejected
[1] During: resolving callee type: Function(<class 'list'>)
[2] During: typing of call at <ipython-input-2-662107d532e2> (2)
```` 

If instead the `list` has an argument:

```
import numba as nb

@nb.jit(nopython=True)
def test(x):
    y = list([1]) 
    y.append(x)
    return x
```

then this code works as expected. 


Discussion:

Resolving patch:
diff --git a/numba/targets/listobj.py b/numba/targets/listobj.py
--- a/numba/targets/listobj.py
+++ b/numba/targets/listobj.py
@@ -465,6 +465,12 @@ def list_impl(iterable):
 
     return context.compile_internal(builder, list_impl, sig, args)
 
+@lower_builtin(list)
+def list_constructor(context, builder, sig, args):
+    list_type = sig.return_type
+    list_len = 0
+    inst = ListInstance.allocate(context, builder, list_type, list_len)
+    return impl_ret_new_ref(context, builder, list_type, inst.value)
 
 #-------------------------------------------------------------------------------
 # Various operations
diff --git a/numba/typing/listdecl.py b/numba/typing/listdecl.py
--- a/numba/typing/listdecl.py
+++ b/numba/typing/listdecl.py
@@ -24,6 +24,8 @@ def generic(self, args, kws):
             if isinstance(iterable, types.IterableType):
                 dtype = iterable.iterator_type.yield_type
                 return signature(types.List(dtype), iterable)
+        else:
+            return signature(types.List(types.undefined))
 
 
 @infer_global(sorted)


Test patch:
diff --git a/numba/tests/test_lists.py b/numba/tests/test_lists.py
--- a/numba/tests/test_lists.py
+++ b/numba/tests/test_lists.py
@@ -93,6 +93,17 @@ def list_comprehension6():
 def list_constructor(n):
     return list(range(n))
 
+def list_constructor_empty():
+    # cannot be typed, list is empty and no typing information is present to
+    # infer a type
+    return list()
+
+def list_constructor_empty_but_typeable(n):
+    # can be typed, list is empty but later append has typing info that allows
+    # for inference
+    y = list()
+    return y.append(n)
+
 def list_append(n):
     l = []
     l.append(42)
@@ -407,6 +418,23 @@ def check_unary_with_size(self, pyfunc, precise=True):
     def test_constructor(self):
         self.check_unary_with_size(list_constructor)
 
+    def test_constructor_empty(self):
+        self.disable_leak_check()
+        cfunc = jit(nopython=True)(list_constructor_empty)
+        with self.assertRaises(errors.TypingError) as raises:
+            cfunc()
+        self.assertIn("Can't infer type of variable", str(raises.exception))
+        self.assertIn("list(undefined)", str(raises.exception))
+
+    def test_constructor_empty_but_typeable(self):
+        args = [np.int32(1), 10., 1 + 3j, [7], [17., 14.], np.array([10])]
+        pyfunc = list_constructor_empty_but_typeable
+        for arg in args:
+            cfunc = jit(nopython=True)(pyfunc)
+            expected = pyfunc(arg)
+            got = cfunc(arg)
+            self.assertPreciseEqual(got, expected)
+
     def test_append(self):
         self.check_unary_with_size(list_append)