# Buggy code
def raise_on_unsupported_feature(func_ir, typemap):
    """
    Helper function to walk IR and raise if it finds op codes
    that are unsupported. Could be extended to cover IR sequences
    as well as op codes. Intended use is to call it as a pipeline
    stage just prior to lowering to prevent LoweringErrors for known
    unsupported features.
    """
    gdb_calls = []  # accumulate calls to gdb/gdb_init

    # issue 2195: check for excessively large tuples
    for arg_name in func_ir.arg_names:
        if (
            arg_name in typemap
            and isinstance(typemap[arg_name], types.containers.UniTuple)
            and typemap[arg_name].count > 1000
        ):
            # Raise an exception when len(tuple) > 1000. The choice of this number (1000)
            # was entirely arbitrary
            msg = (
                "Tuple '{}' length must be smaller than 1000.\n"
                "Large tuples lead to the generation of a prohibitively large "
                "LLVM IR which causes excessive memory pressure "
                "and large compile times.\n"
                "As an alternative, the use of a 'list' is recommended in "
                "place of a 'tuple' as lists do not suffer from this problem.".format(
                    arg_name
                )
            )
            raise UnsupportedError(msg, func_ir.loc)

    for blk in func_ir.blocks.values():
        for stmt in blk.find_insts(ir.Assign):
            # This raises on finding `make_function`
            if isinstance(stmt.value, ir.Expr):
                if stmt.value.op == "make_function":
                    val = stmt.value

                    # See if the construct name can be refined
                    code = getattr(val, "code", None)
                    if code is not None:
                        # check if this is a closure, the co_name will
                        # be the captured function name which is not
                        # useful so be explicit
                        if getattr(val, "closure", None) is not None:
                            use = "<creating a function from a closure>"
                            expr = ""
                        else:
                            use = code.co_name
                            expr = "(%s) " % use
                    else:
                        use = "<could not ascertain use case>"
                        expr = ""

                    msg = (
                        "Numba encountered the use of a language "
                        "feature it does not support in this context: "
                        "%s (op code: make_function not supported). If "
                        "the feature is explicitly supported it is "
                        "likely that the result of the expression %s"
                        "is being used in an unsupported manner."
                    ) % (use, expr)
                    raise UnsupportedError(msg, stmt.value.loc)

            # this checks for gdb initilization calls, only one is permitted
            if isinstance(stmt.value, (ir.Global, ir.FreeVar)):
                val = stmt.value
                val = getattr(val, "value", None)
                if val is None:
                    continue

                # check global function
                found = False
                if isinstance(val, pytypes.FunctionType):
                    found = val in {numba.gdb, numba.gdb_init}
                if not found:  # freevar bind to intrinsic
                    found = getattr(val, "_name", "") == "gdb_internal"
                if found:
                    gdb_calls.append(stmt.loc)  # report last seen location

            # this checks that np.<type> was called if view is called
            if isinstance(stmt.value, ir.Expr):
                if stmt.value.op == "getattr" and stmt.value.attr == "view":
                    var = stmt.value.value.name
                    if isinstance(typemap[var], types.Array):
                        continue
                    df = func_ir.get_definition(var)
                    cn = guard(find_callname, func_ir, df)
                    if cn and cn[1] == "numpy":
                        ty = getattr(numpy, cn[0])
                        if numpy.issubdtype(ty, numpy.integer) or numpy.issubdtype(
                            ty, numpy.floating
                        ):
                            continue

                    vardescr = "" if var.startswith("$") else "'{}' ".format(var)
                    raise TypingError(
                        "'view' can only be called on NumPy dtypes, "
                        "try wrapping the variable {}with 'np.<dtype>()'".format(
                            vardescr
                        ),
                        loc=stmt.loc,
                    )

            # checks for globals that are also reflected
            if isinstance(stmt.value, ir.Global):
                ty = typemap[stmt.target.name]
                msg = (
                    "Writing to a %s defined in globals is not "
                    "supported as globals are considered compile-time "
                    "constants."
                )
                if getattr(ty, "reflected", False) or isinstance(ty, types.DictType):
                    raise TypingError(msg % ty, loc=stmt.loc)

    # There is more than one call to function gdb/gdb_init
    if len(gdb_calls) > 1:
        msg = (
            "Calling either numba.gdb() or numba.gdb_init() more than once "
            "in a function is unsupported (strange things happen!), use "
            "numba.gdb_breakpoint() to create additional breakpoints "
            "instead.\n\nRelevant documentation is available here:\n"
            "http://numba.pydata.org/numba-doc/latest/user/troubleshoot.html"
            "/troubleshoot.html#using-numba-s-direct-gdb-bindings-in-"
            "nopython-mode\n\nConflicting calls found at:\n %s"
        )
        buf = "\n".join([x.strformat() for x in gdb_calls])
        raise UnsupportedError(msg % buf)


