# Buggy code
def register_binary_operator_kernel(op, kernel, inplace=False):
    def lower_binary_operator(context, builder, sig, args):
        return numpy_ufunc_kernel(
            context, builder, sig, args, kernel, explicit_output=False
        )

    def lower_inplace_operator(context, builder, sig, args):
        # The visible signature is (A, B) -> A
        # The implementation's signature (with explicit output)
        # is (A, B, A) -> A
        args = args + (args[0],)
        sig = typing.signature(sig.return_type, *sig.args + (sig.args[0],))
        return numpy_ufunc_kernel(
            context, builder, sig, args, kernel, explicit_output=True
        )

    _any = types.Any
    _arr_kind = types.Array
    formal_sigs = [(_arr_kind, _arr_kind), (_any, _arr_kind), (_arr_kind, _any)]
    for sig in formal_sigs:
        if not inplace:
            lower(op, *sig)(lower_binary_operator)
        else:
            lower(op, *sig)(lower_inplace_operator)


# Traceback (TypeError)
TypeError                                 Traceback (most recent call last)
~/dev/numba/numba/errors.py in new_error_context(fmt_, *args, **kwargs)
660     try:
--> 661         yield
662     except NumbaError as e:

~/dev/numba/numba/lowering.py in lower_block(self, block)
257                                    loc=self.loc, errcls_=defaulterrcls):
--> 258                 self.lower_inst(inst)
259

~/dev/numba/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)

~/dev/numba/numba/lowering.py in lower_assign(self, ty, inst)
458         elif isinstance(value, ir.Expr):
--> 459             return self.lower_expr(ty, value)
460

~/dev/numba/numba/lowering.py in lower_expr(self, resty, expr)
917         elif expr.op == 'call':
--> 918             res = self.lower_call(resty, expr)
919             return res

~/dev/numba/numba/lowering.py in lower_call(self, resty, expr)
710         else:
--> 711             res = self._lower_call_normal(fnty, expr, signature)
712

~/dev/numba/numba/lowering.py in _lower_call_normal(self, fnty, expr, signature)
889
--> 890         res = impl(self.builder, argvals, self.loc)
891         return res

~/dev/numba/numba/targets/base.py in __call__(self, builder, args, loc)
1131     def __call__(self, builder, args, loc=None):
-> 1132         res = self._imp(self._context, builder, self._sig, args, loc=loc)
1133         self._context.add_linking_libs(getattr(self, 'libs', ()))

~/dev/numba/numba/targets/base.py in wrapper(*args, **kwargs)
1156             kwargs.pop('loc')     # drop unused loc
-> 1157             return fn(*args, **kwargs)
1158

~/dev/numba/numba/targets/npyimpl.py in lower_inplace_operator(context, builder, sig, args)
497         # is (A, B, A) -> A
--> 498         args = args + (args[0],)
499         sig = typing.signature(sig.return_type, *sig.args + (sig.args[0],))

TypeError: can only concatenate list (not "tuple") to list

During handling of the above exception, another exception occurred:

LoweringError                             Traceback (most recent call last)
<ipython-input-5-a36eda57cdc1> in <module>
----> 1 f(A)

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

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

~/dev/numba/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

~/dev/numba/numba/dispatcher.py in compile(self, sig)
657
658             self._cache_misses[sig] += 1
--> 659             cres = self._compiler.compile(args, return_type)
660             self.add_overload(cres)
661             self._cache.save_overload(sig, cres)

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

~/dev/numba/numba/compiler.py in compile_extra(typingctx, targetctx, func, args, return_type, flags, locals, library, pipeline_class)
953     pipeline = pipeline_class(typingctx, targetctx, library,
954                               args, return_type, flags, locals)
--> 955     return pipeline.compile_extra(func)
956
957

~/dev/numba/numba/compiler.py in compile_extra(self, func)
375         self.lifted = ()
376         self.lifted_from = None
--> 377         return self._compile_bytecode()
378
379     def compile_ir(self, func_ir, lifted=(), lifted_from=None):

