# Buggy code
def _arrayexpr_tree_to_ir(
    func_ir,
    typingctx,
    typemap,
    calltypes,
    equiv_set,
    init_block,
    expr_out_var,
    expr,
    parfor_index_tuple_var,
    all_parfor_indices,
    avail_vars,
):
    """generate IR from array_expr's expr tree recursively. Assign output to
    expr_out_var and returns the whole IR as a list of Assign nodes.
    """
    el_typ = typemap[expr_out_var.name]
    scope = expr_out_var.scope
    loc = expr_out_var.loc
    out_ir = []

    if isinstance(expr, tuple):
        op, arr_expr_args = expr
        arg_vars = []
        for arg in arr_expr_args:
            arg_out_var = ir.Var(scope, mk_unique_var("$arg_out_var"), loc)
            typemap[arg_out_var.name] = el_typ
            out_ir += _arrayexpr_tree_to_ir(
                func_ir,
                typingctx,
                typemap,
                calltypes,
                equiv_set,
                init_block,
                arg_out_var,
                arg,
                parfor_index_tuple_var,
                all_parfor_indices,
                avail_vars,
            )
            arg_vars.append(arg_out_var)
        if op in npydecl.supported_array_operators:
            el_typ1 = typemap[arg_vars[0].name]
            if len(arg_vars) == 2:
                el_typ2 = typemap[arg_vars[1].name]
                func_typ = typingctx.resolve_function_type(op, (el_typ1, el_typ), {})
                ir_expr = ir.Expr.binop(op, arg_vars[0], arg_vars[1], loc)
                if op == operator.truediv:
                    func_typ, ir_expr = _gen_np_divide(
                        arg_vars[0], arg_vars[1], out_ir, typemap
                    )
            else:
                func_typ = typingctx.resolve_function_type(op, (el_typ1,), {})
                ir_expr = ir.Expr.unary(op, arg_vars[0], loc)
            calltypes[ir_expr] = func_typ
            el_typ = func_typ.return_type
            out_ir.append(ir.Assign(ir_expr, expr_out_var, loc))
        for T in array_analysis.MAP_TYPES:
            if isinstance(op, T):
                # elif isinstance(op, (np.ufunc, DUFunc)):
                # function calls are stored in variables which are not removed
                # op is typing_key to the variables type
                func_var_name = _find_func_var(typemap, op, avail_vars)
                func_var = ir.Var(scope, mk_unique_var(func_var_name), loc)
                typemap[func_var.name] = typemap[func_var_name]
                func_var_def = func_ir.get_definition(func_var_name)
                if (
                    isinstance(func_var_def, ir.Expr)
                    and func_var_def.op == "getattr"
                    and func_var_def.attr == "sqrt"
                ):
                    g_math_var = ir.Var(scope, mk_unique_var("$math_g_var"), loc)
                    typemap[g_math_var.name] = types.misc.Module(math)
                    g_math = ir.Global("math", math, loc)
                    g_math_assign = ir.Assign(g_math, g_math_var, loc)
                    func_var_def = ir.Expr.getattr(g_math_var, "sqrt", loc)
                    out_ir.append(g_math_assign)
                #                     out_ir.append(func_var_def)
                ir_expr = ir.Expr.call(func_var, arg_vars, (), loc)
                call_typ = typemap[func_var.name].get_call_type(
                    typingctx, tuple(typemap[a.name] for a in arg_vars), {}
                )
                calltypes[ir_expr] = call_typ
                el_typ = call_typ.return_type
                # signature(el_typ, el_typ)
                out_ir.append(ir.Assign(func_var_def, func_var, loc))
                out_ir.append(ir.Assign(ir_expr, expr_out_var, loc))
    elif isinstance(expr, ir.Var):
        var_typ = typemap[expr.name]
        if isinstance(var_typ, types.Array):
            el_typ = var_typ.dtype
            ir_expr = _gen_arrayexpr_getitem(
                equiv_set,
                expr,
                parfor_index_tuple_var,
                all_parfor_indices,
                el_typ,
                calltypes,
                typingctx,
                typemap,
                init_block,
                out_ir,
            )
        else:
            # assert typemap[expr.name]==el_typ
            el_typ = var_typ
            ir_expr = expr
        out_ir.append(ir.Assign(ir_expr, expr_out_var, loc))
    elif isinstance(expr, ir.Const):
        el_typ = typing.Context().resolve_value_type(expr.value)
        out_ir.append(ir.Assign(expr, expr_out_var, loc))

    if len(out_ir) == 0:
        raise NotImplementedError(
            "Don't know how to translate array expression '%r'" % (expr,)
        )
    typemap.pop(expr_out_var.name, None)
    typemap[expr_out_var.name] = el_typ
    return out_ir