# Traceback (NotImplementedError)
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/targets/base.py in get_constant_generic(self, builder, ty, val)
498         try:
--> 499             impl = self._get_constants.find((ty,))
500             return impl(self, builder, ty, val)

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/targets/base.py in find(self, sig)
49         if out is None:
---> 50             out = self._find(sig)
51             self._cache[sig] = out

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/targets/base.py in _find(self, sig)
58         else:
---> 59             raise NotImplementedError(self, sig)
60

NotImplementedError: (<numba.targets.base.OverloadSelector object at 0x7ff2ff01e7f0>, (reflected list(reflected list(array(int64, 2d, C))),))

During handling of the above exception, another exception occurred:

NotImplementedError                       Traceback (most recent call last)
~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/errors.py in new_error_context(fmt_, *args, **kwargs)
626     try:
--> 627         yield
628     except NumbaError as e:

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/lowering.py in lower_block(self, block)
257                                    loc=self.loc, errcls_=defaulterrcls):
--> 258                 self.lower_inst(inst)
259

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/lowering.py in lower_inst(self, inst)
300             ty = self.typeof(inst.target.name)
--> 301             val = self.lower_assign(ty, inst)
302             self.storevar(val, inst.target.name)

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/lowering.py in lower_assign(self, ty, inst)
448             res = self.context.get_constant_generic(self.builder, ty,
--> 449                                                     value.value)
450             self.incref(ty, res)

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/targets/base.py in get_constant_generic(self, builder, ty, val)
501         except NotImplementedError:
--> 502             raise NotImplementedError("Cannot lower constant of type '%s'" % (ty,))
503

NotImplementedError: Cannot lower constant of type 'reflected list(reflected list(array(int64, 2d, C)))'

During handling of the above exception, another exception occurred:

LoweringError                             Traceback (most recent call last)
<ipython-input-8-a8e8627a1b30> in <module>
----> 1 T_matrix(0)

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
367                     e.patch_message(''.join(e.args) + help_msg)
368             # ignore the FULL_TRACEBACKS config, this needs reporting!
--> 369             raise e
370
371     def inspect_llvm(self, signature=None):

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
324                 argtypes.append(self.typeof_pyval(a))
325         try:
--> 326             return self.compile(tuple(argtypes))
327         except errors.TypingError as e:
328             # Intercept typing error that may be due to an argument

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler_lock.py in _acquire_compile_lock(*args, **kwargs)
30         def _acquire_compile_lock(*args, **kwargs):
31             with self:
---> 32                 return func(*args, **kwargs)
33         return _acquire_compile_lock
34

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/dispatcher.py in compile(self, sig)
656
657             self._cache_misses[sig] += 1
--> 658             cres = self._compiler.compile(args, return_type)
659             self.add_overload(cres)
660             self._cache.save_overload(sig, cres)

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/dispatcher.py in compile(self, args, return_type)
80                                       args=args, return_type=return_type,
81                                       flags=flags, locals=self.locals,
---> 82                                       pipeline_class=self.pipeline_class)
83         # Check typing error if object mode is used
84         if cres.typing_error is not None and not flags.enable_pyobject:

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler.py in compile_extra(typingctx, targetctx, func, args, return_type, flags, locals, library, pipeline_class)
939     pipeline = pipeline_class(typingctx, targetctx, library,
940                               args, return_type, flags, locals)
--> 941     return pipeline.compile_extra(func)
942
943

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler.py in compile_extra(self, func)
370         self.lifted = ()
371         self.lifted_from = None
--> 372         return self._compile_bytecode()
373
374     def compile_ir(self, func_ir, lifted=(), lifted_from=None):

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler.py in _compile_bytecode(self)
870         """
871         assert self.func_ir is None
--> 872         return self._compile_core()
873
874     def _compile_ir(self):

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler.py in _compile_core(self)
857         self.define_pipelines(pm)
858         pm.finalize()
--> 859         res = pm.run(self.status)
860         if res is not None:
861             # Early pipeline completion

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler_lock.py in _acquire_compile_lock(*args, **kwargs)
30         def _acquire_compile_lock(*args, **kwargs):
31             with self:
---> 32                 return func(*args, **kwargs)
33         return _acquire_compile_lock
34

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler.py in run(self, status)
251                     # No more fallback pipelines?
252                     if is_final_pipeline:
--> 253                         raise patched_exception
254                     # Go to next fallback pipeline
255                     else:

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler.py in run(self, status)
242                 try:
243                     event(stage_name)
--> 244                     stage()
245                 except _EarlyPipelineCompletion as e:
246                     return e.result

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler.py in stage_nopython_backend(self)
729         """
730         lowerfn = self.backend_nopython_mode
--> 731         self._backend(lowerfn, objectmode=False)
732
733     def stage_compile_interp_mode(self):

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler.py in _backend(self, lowerfn, objectmode)
679             self.library.enable_object_caching()
680
--> 681         lowered = lowerfn()
682         signature = typing.signature(self.return_type, *self.args)
683         self.cr = compile_result(

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler.py in backend_nopython_mode(self)
666                 self.calltypes,
667                 self.flags,
--> 668                 self.metadata)
669
670     def _backend(self, lowerfn, objectmode):

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/compiler.py in native_lowering_stage(targetctx, library, interp, typemap, restype, calltypes, flags, metadata)
1061         lower = lowering.Lower(targetctx, library, fndesc, interp,
1062                                metadata=metadata)
-> 1063         lower.lower()
1064         if not flags.no_cpython_wrapper:
1065             lower.create_cpython_wrapper(flags.release_gil)

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/lowering.py in lower(self)
175         if self.generator_info is None:
176             self.genlower = None
--> 177             self.lower_normal_function(self.fndesc)
178         else:
179             self.genlower = self.GeneratorLower(self)

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/lowering.py in lower_normal_function(self, fndesc)
216         # Init argument values
217         self.extract_function_arguments()
--> 218         entry_block_tail = self.lower_function_body()
219
220         # Close tail of entry block

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/lowering.py in lower_function_body(self)
241             bb = self.blkmap[offset]
242             self.builder.position_at_end(bb)
--> 243             self.lower_block(block)
244
245         self.post_lower()

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/lowering.py in lower_block(self, block)
256             with new_error_context('lowering "{inst}" at {loc}', inst=inst,
257                                    loc=self.loc, errcls_=defaulterrcls):
--> 258                 self.lower_inst(inst)
259
260     def create_cpython_wrapper(self, release_gil=False):

~/Miscelania/anaconda3/lib/python3.6/contextlib.py in __exit__(self, type, value, traceback)
97                 value = type()
98             try:
---> 99                 self.gen.throw(type, value, traceback)
100             except StopIteration as exc:
101                 # Suppress StopIteration *unless* it's the same exception that

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/errors.py in new_error_context(fmt_, *args, **kwargs)
633         from numba import config
634         tb = sys.exc_info()[2] if config.FULL_TRACEBACKS else None
--> 635         six.reraise(type(newerr), newerr, tb)
636
637

~/Miscelania/anaconda3/lib/python3.6/site-packages/numba/six.py in reraise(tp, value, tb)
657         if value.__traceback__ is not tb:
658             raise value.with_traceback(tb)
--> 659         raise value
660
661 else:

LoweringError: Failed in nopython mode pipeline (step: nopython mode backend)
Cannot lower constant of type 'reflected list(reflected list(array(int64, 2d, C)))'

File "<ipython-input-6-c8c5dfd066cc>", line 17:
def T_matrix (phi):
return ts[0][0]*np.cos(phi)  - 1j*ts[3][3]*np.sin(phi)
^

