# Buggy code
def run(self):
    """Run inline closure call pass."""
    # Analysis relies on ir.Del presence, strip out later
    pp = postproc.PostProcessor(self.func_ir)
    pp.run(True)

    modified = False
    work_list = list(self.func_ir.blocks.items())
    debug_print = _make_debug_print("InlineClosureCallPass")
    debug_print("START")
    while work_list:
        label, block = work_list.pop()
        for i, instr in enumerate(block.body):
            if isinstance(instr, ir.Assign):
                lhs = instr.target
                expr = instr.value
                if isinstance(expr, ir.Expr) and expr.op == "call":
                    call_name = guard(find_callname, self.func_ir, expr)
                    func_def = guard(get_definition, self.func_ir, expr.func)

                    if guard(
                        self._inline_reduction, work_list, block, i, expr, call_name
                    ):
                        modified = True
                        break  # because block structure changed

                    if guard(self._inline_closure, work_list, block, i, func_def):
                        modified = True
                        break  # because block structure changed

                    if guard(self._inline_stencil, instr, call_name, func_def):
                        modified = True

    if enable_inline_arraycall:
        # Identify loop structure
        if modified:
            # Need to do some cleanups if closure inlining kicked in
            merge_adjacent_blocks(self.func_ir.blocks)
        cfg = compute_cfg_from_blocks(self.func_ir.blocks)
        debug_print("start inline arraycall")
        _debug_dump(cfg)
        loops = cfg.loops()
        sized_loops = [(k, len(loops[k].body)) for k in loops.keys()]
        visited = []
        # We go over all loops, bigger loops first (outer first)
        for k, s in sorted(sized_loops, key=lambda tup: tup[1], reverse=True):
            visited.append(k)
            if guard(
                _inline_arraycall,
                self.func_ir,
                cfg,
                visited,
                loops[k],
                self.swapped,
                self.parallel_options.comprehension,
                self.typed,
            ):
                modified = True
        if modified:
            _fix_nested_array(self.func_ir)

    if modified:
        # run dead code elimination
        dead_code_elimination(self.func_ir)
        # do label renaming
        self.func_ir.blocks = rename_labels(self.func_ir.blocks)

    # inlining done, strip dels
    remove_dels(self.func_ir.blocks)

    debug_print("END")


# Traceback (ValueError)
Traceback (most recent call last):
File "test_inline.py", line 14, in <module>
print(fn())
File "numba\numba\dispatcher.py", line 420, in _compile_for_args
raise e
File "numba\numba\dispatcher.py", line 353, in _compile_for_args
return self.compile(tuple(argtypes))
File "numba\numba\compiler_lock.py", line 32, in _acquire_compile_lock
return func(*args, **kwargs)
File "numba\numba\dispatcher.py", line 768, in compile
cres = self._compiler.compile(args, return_type)
File "numba\numba\dispatcher.py", line 77, in compile
status, retval = self._compile_cached(args, return_type)
File "numba\numba\dispatcher.py", line 91, in _compile_cached
retval = self._compile_core(args, return_type)
File "numba\numba\dispatcher.py", line 109, in _compile_core
pipeline_class=self.pipeline_class)
File "numba\numba\compiler.py", line 551, in compile_extra
return pipeline.compile_extra(func)
File "numba\numba\compiler.py", line 331, in compile_extra
return self._compile_bytecode()
File "numba\numba\compiler.py", line 393, in _compile_bytecode
return self._compile_core()
File "numba\numba\compiler.py", line 373, in _compile_core
raise e
File "numba\numba\compiler.py", line 364, in _compile_core
pm.run(self.state)
File "numba\numba\compiler_machinery.py", line 347, in run
raise patched_exception
File "numba\numba\compiler_machinery.py", line 338, in run
self._runPass(idx, pass_inst, state)
File "numba\numba\compiler_lock.py", line 32, in _acquire_compile_lock
return func(*args, **kwargs)
File "numba\numba\compiler_machinery.py", line 302, in _runPass
mutated |= check(pss.run_pass, internal_state)
File "numba\numba\compiler_machinery.py", line 275, in check
mangled = func(compiler_state)
File "numba\numba\untyped_passes.py", line 312, in run_pass
state.func_ir.blocks = simplify_CFG(state.func_ir.blocks)
File "numba\numba\ir_utils.py", line 1237, in simplify_CFG
return rename_labels(blocks)
File "numba\numba\ir_utils.py", line 1188, in rename_labels
topo_order.remove(return_label)
ValueError: Failed in nopython mode pipeline (step: inline inlinable functions)
list.remove(x): x not in list

# Fixed code
def run(self):
    """Run inline closure call pass."""
    # Analysis relies on ir.Del presence, strip out later
    pp = postproc.PostProcessor(self.func_ir)
    pp.run(True)

    modified = False
    work_list = list(self.func_ir.blocks.items())
    debug_print = _make_debug_print("InlineClosureCallPass")
    debug_print("START")
    while work_list:
        label, block = work_list.pop()
        for i, instr in enumerate(block.body):
            if isinstance(instr, ir.Assign):
                lhs = instr.target
                expr = instr.value
                if isinstance(expr, ir.Expr) and expr.op == "call":
                    call_name = guard(find_callname, self.func_ir, expr)
                    func_def = guard(get_definition, self.func_ir, expr.func)

                    if guard(
                        self._inline_reduction, work_list, block, i, expr, call_name
                    ):
                        modified = True
                        break  # because block structure changed

                    if guard(self._inline_closure, work_list, block, i, func_def):
                        modified = True
                        break  # because block structure changed

                    if guard(self._inline_stencil, instr, call_name, func_def):
                        modified = True

    if enable_inline_arraycall:
        # Identify loop structure
        if modified:
            # Need to do some cleanups if closure inlining kicked in
            merge_adjacent_blocks(self.func_ir.blocks)
        cfg = compute_cfg_from_blocks(self.func_ir.blocks)
        debug_print("start inline arraycall")
        _debug_dump(cfg)
        loops = cfg.loops()
        sized_loops = [(k, len(loops[k].body)) for k in loops.keys()]
        visited = []
        # We go over all loops, bigger loops first (outer first)
        for k, s in sorted(sized_loops, key=lambda tup: tup[1], reverse=True):
            visited.append(k)
            if guard(
                _inline_arraycall,
                self.func_ir,
                cfg,
                visited,
                loops[k],
                self.swapped,
                self.parallel_options.comprehension,
                self.typed,
            ):
                modified = True
        if modified:
            _fix_nested_array(self.func_ir)

    if modified:
        # clean up now dead/unreachable blocks, e.g. unconditionally raising
        # an exception in an inlined function would render some parts of the
        # inliner unreachable
        cfg = compute_cfg_from_blocks(self.func_ir.blocks)
        for dead in cfg.dead_nodes():
            del self.func_ir.blocks[dead]

        # run dead code elimination
        dead_code_elimination(self.func_ir)
        # do label renaming
        self.func_ir.blocks = rename_labels(self.func_ir.blocks)

    # inlining done, strip dels
    remove_dels(self.func_ir.blocks)

    debug_print("END")