Repository: numba/numba

Issue:
TypingError while returning a generator
``` python
from numba import njit

@njit
def generator():
    yield 1

@njit
def get_generator():
    return generator()

@njit  # does not matter if compiled or not
def main():
    for x in get_generator():
        pass

main()
```

Traceback for Numba version `0.24.0+249.g7bff417`:

```
Traceback (most recent call last):
  File "numba_bug_return_generator.py", line 16, in <module>
    main()
  File "numba/numba/dispatcher.py", line 288, in _compile_for_args
    return self.compile(tuple(real_args))
  File "numba/numba/dispatcher.py", line 506, in compile
    cres = self._compiler.compile(args, return_type)
  File "numba/numba/dispatcher.py", line 85, in compile
    flags=flags, locals=self.locals)
  File "numba/numba/compiler.py", line 690, in compile_extra
    return pipeline.compile_extra(func)
  File "numba/numba/compiler.py", line 378, in compile_extra
    return self.compile_bytecode(bc, func_attr=self.func_attr)
  File "numba/numba/compiler.py", line 387, in compile_bytecode
    return self._compile_bytecode()
  File "numba/numba/compiler.py", line 671, in _compile_bytecode
    res = pm.run(self.status)
  File "numba/numba/compiler.py", line 257, in run
    raise patched_exception
  File "numba/numba/compiler.py", line 249, in run
    stage()
  File "numba/numba/compiler.py", line 475, in stage_nopython_frontend
    self.locals)
  File "numba/numba/compiler.py", line 799, in type_inference_stage
    infer.propagate()
  File "numba/numba/typeinfer.py", line 613, in propagate
    raise errors[0]
numba.errors.TypingError: Failed at nopython (nopython frontend)
Internal error at <numba.typeinfer.CallConstraint object at 0x7f3ca5119a90>:
--%<-----------------------------------------------------------------
Traceback (most recent call last):
  File "numba/numba/lowering.py", line 196, in lower_block
    self.lower_inst(inst)
  File "numba/numba/lowering.py", line 270, in lower_inst
    self.call_conv.return_value(self.builder, retval)
  File "numba/numba/targets/callconv.py", line 325, in return_value
    (str(retval.type), str(retptr.type.pointee))
AssertionError: ('{i32, {}, {i64}}*', '{i32, {}, {i64}}')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "numba/numba/typeinfer.py", line 114, in propagate
    constraint(typeinfer)
  File "numba/numba/typeinfer.py", line 317, in __call__
    self.resolve(typeinfer, typevars, fnty)
  File "numba/numba/typeinfer.py", line 344, in resolve
    sig = context.resolve_function_type(fnty, pos_args, kw_args)
  File "numba/numba/typing/context.py", line 125, in resolve_function_type
    return func.get_call_type(self, args, kws)
  File "numba/numba/types/functions.py", line 153, in get_call_type
    template, pysig, args, kws = self.dispatcher.get_call_template(args, kws)
  File "numba/numba/dispatcher.py", line 251, in get_call_template
    self.compile(tuple(args))
  File "numba/numba/dispatcher.py", line 506, in compile
    cres = self._compiler.compile(args, return_type)
  File "numba/numba/dispatcher.py", line 85, in compile
    flags=flags, locals=self.locals)
  File "numba/numba/compiler.py", line 690, in compile_extra
    return pipeline.compile_extra(func)
  File "numba/numba/compiler.py", line 378, in compile_extra
    return self.compile_bytecode(bc, func_attr=self.func_attr)
  File "numba/numba/compiler.py", line 387, in compile_bytecode
    return self._compile_bytecode()
  File "numba/numba/compiler.py", line 671, in _compile_bytecode
    res = pm.run(self.status)
  File "numba/numba/compiler.py", line 257, in run
    raise patched_exception
  File "numba/numba/compiler.py", line 249, in run
    stage()
  File "numba/numba/compiler.py", line 616, in stage_nopython_backend
    self._backend(lowerfn, objectmode=False)
  File "numba/numba/compiler.py", line 571, in _backend
    lowered = lowerfn()
  File "numba/numba/compiler.py", line 558, in backend_nopython_mode
    self.flags)
  File "numba/numba/compiler.py", line 816, in native_lowering_stage
    lower.lower()
  File "numba/numba/lowering.py", line 123, in lower
    self.lower_normal_function(self.fndesc)
  File "numba/numba/lowering.py", line 158, in lower_normal_function
    entry_block_tail = self.lower_function_body()
  File "numba/numba/lowering.py", line 183, in lower_function_body
    self.lower_block(block)
  File "numba/numba/lowering.py", line 201, in lower_block
    raise LoweringError(msg, inst.loc)
numba.errors.LoweringError: Failed at nopython (nopython mode backend)
Internal error:
AssertionError: ('{i32, {}, {i64}}*', '{i32, {}, {i64}}')
File "numba_bug_return_generator.py", line 9
--%<-----------------------------------------------------------------

File "numba_bug_return_generator.py", line 13
```



Discussion:

Resolving patch:
diff --git a/numba/datamodel/models.py b/numba/datamodel/models.py
--- a/numba/datamodel/models.py
+++ b/numba/datamodel/models.py
@@ -1111,10 +1111,10 @@ def from_argument(self, builder, value):
         return value
 
     def as_return(self, builder, value):
-        return value
+        return self.as_data(builder, value)
 
     def from_return(self, builder, value):
-        return value
+        return self.from_data(builder, value)
 
     def as_data(self, builder, value):
         return builder.load(value)
diff --git a/numba/targets/callconv.py b/numba/targets/callconv.py
--- a/numba/targets/callconv.py
+++ b/numba/targets/callconv.py
@@ -452,10 +452,7 @@ def call_function(self, builder, callee, resty, argtys, args, env=None):
         code = builder.call(callee, realargs)
         status = self._get_return_status(builder, code,
                                          builder.load(excinfoptr))
-        if is_generator_function:
-            retval = retvaltmp
-        else:
-            retval = builder.load(retvaltmp)
+        retval = builder.load(retvaltmp)
         out = self.context.get_returned_value(builder, resty, retval)
         return status, out
 


Test patch:
diff --git a/numba/tests/test_generators.py b/numba/tests/test_generators.py
--- a/numba/tests/test_generators.py
+++ b/numba/tests/test_generators.py
@@ -5,9 +5,11 @@
 
 import numba.unittest_support as unittest
 from numba.compiler import compile_isolated, Flags
-from numba import jit, types
+from numba import jit, njit, types
 from .support import TestCase, MemoryLeakMixin, tag
 from numba import testing
+from numba.datamodel.testing import test_factory
+
 
 enable_pyobj_flags = Flags()
 enable_pyobj_flags.set("enable_pyobject")
@@ -588,6 +590,37 @@ def c_driver(args):
 
         np.testing.assert_equal(py_res, c_res)
 
+    def test_issue_1808(self):
+        """
+        Incorrect return data model
+        """
+        magic = 0xdeadbeef
+
+        @njit
+        def generator():
+            yield magic
+
+        @njit
+        def get_generator():
+            return generator()
+
+        @njit
+        def main():
+            out = 0
+            for x in get_generator():
+                out += x
+
+            return out
+
+        self.assertEqual(main(), magic)
+
+
+class TestGeneratorModel(test_factory()):
+    fe_type = types.Generator(gen_func=None, yield_type=types.int32,
+                              arg_types=[types.int64, types.float32],
+                              state_types=[types.intp, types.intp[::1]],
+                              has_finalizer=False)
+
 
 if __name__ == '__main__':
     unittest.main()