[1] During: lowering "$0.1 = global(ts: [[matrix([[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]]), matrix([[0, 1, 0, 0],
[1, 0, 0, 0],
[0, 0, 0, 1],
[0, 0, 1, 0]]), matrix([[0.+0.j, 0.-1.j, 0.+0.j, 0.-0.j],
[0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.-0.j, 0.+0.j, 0.-1.j],
[0.+0.j, 0.+0.j, 0.+1.j, 0.+0.j]]), matrix([[ 1,  0,  0,  0],
[ 0, -1,  0,  0],
[ 0,  0,  1,  0],
[ 0,  0,  0, -1]])], [matrix([[0, 0, 1, 0],
[0, 0, 0, 1],
[1, 0, 0, 0],
[0, 1, 0, 0]]), matrix([[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 1, 0, 0],
[1, 0, 0, 0]]), matrix([[0.+0.j, 0.-0.j, 0.+0.j, 0.-1.j],
[0.+0.j, 0.+0.j, 0.+1.j, 0.+0.j],
[0.+0.j, 0.-1.j, 0.+0.j, 0.-0.j],
[0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j]]), matrix([[ 0,  0,  1,  0],
[ 0,  0,  0, -1],
[ 1,  0,  0,  0],
[ 0, -1,  0,  0]])], [matrix([[0.+0.j, 0.+0.j, 0.-1.j, 0.-0.j],
[0.+0.j, 0.+0.j, 0.-0.j, 0.-1.j],
[0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j]]), matrix([[0.+0.j, 0.+0.j, 0.-0.j, 0.-1.j],
[0.+0.j, 0.+0.j, 0.-1.j, 0.-0.j],
[0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j],
[0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j]]), matrix([[ 0.+0.j,  0.-0.j,  0.-0.j, -1.+0.j],
[ 0.+0.j,  0.+0.j,  1.-0.j,  0.-0.j],
[ 0.+0.j,  1.-0.j,  0.+0.j,  0.-0.j],
[-1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j]]), matrix([[ 0.+0.j,  0.+0.j,  0.-1.j,  0.-0.j],
[ 0.+0.j, -0.+0.j,  0.-0.j,  0.+1.j],
[ 0.+1.j,  0.+0.j,  0.+0.j,  0.+0.j],
[ 0.+0.j, -0.-1.j,  0.+0.j, -0.+0.j]])], [matrix([[ 1,  0,  0,  0],
[ 0,  1,  0,  0],
[ 0,  0, -1,  0],
[ 0,  0,  0, -1]]), matrix([[ 0,  1,  0,  0],
[ 1,  0,  0,  0],
[ 0,  0,  0, -1],
[ 0,  0, -1,  0]]), matrix([[ 0.+0.j,  0.-1.j,  0.+0.j,  0.-0.j],
[ 0.+1.j,  0.+0.j,  0.+0.j,  0.+0.j],
[ 0.+0.j,  0.-0.j, -0.+0.j,  0.+1.j],
[ 0.+0.j,  0.+0.j, -0.-1.j, -0.+0.j]]), matrix([[ 1,  0,  0,  0],
[ 0, -1,  0,  0],
[ 0,  0, -1,  0],
[ 0,  0,  0,  1]])]])" at <ipython-input-6-c8c5dfd066cc> (17)
-------------------------------------------------------------------------------
This should not have happened, a problem has occurred in Numba's internals.

Please report the error message and traceback, along with a minimal reproducer
at: https://github.com/numba/numba/issues/new

If more help is needed please feel free to speak to the Numba core developers
directly at: https://gitter.im/numba/numba

Thanks in advance for your help in improving Numba!