# Traceback (AssertionError)
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
~/anaconda3/lib/python3.7/site-packages/numba/errors.py in new_error_context(fmt_, *args, **kwargs)
716     try:
--> 717         yield
718     except NumbaError as e:

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

~/anaconda3/lib/python3.7/site-packages/numba/lowering.py in lower_inst(self, inst)
413                 if isinstance(inst, _class):
--> 414                     func(self, inst)
415                     return

~/anaconda3/lib/python3.7/site-packages/numba/npyufunc/parfor.py in _lower_parfor_parallel(lowerer, parfor)
239         lowerer, parfor, typemap, typingctx, targetctx, flags, {},
--> 240         bool(alias_map), index_var_typ, parfor.races)
241     numba.parfor.sequential_parfor_lowering = False

~/anaconda3/lib/python3.7/site-packages/numba/npyufunc/parfor.py in _create_gufunc_for_parfor_body(lowerer, parfor, typemap, typingctx, targetctx, flags, locals, has_aliases, index_var_typ, races)
1124         flags,
-> 1125         locals)
1126

~/anaconda3/lib/python3.7/site-packages/numba/compiler.py in compile_ir(typingctx, targetctx, func_ir, args, return_type, flags, locals, lifted, lifted_from, is_lifted_loop, library, pipeline_class)
591         return pipeline.compile_ir(func_ir=func_ir, lifted=lifted,
--> 592                                    lifted_from=lifted_from)
593

~/anaconda3/lib/python3.7/site-packages/numba/compiler.py in compile_ir(self, func_ir, lifted, lifted_from)
335         FixupArgs().run_pass(self.state)
--> 336         return self._compile_ir()
337

~/anaconda3/lib/python3.7/site-packages/numba/compiler.py in _compile_ir(self)
391         assert self.state.func_ir is not None
--> 392         return self._compile_core()
393

~/anaconda3/lib/python3.7/site-packages/numba/compiler.py in _compile_core(self)
364                 if is_final_pipeline:
--> 365                     raise e
366         else:

~/anaconda3/lib/python3.7/site-packages/numba/compiler.py in _compile_core(self)
355             try:
--> 356                 pm.run(self.state)
357                 if self.state.cr is not None:

~/anaconda3/lib/python3.7/site-packages/numba/compiler_machinery.py in run(self, state)
327                 patched_exception = self._patch_error(msg, e)
--> 328                 raise patched_exception
329

~/anaconda3/lib/python3.7/site-packages/numba/compiler_machinery.py in run(self, state)
318                 if isinstance(pass_inst, CompilerPass):
--> 319                     self._runPass(idx, pass_inst, state)
320                 else:

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

~/anaconda3/lib/python3.7/site-packages/numba/compiler_machinery.py in _runPass(self, index, pss, internal_state)
280         with SimpleTimer() as pass_time:
--> 281             mutated |= check(pss.run_pass, internal_state)
282         with SimpleTimer() as finalize_time:

~/anaconda3/lib/python3.7/site-packages/numba/compiler_machinery.py in check(func, compiler_state)
267         def check(func, compiler_state):
--> 268             mangled = func(compiler_state)
269             if mangled not in (True, False):

