We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Crash when returning a named tuple of lists
This crashes with a segmentation fault:

```
Point = collections.namedtuple('Point', ('x', 'y'))

@jit(nopython=True)
def list_tup(n):
    return Point(list(range(n)), [42])

print(list_tup(3))
```

gdb shows it crashing in `wrapper..main..list_tup$1.int64`. There's probably a NRT incref missing somewhere.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `numba/targets/tupleobj.py`
Content:
```
1 """
2 Implementation of tuple objects
3 """
4 
5 from llvmlite import ir
6 import llvmlite.llvmpy.core as lc
7 
8 from .imputils import (builtin, builtin_attr, implement, impl_attribute,
9                        impl_attribute_generic, iternext_impl, struct_factory,
10                        impl_ret_borrowed, impl_ret_untracked)
11 from .. import typing, types, cgutils
12 
13 
14 def generic_compare(context, builder, key, argtypes, args):
15     """
16     Compare the given LLVM values of the given Numba types using
17     the comparison *key* (e.g. '==').  The values are first cast to
18     a common safe conversion type.
19     """
20     at, bt = argtypes
21     av, bv = args
22     ty = context.typing_context.unify_types(at, bt)
23     cav = context.cast(builder, av, at, ty)
24     cbv = context.cast(builder, bv, bt, ty)
25     cmpsig = typing.signature(types.boolean, ty, ty)
26     cmpfunc = context.get_function(key, cmpsig)
27     return cmpfunc(builder, (cav, cbv))
28 
29 
30 @builtin
31 @implement(types.NamedTupleClass, types.VarArg(types.Any))
32 def namedtuple_constructor(context, builder, sig, args):
33     # A namedtuple has the same representation as a regular tuple
34     return context.make_tuple(builder, sig.return_type, args)
35 
36 @builtin
37 @implement(types.len_type, types.Kind(types.BaseTuple))
38 def tuple_len(context, builder, sig, args):
39     tupty, = sig.args
40     retty = sig.return_type
41     res = context.get_constant(retty, len(tupty.types))
42     return impl_ret_untracked(context, builder, sig.return_type, res)
43 
44 @builtin
45 @implement(bool, types.Kind(types.BaseTuple))
46 def tuple_bool(context, builder, sig, args):
47     tupty, = sig.args
48     if len(tupty):
49         return cgutils.true_bit
50     else:
51         return cgutils.false_bit
52 
53 def tuple_cmp_ordered(context, builder, op, sig, args):
54     tu, tv = sig.args
55     u, v = args
56     res = cgutils.alloca_once_value(builder, cgutils.true_bit)
57     bbend = builder.append_basic_block("cmp_end")
58     for i, (ta, tb) in enumerate(zip(tu.types, tv.types)):
59         a = builder.extract_value(u, i)
60         b = builder.extract_value(v, i)
61         not_equal = generic_compare(context, builder, '!=', (ta, tb), (a, b))
62         with builder.if_then(not_equal):
63             pred = generic_compare(context, builder, op, (ta, tb), (a, b))
64             builder.store(pred, res)
65             builder.branch(bbend)
66     # Everything matched equal => compare lengths
67     len_compare = eval("%d %s %d" % (len(tu.types), op, len(tv.types)))
68     pred = context.get_constant(types.boolean, len_compare)
69     builder.store(pred, res)
70     builder.branch(bbend)
71     builder.position_at_end(bbend)
72     return builder.load(res)
73 
74 @builtin
75 @implement('==', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))
76 def tuple_eq(context, builder, sig, args):
77     tu, tv = sig.args
78     u, v = args
79     if len(tu.types) != len(tv.types):
80         res = context.get_constant(types.boolean, False)
81         return impl_ret_untracked(context, builder, sig.return_type, res)
82     res = context.get_constant(types.boolean, True)
83     for i, (ta, tb) in enumerate(zip(tu.types, tv.types)):
84         a = builder.extract_value(u, i)
85         b = builder.extract_value(v, i)
86         pred = generic_compare(context, builder, "==", (ta, tb), (a, b))
87         res = builder.and_(res, pred)
88     return impl_ret_untracked(context, builder, sig.return_type, res)
89 
90 @builtin
91 @implement('!=', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))
92 def tuple_ne(context, builder, sig, args):
93     res = builder.not_(tuple_eq(context, builder, sig, args))
94     return impl_ret_untracked(context, builder, sig.return_type, res)
95 
96 @builtin
97 @implement('<', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))
98 def tuple_lt(context, builder, sig, args):
99     res = tuple_cmp_ordered(context, builder, '<', sig, args)
100     return impl_ret_untracked(context, builder, sig.return_type, res)
101 
102 @builtin
103 @implement('<=', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))
104 def tuple_le(context, builder, sig, args):
105     res = tuple_cmp_ordered(context, builder, '<=', sig, args)
106     return impl_ret_untracked(context, builder, sig.return_type, res)
107 
108 @builtin
109 @implement('>', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))
110 def tuple_gt(context, builder, sig, args):
111     res = tuple_cmp_ordered(context, builder, '>', sig, args)
112     return impl_ret_untracked(context, builder, sig.return_type, res)
113 
114 @builtin
115 @implement('>=', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))
116 def tuple_ge(context, builder, sig, args):
117     res = tuple_cmp_ordered(context, builder, '>=', sig, args)
118     return impl_ret_untracked(context, builder, sig.return_type, res)
119 
120 
121 @builtin_attr
122 @impl_attribute_generic(types.Kind(types.BaseNamedTuple))
123 def namedtuple_getattr(context, builder, typ, value, attr):
124     """
125     Fetch a namedtuple's field.
126     """
127     index = typ.fields.index(attr)
128     return builder.extract_value(value, index)
129 
130 
131 #------------------------------------------------------------------------------
132 # Tuple iterators
133 
134 @struct_factory(types.UniTupleIter)
135 def make_unituple_iter(tupiter):
136     """
137     Return the Structure representation of the given *tupiter* (an
138     instance of types.UniTupleIter).
139     """
140     return cgutils.create_struct_proxy(tupiter)
141 
142 
143 @builtin
144 @implement('getiter', types.Kind(types.UniTuple))
145 @implement('getiter', types.Kind(types.NamedUniTuple))
146 def getiter_unituple(context, builder, sig, args):
147     [tupty] = sig.args
148     [tup] = args
149 
150     tupitercls = make_unituple_iter(types.UniTupleIter(tupty))
151     iterval = tupitercls(context, builder)
152 
153     index0 = context.get_constant(types.intp, 0)
154     indexptr = cgutils.alloca_once(builder, index0.type)
155     builder.store(index0, indexptr)
156 
157     iterval.index = indexptr
158     iterval.tuple = tup
159 
160     res = iterval._getvalue()
161     return impl_ret_borrowed(context, builder, sig.return_type, res)
162 
163 
164 @builtin
165 @implement('iternext', types.Kind(types.UniTupleIter))
166 @iternext_impl
167 def iternext_unituple(context, builder, sig, args, result):
168     [tupiterty] = sig.args
169     [tupiter] = args
170 
171     tupitercls = make_unituple_iter(tupiterty)
172     iterval = tupitercls(context, builder, value=tupiter)
173     tup = iterval.tuple
174     idxptr = iterval.index
175     idx = builder.load(idxptr)
176     count = context.get_constant(types.intp, tupiterty.unituple.count)
177 
178     is_valid = builder.icmp(lc.ICMP_SLT, idx, count)
179     result.set_valid(is_valid)
180 
181     with builder.if_then(is_valid):
182         getitem_sig = typing.signature(tupiterty.unituple.dtype,
183                                        tupiterty.unituple,
184                                        types.intp)
185         getitem_out = getitem_unituple(context, builder, getitem_sig,
186                                        [tup, idx])
187         result.yield_(getitem_out)
188         nidx = builder.add(idx, context.get_constant(types.intp, 1))
189         builder.store(nidx, iterval.index)
190 
191 
192 @builtin
193 @implement('getitem', types.Kind(types.UniTuple), types.intp)
194 @implement('getitem', types.Kind(types.NamedUniTuple), types.intp)
195 def getitem_unituple(context, builder, sig, args):
196     tupty, _ = sig.args
197     tup, idx = args
198 
199     bbelse = builder.append_basic_block("switch.else")
200     bbend = builder.append_basic_block("switch.end")
201     switch = builder.switch(idx, bbelse, n=tupty.count)
202 
203     with builder.goto_block(bbelse):
204         context.call_conv.return_user_exc(builder, IndexError,
205                                           ("tuple index out of range",))
206 
207     lrtty = context.get_value_type(tupty.dtype)
208     with builder.goto_block(bbend):
209         phinode = builder.phi(lrtty)
210 
211     for i in range(tupty.count):
212         ki = context.get_constant(types.intp, i)
213         bbi = builder.append_basic_block("switch.%d" % i)
214         switch.add_case(ki, bbi)
215         with builder.goto_block(bbi):
216             value = builder.extract_value(tup, i)
217             builder.branch(bbend)
218             phinode.add_incoming(value, bbi)
219 
220     builder.position_at_end(bbend)
221     res = phinode
222     assert sig.return_type == tupty.dtype
223     return impl_ret_borrowed(context, builder, sig.return_type, res)
224
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/numba/targets/tupleobj.py b/numba/targets/tupleobj.py
--- a/numba/targets/tupleobj.py
+++ b/numba/targets/tupleobj.py
@@ -31,7 +31,9 @@
 @implement(types.NamedTupleClass, types.VarArg(types.Any))
 def namedtuple_constructor(context, builder, sig, args):
     # A namedtuple has the same representation as a regular tuple
-    return context.make_tuple(builder, sig.return_type, args)
+    res = context.make_tuple(builder, sig.return_type, args)
+    # The tuple's contents are borrowed
+    return impl_ret_borrowed(context, builder, sig.return_type, res)
 
 @builtin
 @implement(types.len_type, types.Kind(types.BaseTuple))
@@ -125,7 +127,8 @@
     Fetch a namedtuple's field.
     """
     index = typ.fields.index(attr)
-    return builder.extract_value(value, index)
+    res = builder.extract_value(value, index)
+    return impl_ret_borrowed(context, builder, typ[index], res)
 
 
 #------------------------------------------------------------------------------

{"golden_diff": "diff --git a/numba/targets/tupleobj.py b/numba/targets/tupleobj.py\n--- a/numba/targets/tupleobj.py\n+++ b/numba/targets/tupleobj.py\n@@ -31,7 +31,9 @@\n @implement(types.NamedTupleClass, types.VarArg(types.Any))\n def namedtuple_constructor(context, builder, sig, args):\n     # A namedtuple has the same representation as a regular tuple\n-    return context.make_tuple(builder, sig.return_type, args)\n+    res = context.make_tuple(builder, sig.return_type, args)\n+    # The tuple's contents are borrowed\n+    return impl_ret_borrowed(context, builder, sig.return_type, res)\n \n @builtin\n @implement(types.len_type, types.Kind(types.BaseTuple))\n@@ -125,7 +127,8 @@\n     Fetch a namedtuple's field.\n     \"\"\"\n     index = typ.fields.index(attr)\n-    return builder.extract_value(value, index)\n+    res = builder.extract_value(value, index)\n+    return impl_ret_borrowed(context, builder, typ[index], res)\n \n \n #------------------------------------------------------------------------------\n", "issue": "Crash when returning a named tuple of lists\nThis crashes with a segmentation fault:\n\n```\nPoint = collections.namedtuple('Point', ('x', 'y'))\n\n@jit(nopython=True)\ndef list_tup(n):\n    return Point(list(range(n)), [42])\n\nprint(list_tup(3))\n```\n\ngdb shows it crashing in `wrapper..main..list_tup$1.int64`. There's probably a NRT incref missing somewhere.\n\n", "before_files": [{"content": "\"\"\"\nImplementation of tuple objects\n\"\"\"\n\nfrom llvmlite import ir\nimport llvmlite.llvmpy.core as lc\n\nfrom .imputils import (builtin, builtin_attr, implement, impl_attribute,\n                       impl_attribute_generic, iternext_impl, struct_factory,\n                       impl_ret_borrowed, impl_ret_untracked)\nfrom .. import typing, types, cgutils\n\n\ndef generic_compare(context, builder, key, argtypes, args):\n    \"\"\"\n    Compare the given LLVM values of the given Numba types using\n    the comparison *key* (e.g. '==').  The values are first cast to\n    a common safe conversion type.\n    \"\"\"\n    at, bt = argtypes\n    av, bv = args\n    ty = context.typing_context.unify_types(at, bt)\n    cav = context.cast(builder, av, at, ty)\n    cbv = context.cast(builder, bv, bt, ty)\n    cmpsig = typing.signature(types.boolean, ty, ty)\n    cmpfunc = context.get_function(key, cmpsig)\n    return cmpfunc(builder, (cav, cbv))\n\n\n@builtin\n@implement(types.NamedTupleClass, types.VarArg(types.Any))\ndef namedtuple_constructor(context, builder, sig, args):\n    # A namedtuple has the same representation as a regular tuple\n    return context.make_tuple(builder, sig.return_type, args)\n\n@builtin\n@implement(types.len_type, types.Kind(types.BaseTuple))\ndef tuple_len(context, builder, sig, args):\n    tupty, = sig.args\n    retty = sig.return_type\n    res = context.get_constant(retty, len(tupty.types))\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement(bool, types.Kind(types.BaseTuple))\ndef tuple_bool(context, builder, sig, args):\n    tupty, = sig.args\n    if len(tupty):\n        return cgutils.true_bit\n    else:\n        return cgutils.false_bit\n\ndef tuple_cmp_ordered(context, builder, op, sig, args):\n    tu, tv = sig.args\n    u, v = args\n    res = cgutils.alloca_once_value(builder, cgutils.true_bit)\n    bbend = builder.append_basic_block(\"cmp_end\")\n    for i, (ta, tb) in enumerate(zip(tu.types, tv.types)):\n        a = builder.extract_value(u, i)\n        b = builder.extract_value(v, i)\n        not_equal = generic_compare(context, builder, '!=', (ta, tb), (a, b))\n        with builder.if_then(not_equal):\n            pred = generic_compare(context, builder, op, (ta, tb), (a, b))\n            builder.store(pred, res)\n            builder.branch(bbend)\n    # Everything matched equal => compare lengths\n    len_compare = eval(\"%d %s %d\" % (len(tu.types), op, len(tv.types)))\n    pred = context.get_constant(types.boolean, len_compare)\n    builder.store(pred, res)\n    builder.branch(bbend)\n    builder.position_at_end(bbend)\n    return builder.load(res)\n\n@builtin\n@implement('==', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_eq(context, builder, sig, args):\n    tu, tv = sig.args\n    u, v = args\n    if len(tu.types) != len(tv.types):\n        res = context.get_constant(types.boolean, False)\n        return impl_ret_untracked(context, builder, sig.return_type, res)\n    res = context.get_constant(types.boolean, True)\n    for i, (ta, tb) in enumerate(zip(tu.types, tv.types)):\n        a = builder.extract_value(u, i)\n        b = builder.extract_value(v, i)\n        pred = generic_compare(context, builder, \"==\", (ta, tb), (a, b))\n        res = builder.and_(res, pred)\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement('!=', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_ne(context, builder, sig, args):\n    res = builder.not_(tuple_eq(context, builder, sig, args))\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement('<', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_lt(context, builder, sig, args):\n    res = tuple_cmp_ordered(context, builder, '<', sig, args)\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement('<=', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_le(context, builder, sig, args):\n    res = tuple_cmp_ordered(context, builder, '<=', sig, args)\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement('>', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_gt(context, builder, sig, args):\n    res = tuple_cmp_ordered(context, builder, '>', sig, args)\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement('>=', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_ge(context, builder, sig, args):\n    res = tuple_cmp_ordered(context, builder, '>=', sig, args)\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n\n@builtin_attr\n@impl_attribute_generic(types.Kind(types.BaseNamedTuple))\ndef namedtuple_getattr(context, builder, typ, value, attr):\n    \"\"\"\n    Fetch a namedtuple's field.\n    \"\"\"\n    index = typ.fields.index(attr)\n    return builder.extract_value(value, index)\n\n\n#------------------------------------------------------------------------------\n# Tuple iterators\n\n@struct_factory(types.UniTupleIter)\ndef make_unituple_iter(tupiter):\n    \"\"\"\n    Return the Structure representation of the given *tupiter* (an\n    instance of types.UniTupleIter).\n    \"\"\"\n    return cgutils.create_struct_proxy(tupiter)\n\n\n@builtin\n@implement('getiter', types.Kind(types.UniTuple))\n@implement('getiter', types.Kind(types.NamedUniTuple))\ndef getiter_unituple(context, builder, sig, args):\n    [tupty] = sig.args\n    [tup] = args\n\n    tupitercls = make_unituple_iter(types.UniTupleIter(tupty))\n    iterval = tupitercls(context, builder)\n\n    index0 = context.get_constant(types.intp, 0)\n    indexptr = cgutils.alloca_once(builder, index0.type)\n    builder.store(index0, indexptr)\n\n    iterval.index = indexptr\n    iterval.tuple = tup\n\n    res = iterval._getvalue()\n    return impl_ret_borrowed(context, builder, sig.return_type, res)\n\n\n@builtin\n@implement('iternext', types.Kind(types.UniTupleIter))\n@iternext_impl\ndef iternext_unituple(context, builder, sig, args, result):\n    [tupiterty] = sig.args\n    [tupiter] = args\n\n    tupitercls = make_unituple_iter(tupiterty)\n    iterval = tupitercls(context, builder, value=tupiter)\n    tup = iterval.tuple\n    idxptr = iterval.index\n    idx = builder.load(idxptr)\n    count = context.get_constant(types.intp, tupiterty.unituple.count)\n\n    is_valid = builder.icmp(lc.ICMP_SLT, idx, count)\n    result.set_valid(is_valid)\n\n    with builder.if_then(is_valid):\n        getitem_sig = typing.signature(tupiterty.unituple.dtype,\n                                       tupiterty.unituple,\n                                       types.intp)\n        getitem_out = getitem_unituple(context, builder, getitem_sig,\n                                       [tup, idx])\n        result.yield_(getitem_out)\n        nidx = builder.add(idx, context.get_constant(types.intp, 1))\n        builder.store(nidx, iterval.index)\n\n\n@builtin\n@implement('getitem', types.Kind(types.UniTuple), types.intp)\n@implement('getitem', types.Kind(types.NamedUniTuple), types.intp)\ndef getitem_unituple(context, builder, sig, args):\n    tupty, _ = sig.args\n    tup, idx = args\n\n    bbelse = builder.append_basic_block(\"switch.else\")\n    bbend = builder.append_basic_block(\"switch.end\")\n    switch = builder.switch(idx, bbelse, n=tupty.count)\n\n    with builder.goto_block(bbelse):\n        context.call_conv.return_user_exc(builder, IndexError,\n                                          (\"tuple index out of range\",))\n\n    lrtty = context.get_value_type(tupty.dtype)\n    with builder.goto_block(bbend):\n        phinode = builder.phi(lrtty)\n\n    for i in range(tupty.count):\n        ki = context.get_constant(types.intp, i)\n        bbi = builder.append_basic_block(\"switch.%d\" % i)\n        switch.add_case(ki, bbi)\n        with builder.goto_block(bbi):\n            value = builder.extract_value(tup, i)\n            builder.branch(bbend)\n            phinode.add_incoming(value, bbi)\n\n    builder.position_at_end(bbend)\n    res = phinode\n    assert sig.return_type == tupty.dtype\n    return impl_ret_borrowed(context, builder, sig.return_type, res)\n", "path": "numba/targets/tupleobj.py"}], "after_files": [{"content": "\"\"\"\nImplementation of tuple objects\n\"\"\"\n\nfrom llvmlite import ir\nimport llvmlite.llvmpy.core as lc\n\nfrom .imputils import (builtin, builtin_attr, implement, impl_attribute,\n                       impl_attribute_generic, iternext_impl, struct_factory,\n                       impl_ret_borrowed, impl_ret_untracked)\nfrom .. import typing, types, cgutils\n\n\ndef generic_compare(context, builder, key, argtypes, args):\n    \"\"\"\n    Compare the given LLVM values of the given Numba types using\n    the comparison *key* (e.g. '==').  The values are first cast to\n    a common safe conversion type.\n    \"\"\"\n    at, bt = argtypes\n    av, bv = args\n    ty = context.typing_context.unify_types(at, bt)\n    cav = context.cast(builder, av, at, ty)\n    cbv = context.cast(builder, bv, bt, ty)\n    cmpsig = typing.signature(types.boolean, ty, ty)\n    cmpfunc = context.get_function(key, cmpsig)\n    return cmpfunc(builder, (cav, cbv))\n\n\n@builtin\n@implement(types.NamedTupleClass, types.VarArg(types.Any))\ndef namedtuple_constructor(context, builder, sig, args):\n    # A namedtuple has the same representation as a regular tuple\n    res = context.make_tuple(builder, sig.return_type, args)\n    # The tuple's contents are borrowed\n    return impl_ret_borrowed(context, builder, sig.return_type, res)\n\n@builtin\n@implement(types.len_type, types.Kind(types.BaseTuple))\ndef tuple_len(context, builder, sig, args):\n    tupty, = sig.args\n    retty = sig.return_type\n    res = context.get_constant(retty, len(tupty.types))\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement(bool, types.Kind(types.BaseTuple))\ndef tuple_bool(context, builder, sig, args):\n    tupty, = sig.args\n    if len(tupty):\n        return cgutils.true_bit\n    else:\n        return cgutils.false_bit\n\ndef tuple_cmp_ordered(context, builder, op, sig, args):\n    tu, tv = sig.args\n    u, v = args\n    res = cgutils.alloca_once_value(builder, cgutils.true_bit)\n    bbend = builder.append_basic_block(\"cmp_end\")\n    for i, (ta, tb) in enumerate(zip(tu.types, tv.types)):\n        a = builder.extract_value(u, i)\n        b = builder.extract_value(v, i)\n        not_equal = generic_compare(context, builder, '!=', (ta, tb), (a, b))\n        with builder.if_then(not_equal):\n            pred = generic_compare(context, builder, op, (ta, tb), (a, b))\n            builder.store(pred, res)\n            builder.branch(bbend)\n    # Everything matched equal => compare lengths\n    len_compare = eval(\"%d %s %d\" % (len(tu.types), op, len(tv.types)))\n    pred = context.get_constant(types.boolean, len_compare)\n    builder.store(pred, res)\n    builder.branch(bbend)\n    builder.position_at_end(bbend)\n    return builder.load(res)\n\n@builtin\n@implement('==', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_eq(context, builder, sig, args):\n    tu, tv = sig.args\n    u, v = args\n    if len(tu.types) != len(tv.types):\n        res = context.get_constant(types.boolean, False)\n        return impl_ret_untracked(context, builder, sig.return_type, res)\n    res = context.get_constant(types.boolean, True)\n    for i, (ta, tb) in enumerate(zip(tu.types, tv.types)):\n        a = builder.extract_value(u, i)\n        b = builder.extract_value(v, i)\n        pred = generic_compare(context, builder, \"==\", (ta, tb), (a, b))\n        res = builder.and_(res, pred)\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement('!=', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_ne(context, builder, sig, args):\n    res = builder.not_(tuple_eq(context, builder, sig, args))\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement('<', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_lt(context, builder, sig, args):\n    res = tuple_cmp_ordered(context, builder, '<', sig, args)\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement('<=', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_le(context, builder, sig, args):\n    res = tuple_cmp_ordered(context, builder, '<=', sig, args)\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement('>', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_gt(context, builder, sig, args):\n    res = tuple_cmp_ordered(context, builder, '>', sig, args)\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n@builtin\n@implement('>=', types.Kind(types.BaseTuple), types.Kind(types.BaseTuple))\ndef tuple_ge(context, builder, sig, args):\n    res = tuple_cmp_ordered(context, builder, '>=', sig, args)\n    return impl_ret_untracked(context, builder, sig.return_type, res)\n\n\n@builtin_attr\n@impl_attribute_generic(types.Kind(types.BaseNamedTuple))\ndef namedtuple_getattr(context, builder, typ, value, attr):\n    \"\"\"\n    Fetch a namedtuple's field.\n    \"\"\"\n    index = typ.fields.index(attr)\n    res = builder.extract_value(value, index)\n    return impl_ret_borrowed(context, builder, typ[index], res)\n\n\n#------------------------------------------------------------------------------\n# Tuple iterators\n\n@struct_factory(types.UniTupleIter)\ndef make_unituple_iter(tupiter):\n    \"\"\"\n    Return the Structure representation of the given *tupiter* (an\n    instance of types.UniTupleIter).\n    \"\"\"\n    return cgutils.create_struct_proxy(tupiter)\n\n\n@builtin\n@implement('getiter', types.Kind(types.UniTuple))\n@implement('getiter', types.Kind(types.NamedUniTuple))\ndef getiter_unituple(context, builder, sig, args):\n    [tupty] = sig.args\n    [tup] = args\n\n    tupitercls = make_unituple_iter(types.UniTupleIter(tupty))\n    iterval = tupitercls(context, builder)\n\n    index0 = context.get_constant(types.intp, 0)\n    indexptr = cgutils.alloca_once(builder, index0.type)\n    builder.store(index0, indexptr)\n\n    iterval.index = indexptr\n    iterval.tuple = tup\n\n    res = iterval._getvalue()\n    return impl_ret_borrowed(context, builder, sig.return_type, res)\n\n\n@builtin\n@implement('iternext', types.Kind(types.UniTupleIter))\n@iternext_impl\ndef iternext_unituple(context, builder, sig, args, result):\n    [tupiterty] = sig.args\n    [tupiter] = args\n\n    tupitercls = make_unituple_iter(tupiterty)\n    iterval = tupitercls(context, builder, value=tupiter)\n    tup = iterval.tuple\n    idxptr = iterval.index\n    idx = builder.load(idxptr)\n    count = context.get_constant(types.intp, tupiterty.unituple.count)\n\n    is_valid = builder.icmp(lc.ICMP_SLT, idx, count)\n    result.set_valid(is_valid)\n\n    with builder.if_then(is_valid):\n        getitem_sig = typing.signature(tupiterty.unituple.dtype,\n                                       tupiterty.unituple,\n                                       types.intp)\n        getitem_out = getitem_unituple(context, builder, getitem_sig,\n                                       [tup, idx])\n        result.yield_(getitem_out)\n        nidx = builder.add(idx, context.get_constant(types.intp, 1))\n        builder.store(nidx, iterval.index)\n\n\n@builtin\n@implement('getitem', types.Kind(types.UniTuple), types.intp)\n@implement('getitem', types.Kind(types.NamedUniTuple), types.intp)\ndef getitem_unituple(context, builder, sig, args):\n    tupty, _ = sig.args\n    tup, idx = args\n\n    bbelse = builder.append_basic_block(\"switch.else\")\n    bbend = builder.append_basic_block(\"switch.end\")\n    switch = builder.switch(idx, bbelse, n=tupty.count)\n\n    with builder.goto_block(bbelse):\n        context.call_conv.return_user_exc(builder, IndexError,\n                                          (\"tuple index out of range\",))\n\n    lrtty = context.get_value_type(tupty.dtype)\n    with builder.goto_block(bbend):\n        phinode = builder.phi(lrtty)\n\n    for i in range(tupty.count):\n        ki = context.get_constant(types.intp, i)\n        bbi = builder.append_basic_block(\"switch.%d\" % i)\n        switch.add_case(ki, bbi)\n        with builder.goto_block(bbi):\n            value = builder.extract_value(tup, i)\n            builder.branch(bbend)\n            phinode.add_incoming(value, bbi)\n\n    builder.position_at_end(bbend)\n    res = phinode\n    assert sig.return_type == tupty.dtype\n    return impl_ret_borrowed(context, builder, sig.return_type, res)\n", "path": "numba/targets/tupleobj.py"}]}