# Fixed code
def raise_on_unsupported_feature(func_ir, typemap):
    """
    Helper function to walk IR and raise if it finds op codes
    that are unsupported. Could be extended to cover IR sequences
    as well as op codes. Intended use is to call it as a pipeline
    stage just prior to lowering to prevent LoweringErrors for known
    unsupported features.
    """
    gdb_calls = []  # accumulate calls to gdb/gdb_init

    # issue 2195: check for excessively large tuples
    for arg_name in func_ir.arg_names:
        if (
            arg_name in typemap
            and isinstance(typemap[arg_name], types.containers.UniTuple)
            and typemap[arg_name].count > 1000
        ):
            # Raise an exception when len(tuple) > 1000. The choice of this number (1000)
            # was entirely arbitrary
            msg = (
                "Tuple '{}' length must be smaller than 1000.\n"
                "Large tuples lead to the generation of a prohibitively large "
                "LLVM IR which causes excessive memory pressure "
                "and large compile times.\n"
                "As an alternative, the use of a 'list' is recommended in "
                "place of a 'tuple' as lists do not suffer from this problem.".format(
                    arg_name
                )
            )
            raise UnsupportedError(msg, func_ir.loc)

    for blk in func_ir.blocks.values():
        for stmt in blk.find_insts(ir.Assign):
            # This raises on finding `make_function`
            if isinstance(stmt.value, ir.Expr):
                if stmt.value.op == "make_function":
                    val = stmt.value

                    # See if the construct name can be refined
                    code = getattr(val, "code", None)
                    if code is not None:
                        # check if this is a closure, the co_name will
                        # be the captured function name which is not
                        # useful so be explicit
                        if getattr(val, "closure", None) is not None:
                            use = "<creating a function from a closure>"
                            expr = ""
                        else:
                            use = code.co_name
                            expr = "(%s) " % use
                    else:
                        use = "<could not ascertain use case>"
                        expr = ""

                    msg = (
                        "Numba encountered the use of a language "
                        "feature it does not support in this context: "
                        "%s (op code: make_function not supported). If "
                        "the feature is explicitly supported it is "
                        "likely that the result of the expression %s"
                        "is being used in an unsupported manner."
                    ) % (use, expr)
                    raise UnsupportedError(msg, stmt.value.loc)

            # this checks for gdb initilization calls, only one is permitted
            if isinstance(stmt.value, (ir.Global, ir.FreeVar)):
                val = stmt.value
                val = getattr(val, "value", None)
                if val is None:
                    continue

                # check global function
                found = False
                if isinstance(val, pytypes.FunctionType):
                    found = val in {numba.gdb, numba.gdb_init}
                if not found:  # freevar bind to intrinsic
                    found = getattr(val, "_name", "") == "gdb_internal"
                if found:
                    gdb_calls.append(stmt.loc)  # report last seen location

            # this checks that np.<type> was called if view is called
            if isinstance(stmt.value, ir.Expr):
                if stmt.value.op == "getattr" and stmt.value.attr == "view":
                    var = stmt.value.value.name
                    if isinstance(typemap[var], types.Array):
                        continue
                    df = func_ir.get_definition(var)
                    cn = guard(find_callname, func_ir, df)
                    if cn and cn[1] == "numpy":
                        ty = getattr(numpy, cn[0])
                        if numpy.issubdtype(ty, numpy.integer) or numpy.issubdtype(
                            ty, numpy.floating
                        ):
                            continue

                    vardescr = "" if var.startswith("$") else "'{}' ".format(var)
                    raise TypingError(
                        "'view' can only be called on NumPy dtypes, "
                        "try wrapping the variable {}with 'np.<dtype>()'".format(
                            vardescr
                        ),
                        loc=stmt.loc,
                    )

            # checks for globals that are also reflected
            if isinstance(stmt.value, ir.Global):
                ty = typemap[stmt.target.name]
                msg = (
                    "The use of a %s type, assigned to variable '%s' in "
                    "globals, is not supported as globals are considered "
                    "compile-time constants and there is no known way to "
                    "compile a %s type as a constant."
                )
                if getattr(ty, "reflected", False) or isinstance(ty, types.DictType):
                    raise TypingError(msg % (ty, stmt.value.name, ty), loc=stmt.loc)

    # There is more than one call to function gdb/gdb_init
    if len(gdb_calls) > 1:
        msg = (
            "Calling either numba.gdb() or numba.gdb_init() more than once "
            "in a function is unsupported (strange things happen!), use "
            "numba.gdb_breakpoint() to create additional breakpoints "
            "instead.\n\nRelevant documentation is available here:\n"
            "http://numba.pydata.org/numba-doc/latest/user/troubleshoot.html"
            "/troubleshoot.html#using-numba-s-direct-gdb-bindings-in-"
            "nopython-mode\n\nConflicting calls found at:\n %s"
        )
        buf = "\n".join([x.strformat() for x in gdb_calls])
        raise UnsupportedError(msg % buf)