~/anaconda3/lib/python3.7/site-packages/numba/typed_passes.py in run_pass(self, state)
93                 state.return_type,
---> 94                 state.locals)
95             state.typemap = typemap

~/anaconda3/lib/python3.7/site-packages/numba/typed_passes.py in type_inference_stage(typingctx, interp, args, return_type, locals)
64
---> 65         infer.build_constraint()
66         infer.propagate()

~/anaconda3/lib/python3.7/site-packages/numba/typeinfer.py in build_constraint(self)
903             for inst in blk.body:
--> 904                 self.constrain_statement(inst)
905

~/anaconda3/lib/python3.7/site-packages/numba/typeinfer.py in constrain_statement(self, inst)
1187         if isinstance(inst, ir.Assign):
-> 1188             self.typeof_assign(inst)
1189         elif isinstance(inst, ir.SetItem):

~/anaconda3/lib/python3.7/site-packages/numba/typeinfer.py in typeof_assign(self, inst)
1258         elif isinstance(value, (ir.Global, ir.FreeVar)):
-> 1259             self.typeof_global(inst, inst.target, value)
1260         elif isinstance(value, ir.Arg):

~/anaconda3/lib/python3.7/site-packages/numba/typeinfer.py in typeof_global(self, inst, target, gvar)
1399         lit = types.maybe_literal(gvar.value)
-> 1400         self.lock_type(target.name, lit or typ, loc=inst.loc)
1401         self.assumed_immutables.add(inst)

~/anaconda3/lib/python3.7/site-packages/numba/typeinfer.py in lock_type(self, var, tp, loc, literal_value)
975         tv = self.typevars[var]
--> 976         tv.lock(tp, loc=loc, literal_value=literal_value)
977

~/anaconda3/lib/python3.7/site-packages/numba/typeinfer.py in lock(self, tp, loc, literal_value)
82         assert isinstance(tp, types.Type), type(tp)
---> 83         assert not self.locked
84

AssertionError: Failed in nopython mode pipeline (step: nopython frontend)


During handling of the above exception, another exception occurred:

LoweringError                             Traceback (most recent call last)
<ipython-input-1-1ddce8bd8630> in <module>
51
52 # nb.njit()(foo)(zz, xx, yyh, yyhi, vv, vvi, tc, s, w, h, k)
---> 53 nb.njit(parallel=True)(foo)(zz, xx, yyh, yyhi, vv, vvi, tc, s, w, h, k)

~/anaconda3/lib/python3.7/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
418                     e.patch_message('\n'.join((str(e).rstrip(), help_msg)))
419             # ignore the FULL_TRACEBACKS config, this needs reporting!
--> 420             raise e
421
422     def inspect_llvm(self, signature=None):

~/anaconda3/lib/python3.7/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
351                 argtypes.append(self.typeof_pyval(a))
352         try:
--> 353             return self.compile(tuple(argtypes))
354         except errors.ForceLiteralArg as e:
355             # Received request for compiler re-entry with the list of arguments

~/anaconda3/lib/python3.7/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

~/anaconda3/lib/python3.7/site-packages/numba/dispatcher.py in compile(self, sig)
766             self._cache_misses[sig] += 1
767             try:
--> 768                 cres = self._compiler.compile(args, return_type)
769             except errors.ForceLiteralArg as e:
770                 def folded(args, kws):

~/anaconda3/lib/python3.7/site-packages/numba/dispatcher.py in compile(self, args, return_type)
75
76     def compile(self, args, return_type):
---> 77         status, retval = self._compile_cached(args, return_type)
78         if status:
79             return retval

~/anaconda3/lib/python3.7/site-packages/numba/dispatcher.py in _compile_cached(self, args, return_type)
89
90         try:
---> 91             retval = self._compile_core(args, return_type)
92         except errors.TypingError as e:
93             self._failed_cache[key] = e