~/dev/numba/numba/compiler.py in _compile_bytecode(self)
884         """
885         assert self.func_ir is None
--> 886         return self._compile_core()
887
888     def _compile_ir(self):

~/dev/numba/numba/compiler.py in _compile_core(self)
871         self.define_pipelines(pm)
872         pm.finalize()
--> 873         res = pm.run(self.status)
874         if res is not None:
875             # Early pipeline completion

~/dev/numba/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

~/dev/numba/numba/compiler.py in run(self, status)
252                     # No more fallback pipelines?
253                     if is_final_pipeline:
--> 254                         raise patched_exception
255                     # Go to next fallback pipeline
256                     else:

~/dev/numba/numba/compiler.py in run(self, status)
243                 try:
244                     event("-- %s" % stage_name)
--> 245                     stage()
246                 except _EarlyPipelineCompletion as e:
247                     return e.result

~/dev/numba/numba/compiler.py in stage_nopython_backend(self)
745         """
746         lowerfn = self.backend_nopython_mode
--> 747         self._backend(lowerfn, objectmode=False)
748
749     def stage_compile_interp_mode(self):

~/dev/numba/numba/compiler.py in _backend(self, lowerfn, objectmode)
685             self.library.enable_object_caching()
686
--> 687         lowered = lowerfn()
688         signature = typing.signature(self.return_type, *self.args)
689         self.cr = compile_result(

~/dev/numba/numba/compiler.py in backend_nopython_mode(self)
672                 self.calltypes,
673                 self.flags,
--> 674                 self.metadata)
675
676     def _backend(self, lowerfn, objectmode):

~/dev/numba/numba/compiler.py in native_lowering_stage(targetctx, library, interp, typemap, restype, calltypes, flags, metadata)
1122         lower = lowering.Lower(targetctx, library, fndesc, interp,
1123                                metadata=metadata)
-> 1124         lower.lower()
1125         if not flags.no_cpython_wrapper:
1126             lower.create_cpython_wrapper(flags.release_gil)

~/dev/numba/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)

~/dev/numba/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

~/dev/numba/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()

~/dev/numba/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):

~/dev/miniconda3/envs/DEV/lib/python3.7/contextlib.py in __exit__(self, type, value, traceback)
128                 value = type()
129             try:
--> 130                 self.gen.throw(type, value, traceback)
131             except StopIteration as exc:
132                 # Suppress StopIteration *unless* it's the same exception that

~/dev/numba/numba/errors.py in new_error_context(fmt_, *args, **kwargs)
667         from numba import config
668         tb = sys.exc_info()[2] if config.FULL_TRACEBACKS else None
--> 669         six.reraise(type(newerr), newerr, tb)
670
671

~/dev/numba/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)
can only concatenate list (not "tuple") to list

File "<ipython-input-4-a98347f692b7>", line 3:
def f(A):
return operator.iadd(A, A)
^

[1] During: lowering "$0.5 = call $0.2(A, A, func=$0.2, args=[Var(A, <ipython-input-4-a98347f692b7> (3)), Var(A, <ipython-input-4-a98347f692b7> (3))], kws=(), vararg=None)" at <ipython-input-4-a98347f692b7> (3)

# Fixed code
def register_binary_operator_kernel(op, kernel, inplace=False):
    def lower_binary_operator(context, builder, sig, args):
        return numpy_ufunc_kernel(
            context, builder, sig, args, kernel, explicit_output=False
        )

    def lower_inplace_operator(context, builder, sig, args):
        # The visible signature is (A, B) -> A
        # The implementation's signature (with explicit output)
        # is (A, B, A) -> A
        args = tuple(args) + (args[0],)
        sig = typing.signature(sig.return_type, *sig.args + (sig.args[0],))
        return numpy_ufunc_kernel(
            context, builder, sig, args, kernel, explicit_output=True
        )

    _any = types.Any
    _arr_kind = types.Array
    formal_sigs = [(_arr_kind, _arr_kind), (_any, _arr_kind), (_arr_kind, _any)]
    for sig in formal_sigs:
        if not inplace:
            lower(op, *sig)(lower_binary_operator)
        else:
            lower(op, *sig)(lower_inplace_operator)