Repository: numba/numba

Issue:
Can't compile tuple generators
```python
@njit
def gen():
    yield 1, 2
    yield 3, 4

for i in gen():
    print(i)
```
I expected the output to be
```
(1, 2)
(3, 4)
```
Instead, I got this error
```
numba.core.errors.LoweringError: Failed in nopython mode pipeline (step: nopython mode backend)
('{i64, i64}', '[2 x i64]')
```


Works fine with only 1 yield
```python
@njit
def gen():
    for i in range(10):
        yield i, i + 1


for i in gen():
    print(i)
```

Can't compile tuple generators
```python
@njit
def gen():
    yield 1, 2
    yield 3, 4

for i in gen():
    print(i)
```
I expected the output to be
```
(1, 2)
(3, 4)
```
Instead, I got this error
```
numba.core.errors.LoweringError: Failed in nopython mode pipeline (step: nopython mode backend)
('{i64, i64}', '[2 x i64]')
```


Works fine with only 1 yield
```python
@njit
def gen():
    for i in range(10):
        yield i, i + 1


for i in gen():
    print(i)
```



Discussion:
Thanks for reporting the issue. I can confirm that this is a bug.
Also noting, the problem is not new. It has at least been around since the last 2 versions (0.53, 0.52).
This last worked in 0.46.
Thanks for reporting the issue. I can confirm that this is a bug.
Also noting, the problem is not new. It has at least been around since the last 2 versions (0.53, 0.52).
This last worked in 0.46.

Resolving patch:
diff --git a/numba/core/lowering.py b/numba/core/lowering.py
--- a/numba/core/lowering.py
+++ b/numba/core/lowering.py
@@ -597,13 +597,15 @@ def lower_yield(self, retty, inst):
         # Yield to caller
         val = self.loadvar(inst.value.name)
         typ = self.typeof(inst.value.name)
+        actual_rettyp = self.gentype.yield_type
 
         # cast the local val to the type yielded
-        yret = self.context.cast(self.builder, val, typ,
-                                 self.gentype.yield_type)
+        yret = self.context.cast(self.builder, val, typ, actual_rettyp)
 
         # get the return repr of yielded value
-        retval = self.context.get_return_value(self.builder, typ, yret)
+        retval = self.context.get_return_value(
+            self.builder, actual_rettyp, yret,
+        )
 
         # return
         self.call_conv.return_value(self.builder, retval)


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
@@ -128,6 +128,19 @@ def gen_optional_and_type_unification_error():
         i = yield i
 
 
+def gen_changing_tuple_type():
+    # https://github.com/numba/numba/issues/7295
+    yield 1, 2
+    yield 3, 4
+
+
+def gen_changing_number_type():
+    # additional test for https://github.com/numba/numba/issues/7295
+    yield 1
+    yield 3.5
+    yield 67.8j
+
+
 class TestGenerators(MemoryLeakMixin, TestCase):
     def check_generator(self, pygen, cgen):
         self.assertEqual(next(cgen), next(pygen))
@@ -340,6 +353,20 @@ def test_optional_expansion_type_unification_error(self):
                "int%s, none")
         self.assertIn(msg % types.intp.bitwidth, str(e.exception))
 
+    def test_changing_tuple_type(self):
+        # test https://github.com/numba/numba/issues/7295
+        pyfunc = gen_changing_tuple_type
+        expected = list(pyfunc())
+        got = list(njit(pyfunc)())
+        self.assertEqual(expected, got)
+
+    def test_changing_number_type(self):
+        # additional test for https://github.com/numba/numba/issues/7295
+        pyfunc = gen_changing_number_type
+        expected = list(pyfunc())
+        got = list(njit(pyfunc)())
+        self.assertEqual(expected, got)
+
 
 def nrt_gen0(ary):
     for elem in ary: