Repository: numba/numba

Issue:
Regression: `cmath.rect` doesn't work in numba 0.21.0
The following MWE works in numba 0.20.0, but not in 0.21.0:

``` python
import numba as nb
import cmath

@nb.njit
def dumb_wrapper(r, phi):
    return cmath.rect(r, phi)

print(dumb_wrapper(1.0, 2.0))
```

I've only tried a few other functions in `cmath`, but haven't found any other problems.  When this is run, a big traceback results:

``` python
Traceback (most recent call last):
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/llvmlite/ir/instructions.py", line 471, in __init__
    typ = typ.elements[i]
AttributeError: 'DoubleType' object has no attribute 'elements'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 196, in lower_block
    self.lower_inst(inst)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 238, in lower_inst
    val = self.lower_assign(ty, inst)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 395, in lower_assign
    return self.lower_expr(ty, value)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 756, in lower_expr
    self.incref(resty, val)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 808, in incref
    self.context.nrt_incref(self.builder, typ, val)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/targets/base.py", line 1111, in nrt_incref
    self._call_nrt_incref_decref(builder, typ, typ, value, "NRT_incref")
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/targets/base.py", line 1090, in _call_nrt_incref_decref
    members = data_model.traverse(builder, value)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/datamodel/models.py", line 565, in traverse
    for k in self._fields]
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/datamodel/models.py", line 565, in <listcomp>
    for k in self._fields]
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/datamodel/models.py", line 513, in get
    name="extracted." + self._fields[pos])
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/llvmlite/ir/builder.py", line 538, in extract_value
    instr = instructions.ExtractValue(self.block, agg, idx, name=name)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/llvmlite/ir/instructions.py", line 474, in __init__
    % (list(indices), agg.type))
TypeError: Can't index at [0] in double

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test_numba21.py", line 8, in <module>
    print(dumb_wrapper(1.0, 2.0))
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/dispatcher.py", line 171, in _compile_for_args
    return self.compile(sig)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/dispatcher.py", line 348, in compile
    flags=flags, locals=self.locals)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 637, in compile_extra
    return pipeline.compile_extra(func)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 358, in compile_extra
    return self.compile_bytecode(bc, func_attr=self.func_attr)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 367, in compile_bytecode
    return self._compile_bytecode()
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 624, in _compile_bytecode
    return pm.run(self.status)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 250, in run
    raise patched_exception
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 242, in run
    res = stage()
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 580, in stage_nopython_backend
    return self._backend(lowerfn, objectmode=False)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 533, in _backend
    lowered = lowerfn()
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 524, in backend_nopython_mode
    self.flags)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 766, in native_lowering_stage
    lower.lower()
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 123, in lower
    self.lower_normal_function(self.fndesc)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 158, in lower_normal_function
    entry_block_tail = self.lower_function_body()
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 183, in lower_function_body
    self.lower_block(block)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 196, in lower_block
    self.lower_inst(inst)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 238, in lower_inst
    val = self.lower_assign(ty, inst)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 395, in lower_assign
    return self.lower_expr(ty, value)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 609, in lower_expr
    res = self.lower_call(resty, expr)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 575, in lower_call
    res = impl(self.builder, argvals)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/targets/base.py", line 1127, in __call__
    return self._imp(self._context, builder, self._sig, args)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/targets/cmathimpl.py", line 100, in rect_impl
    args + [phi_is_finite])
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/targets/base.py", line 867, in compile_internal
    ty = self.compile_subroutine(builder, impl, sig, locals)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/targets/base.py", line 857, in compile_subroutine
    locals=locals)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/targets/base.py", line 837, in compile_only_no_cache
    locals=locals)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 654, in compile_internal
    return pipeline.compile_extra(func)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 358, in compile_extra
    return self.compile_bytecode(bc, func_attr=self.func_attr)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 367, in compile_bytecode
    return self._compile_bytecode()
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 624, in _compile_bytecode
    return pm.run(self.status)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 250, in run
    raise patched_exception
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 242, in run
    res = stage()
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 580, in stage_nopython_backend
    return self._backend(lowerfn, objectmode=False)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 533, in _backend
    lowered = lowerfn()
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 524, in backend_nopython_mode
    self.flags)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/compiler.py", line 766, in native_lowering_stage
    lower.lower()
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 123, in lower
    self.lower_normal_function(self.fndesc)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 158, in lower_normal_function
    entry_block_tail = self.lower_function_body()
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 183, in lower_function_body
    self.lower_block(block)
  File "/home/me/.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/lowering.py", line 201, in lower_block
    raise LoweringError(msg, inst.loc)
numba.errors.LoweringError: Failed at nopython (nopython mode backend)
Failed at nopython (nopython mode backend)
Internal error:
TypeError: Can't index at [0] in double
File "../../.continuum/anaconda/envs/numba21/lib/python3.4/site-packages/numba/targets/cmathimpl.py", line 80
```

I'm on OS X 10.10.5, using anaconda with python 3.4, though the same seems to happen on Travis-CI (ubuntu?), using [python 2.7](https://travis-ci.org/moble/spherical_functions/jobs/80467434) and [python 3.4](https://travis-ci.org/moble/spherical_functions/jobs/80467435).



Discussion:

Resolving patch:
diff --git a/numba/lowering.py b/numba/lowering.py
--- a/numba/lowering.py
+++ b/numba/lowering.py
@@ -755,7 +755,7 @@ def lower_expr(self, resty, expr):
             val = self.loadvar(expr.value.name)
             ty = self.typeof(expr.value.name)
             castval = self.context.cast(self.builder, val, ty, resty)
-            self.incref(resty, val)
+            self.incref(resty, castval)
             return castval
 
         elif expr.op in self.context.special_ops:


Test patch:
diff --git a/numba/tests/test_nrt.py b/numba/tests/test_nrt.py
--- a/numba/tests/test_nrt.py
+++ b/numba/tests/test_nrt.py
@@ -8,9 +8,13 @@
 
 from numba import unittest_support as unittest
 from numba import njit
+from numba.compiler import compile_isolated, Flags, types
 from numba.runtime import rtsys
 from numba.config import PYVERSION
-from .support import MemoryLeakMixin
+from .support import MemoryLeakMixin, TestCase
+
+enable_nrt_flags = Flags()
+enable_nrt_flags.set("nrt")
 
 
 class Dummy(object):
@@ -230,7 +234,7 @@ def release_memory():
         self.assertLess(stat.size, N * 0.01)
 
 
-class TestNRTIssue(MemoryLeakMixin, unittest.TestCase):
+class TestNRTIssue(MemoryLeakMixin, TestCase):
     def test_issue_with_refct_op_pruning(self):
         """
         GitHub Issue #1244 https://github.com/numba/numba/issues/1244
@@ -274,6 +278,23 @@ def normalize_vectors(num_vectors, vectors):
 
         np.testing.assert_almost_equal(expected, got)
 
+    def test_incref_after_cast(self):
+        # Issue #1427: when casting a value before returning it, the
+        # cast result should be incref'ed, not the original value.
+        def f():
+            return 0.0, np.zeros(1, dtype=np.int32)
+
+        # Note the return type isn't the same as the tuple type above:
+        # the first element is a complex rather than a float.
+        cres = compile_isolated(f, (),
+                                types.Tuple((types.complex128,
+                                             types.Array(types.int32, 1, 'C')
+                                             ))
+                                )
+        z, arr = cres.entry_point()
+        self.assertPreciseEqual(z, 0j)
+        self.assertPreciseEqual(arr, np.zeros(1, dtype=np.int32))
+
 
 if __name__ == '__main__':
     unittest.main()