~/anaconda3/lib/python3.7/site-packages/numba/dispatcher.py in _compile_core(self, args, return_type)
107                                       args=args, return_type=return_type,
108                                       flags=flags, locals=self.locals,
--> 109                                       pipeline_class=self.pipeline_class)
110         # Check typing error if object mode is used
111         if cres.typing_error is not None and not flags.enable_pyobject:

~/anaconda3/lib/python3.7/site-packages/numba/compiler.py in compile_extra(typingctx, targetctx, func, args, return_type, flags, locals, library, pipeline_class)
526     pipeline = pipeline_class(typingctx, targetctx, library,
527                               args, return_type, flags, locals)
--> 528     return pipeline.compile_extra(func)
529
530

~/anaconda3/lib/python3.7/site-packages/numba/compiler.py in compile_extra(self, func)
324         self.state.lifted = ()
325         self.state.lifted_from = None
--> 326         return self._compile_bytecode()
327
328     def compile_ir(self, func_ir, lifted=(), lifted_from=None):

~/anaconda3/lib/python3.7/site-packages/numba/compiler.py in _compile_bytecode(self)
383         """
384         assert self.state.func_ir is None
--> 385         return self._compile_core()
386
387     def _compile_ir(self):

~/anaconda3/lib/python3.7/site-packages/numba/compiler.py in _compile_core(self)
363                 self.state.status.fail_reason = e
364                 if is_final_pipeline:
--> 365                     raise e
366         else:
367             raise CompilerError("All available pipelines exhausted")

~/anaconda3/lib/python3.7/site-packages/numba/compiler.py in _compile_core(self)
354             res = None
355             try:
--> 356                 pm.run(self.state)
357                 if self.state.cr is not None:
358                     break

~/anaconda3/lib/python3.7/site-packages/numba/compiler_machinery.py in run(self, state)
326                     (self.pipeline_name, pass_desc)
327                 patched_exception = self._patch_error(msg, e)
--> 328                 raise patched_exception
329
330     def dependency_analysis(self):

~/anaconda3/lib/python3.7/site-packages/numba/compiler_machinery.py in run(self, state)
317                 pass_inst = _pass_registry.get(pss).pass_inst
318                 if isinstance(pass_inst, CompilerPass):
--> 319                     self._runPass(idx, pass_inst, state)
320                 else:
321                     raise BaseException("Legacy pass in use")

~/anaconda3/lib/python3.7/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

~/anaconda3/lib/python3.7/site-packages/numba/compiler_machinery.py in _runPass(self, index, pss, internal_state)
279             mutated |= check(pss.run_initialization, internal_state)
280         with SimpleTimer() as pass_time:
--> 281             mutated |= check(pss.run_pass, internal_state)
282         with SimpleTimer() as finalize_time:
283             mutated |= check(pss.run_finalizer, internal_state)

~/anaconda3/lib/python3.7/site-packages/numba/compiler_machinery.py in check(func, compiler_state)
266
267         def check(func, compiler_state):
--> 268             mangled = func(compiler_state)
269             if mangled not in (True, False):
270                 msg = ("CompilerPass implementations should return True/False. "

~/anaconda3/lib/python3.7/site-packages/numba/typed_passes.py in run_pass(self, state)
378             state.library.enable_object_caching()
379
--> 380         NativeLowering().run_pass(state) # TODO: Pull this out into the pipeline
381         lowered = state['cr']
382         signature = typing.signature(state.return_type, *state.args)

~/anaconda3/lib/python3.7/site-packages/numba/typed_passes.py in run_pass(self, state)
323                 lower = lowering.Lower(targetctx, library, fndesc, interp,
324                                        metadata=metadata)
--> 325                 lower.lower()
326                 if not flags.no_cpython_wrapper:
327                     lower.create_cpython_wrapper(flags.release_gil)

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

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

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

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

~/anaconda3/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

~/anaconda3/lib/python3.7/site-packages/numba/errors.py in new_error_context(fmt_, *args, **kwargs)
723         from numba import config
724         tb = sys.exc_info()[2] if config.FULL_TRACEBACKS else None
--> 725         six.reraise(type(newerr), newerr, tb)
726
727

~/anaconda3/lib/python3.7/site-packages/numba/six.py in reraise(tp, value, tb)
667         if value.__traceback__ is not tb:
668             raise value.with_traceback(tb)
--> 669         raise value
670
671 else:

LoweringError: Failed in nopython mode pipeline (step: nopython mode backend)
Failed in nopython mode pipeline (step: nopython frontend)


File "<ipython-input-1-1ddce8bd8630>", line 14:
def foo(zz, xx, yyh, yyhi, vv, vvi, tc, s, w, h, k):
<source elided>

for i in nb.prange(n):
^

[1] During: lowering "id=5[LoopNest(index_variable = parfor_index.104, range = (0, $n.119, 1))]{256: <ir.Block at <ipython-input-1-1ddce8bd8630> (23)>, 258: <ir.Block at <ipython-input-1-1ddce8bd8630> (25)>, 130: <ir.Block at <ipython-input-1-1ddce8bd8630> (18)>, 132: <ir.Block at <ipython-input-1-1ddce8bd8630> (18)>, 268: <ir.Block at <ipython-input-1-1ddce8bd8630> (25)>, 146: <ir.Block at <ipython-input-1-1ddce8bd8630> (19)>, 278: <ir.Block at <ipython-input-1-1ddce8bd8630> (27)>, 156: <ir.Block at <ipython-input-1-1ddce8bd8630> (18)>, 158: <ir.Block at <ipython-input-1-1ddce8bd8630> (20)>, 286: <ir.Block at <ipython-input-1-1ddce8bd8630> (27)>, 166: <ir.Block at <ipython-input-1-1ddce8bd8630> (20)>, 296: <ir.Block at <ipython-input-1-1ddce8bd8630> (27)>, 298: <ir.Block at <ipython-input-1-1ddce8bd8630> (28)>, 174: <ir.Block at <ipython-input-1-1ddce8bd8630> (22)>, 184: <ir.Block at <ipython-input-1-1ddce8bd8630> (22)>, 314: <ir.Block at <ipython-input-1-1ddce8bd8630> (28)>, 194: <ir.Block at <ipython-input-1-1ddce8bd8630> (22)>, 196: <ir.Block at <ipython-input-1-1ddce8bd8630> (23)>, 78: <ir.Block at <ipython-input-1-1ddce8bd8630> (14)>, 344: <ir.Block at <ipython-input-1-1ddce8bd8630> (29)>, 348: <ir.Block at <ipython-input-1-1ddce8bd8630> (28)>, 351: <ir.Block at <ipython-input-1-1ddce8bd8630> (30)>, 352: <ir.Block at <ipython-input-1-1ddce8bd8630> (14)>, 96: <ir.Block at <ipython-input-1-1ddce8bd8630> (17)>, 104: <ir.Block at <ipython-input-1-1ddce8bd8630> (17)>, 112: <ir.Block at <ipython-input-1-1ddce8bd8630> (17)>, 120: <ir.Block at <ipython-input-1-1ddce8bd8630> (17)>}Var(parfor_index.104, <ipython-input-1-1ddce8bd8630> (14))" at <ipython-input-1-1ddce8bd8630> (14)

# Fixed code
def _arrayexpr_tree_to_ir(
    func_ir,
    typingctx,
    typemap,
    calltypes,
    equiv_set,
    init_block,
    expr_out_var,
    expr,
    parfor_index_tuple_var,
    all_parfor_indices,
    avail_vars,
):
    """generate IR from array_expr's expr tree recursively. Assign output to
    expr_out_var and returns the whole IR as a list of Assign nodes.
    """
    el_typ = typemap[expr_out_var.name]
    scope = expr_out_var.scope
    loc = expr_out_var.loc
    out_ir = []

    if isinstance(expr, tuple):
        op, arr_expr_args = expr
        arg_vars = []
        for arg in arr_expr_args:
            arg_out_var = ir.Var(scope, mk_unique_var("$arg_out_var"), loc)
            typemap[arg_out_var.name] = el_typ
            out_ir += _arrayexpr_tree_to_ir(
                func_ir,
                typingctx,
                typemap,
                calltypes,
                equiv_set,
                init_block,
                arg_out_var,
                arg,
                parfor_index_tuple_var,
                all_parfor_indices,
                avail_vars,
            )
            arg_vars.append(arg_out_var)
        if op in npydecl.supported_array_operators:
            el_typ1 = typemap[arg_vars[0].name]
            if len(arg_vars) == 2:
                el_typ2 = typemap[arg_vars[1].name]
                func_typ = typingctx.resolve_function_type(op, (el_typ1, el_typ), {})
                ir_expr = ir.Expr.binop(op, arg_vars[0], arg_vars[1], loc)
                if op == operator.truediv:
                    func_typ, ir_expr = _gen_np_divide(
                        arg_vars[0], arg_vars[1], out_ir, typemap
                    )
            else:
                func_typ = typingctx.resolve_function_type(op, (el_typ1,), {})
                ir_expr = ir.Expr.unary(op, arg_vars[0], loc)
            calltypes[ir_expr] = func_typ
            el_typ = func_typ.return_type
            out_ir.append(ir.Assign(ir_expr, expr_out_var, loc))
        for T in array_analysis.MAP_TYPES:
            if isinstance(op, T):
                # elif isinstance(op, (np.ufunc, DUFunc)):
                # function calls are stored in variables which are not removed
                # op is typing_key to the variables type
                func_var_name = _find_func_var(typemap, op, avail_vars)
                func_var = ir.Var(scope, mk_unique_var(func_var_name), loc)
                typemap[func_var.name] = typemap[func_var_name]
                func_var_def = copy.deepcopy(func_ir.get_definition(func_var_name))
                if (
                    isinstance(func_var_def, ir.Expr)
                    and func_var_def.op == "getattr"
                    and func_var_def.attr == "sqrt"
                ):
                    g_math_var = ir.Var(scope, mk_unique_var("$math_g_var"), loc)
                    typemap[g_math_var.name] = types.misc.Module(math)
                    g_math = ir.Global("math", math, loc)
                    g_math_assign = ir.Assign(g_math, g_math_var, loc)
                    func_var_def = ir.Expr.getattr(g_math_var, "sqrt", loc)
                    out_ir.append(g_math_assign)
                #                     out_ir.append(func_var_def)
                ir_expr = ir.Expr.call(func_var, arg_vars, (), loc)
                call_typ = typemap[func_var.name].get_call_type(
                    typingctx, tuple(typemap[a.name] for a in arg_vars), {}
                )
                calltypes[ir_expr] = call_typ
                el_typ = call_typ.return_type
                # signature(el_typ, el_typ)
                out_ir.append(ir.Assign(func_var_def, func_var, loc))
                out_ir.append(ir.Assign(ir_expr, expr_out_var, loc))
    elif isinstance(expr, ir.Var):
        var_typ = typemap[expr.name]
        if isinstance(var_typ, types.Array):
            el_typ = var_typ.dtype
            ir_expr = _gen_arrayexpr_getitem(
                equiv_set,
                expr,
                parfor_index_tuple_var,
                all_parfor_indices,
                el_typ,
                calltypes,
                typingctx,
                typemap,
                init_block,
                out_ir,
            )
        else:
            # assert typemap[expr.name]==el_typ
            el_typ = var_typ
            ir_expr = expr
        out_ir.append(ir.Assign(ir_expr, expr_out_var, loc))
    elif isinstance(expr, ir.Const):
        el_typ = typing.Context().resolve_value_type(expr.value)
        out_ir.append(ir.Assign(expr, expr_out_var, loc))

    if len(out_ir) == 0:
        raise NotImplementedError(
            "Don't know how to translate array expression '%r'" % (expr,)
        )
    typemap.pop(expr_out_var.name, None)
    typemap[expr_out_var.name] = el_typ
    return out_ir