# Buggy code
def lower_expr(self, resty, expr):
    if expr.op == "binop":
        return self.lower_binop(resty, expr)
    elif expr.op == "inplace_binop":
        lty = self.typeof(expr.lhs.name)
        if not lty.mutable:
            # inplace operators on non-mutable types reuse the same
            # definition as the corresponding copying operators.
            return self.lower_binop(resty, expr)
    elif expr.op == "unary":
        val = self.loadvar(expr.value.name)
        typ = self.typeof(expr.value.name)
        # Get function
        signature = self.fndesc.calltypes[expr]
        impl = self.context.get_function(expr.fn, signature)
        # Convert argument to match
        val = self.context.cast(self.builder, val, typ, signature.args[0])
        res = impl(self.builder, [val])
        return self.context.cast(self.builder, res, signature.return_type, resty)

    elif expr.op == "call":
        argvals = [self.loadvar(a.name) for a in expr.args]
        argtyps = [self.typeof(a.name) for a in expr.args]
        signature = self.fndesc.calltypes[expr]

        if isinstance(expr.func, ir.Intrinsic):
            fnty = expr.func.name
            castvals = expr.func.args
        else:
            assert not expr.kws, expr.kws
            fnty = self.typeof(expr.func.name)

            castvals = [
                self.context.cast(self.builder, av, at, ft)
                for av, at, ft in zip(argvals, argtyps, signature.args)
            ]

        if isinstance(fnty, types.Method):
            # Method of objects are handled differently
            fnobj = self.loadvar(expr.func.name)
            res = self.context.call_class_method(
                self.builder, fnobj, signature, castvals
            )

        elif isinstance(fnty, types.FunctionPointer):
            # Handle function pointer
            pointer = fnty.funcptr
            res = self.context.call_function_pointer(
                self.builder, pointer, signature, castvals
            )

        elif isinstance(fnty, cffi_support.ExternCFunction):
            # XXX unused?
            fndesc = ExternalFunctionDescriptor(
                fnty.symbol, fnty.restype, fnty.argtypes
            )
            func = self.context.declare_external_function(
                cgutils.get_module(self.builder), fndesc
            )
            res = self.context.call_external_function(
                self.builder, func, fndesc.argtypes, castvals
            )

        else:
            # Normal function resolution
            impl = self.context.get_function(fnty, signature)
            if signature.recvr:
                # The "self" object is passed as the function object
                # for bounded function
                the_self = self.loadvar(expr.func.name)
                # Prepend the self reference
                castvals = [the_self] + castvals

            res = impl(self.builder, castvals)
            libs = getattr(impl, "libs", ())
            for lib in libs:
                self.library.add_linking_library(lib)
        return self.context.cast(self.builder, res, signature.return_type, resty)

    elif expr.op == "pair_first":
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)
        item = self.context.pair_first(self.builder, val, ty)
        return self.context.get_argument_value(self.builder, ty.first_type, item)

    elif expr.op == "pair_second":
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)
        item = self.context.pair_second(self.builder, val, ty)
        return self.context.get_argument_value(self.builder, ty.second_type, item)

    elif expr.op in ("getiter", "iternext"):
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)
        signature = self.fndesc.calltypes[expr]
        impl = self.context.get_function(expr.op, signature)
        [fty] = signature.args
        castval = self.context.cast(self.builder, val, ty, fty)
        res = impl(self.builder, (castval,))
        return self.context.cast(self.builder, res, signature.return_type, resty)

    elif expr.op == "exhaust_iter":
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)
        # If we have a heterogenous tuple, we needn't do anything,
        # and we can't iterate over it anyway.
        if isinstance(ty, types.Tuple):
            return val

        itemty = ty.iterator_type.yield_type
        tup = self.context.get_constant_undef(resty)
        pairty = types.Pair(itemty, types.boolean)
        getiter_sig = typing.signature(ty.iterator_type, ty)
        getiter_impl = self.context.get_function("getiter", getiter_sig)
        iternext_sig = typing.signature(pairty, ty.iterator_type)
        iternext_impl = self.context.get_function("iternext", iternext_sig)
        iterobj = getiter_impl(self.builder, (val,))
        excid = self.add_exception(ValueError)
        # We call iternext() as many times as desired (`expr.count`).
        for i in range(expr.count):
            pair = iternext_impl(self.builder, (iterobj,))
            is_valid = self.context.pair_second(self.builder, pair, pairty)
            with cgutils.if_unlikely(self.builder, self.builder.not_(is_valid)):
                self.context.return_user_exc(self.builder, excid)
            item = self.context.pair_first(self.builder, pair, pairty)
            tup = self.builder.insert_value(tup, item, i)

        # Call iternext() once more to check that the iterator
        # is exhausted.
        pair = iternext_impl(self.builder, (iterobj,))
        is_valid = self.context.pair_second(self.builder, pair, pairty)
        with cgutils.if_unlikely(self.builder, is_valid):
            self.context.return_user_exc(self.builder, excid)

        return tup

    elif expr.op == "getattr":
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)

        if isinstance(resty, types.BoundFunction):
            # if we are getting out a method, assume we have typed this
            # properly and just build a bound function object
            res = self.context.get_bound_function(self.builder, val, ty)
        else:
            impl = self.context.get_attribute(val, ty, expr.attr)

            if impl is None:
                # ignore the attribute
                res = self.context.get_dummy_value()
            else:
                res = impl(self.context, self.builder, ty, val, expr.attr)
        return res

    elif expr.op == "static_getitem":
        baseval = self.loadvar(expr.value.name)
        indexval = self.context.get_constant(types.intp, expr.index)
        if cgutils.is_struct(baseval.type):
            # Statically extract the given element from the structure
            # (structures aren't dynamically indexable).
            return self.builder.extract_value(baseval, expr.index)
        else:
            # Fall back on the generic getitem() implementation
            # for this type.
            signature = typing.signature(
                resty, self.typeof(expr.value.name), types.intp
            )
            impl = self.context.get_function("getitem", signature)
            argvals = (baseval, indexval)
            res = impl(self.builder, argvals)
            return self.context.cast(self.builder, res, signature.return_type, resty)

    elif expr.op == "getitem":
        baseval = self.loadvar(expr.value.name)
        indexval = self.loadvar(expr.index.name)
        signature = self.fndesc.calltypes[expr]
        impl = self.context.get_function("getitem", signature)
        argvals = (baseval, indexval)
        argtyps = (self.typeof(expr.value.name), self.typeof(expr.index.name))
        castvals = [
            self.context.cast(self.builder, av, at, ft)
            for av, at, ft in zip(argvals, argtyps, signature.args)
        ]
        res = impl(self.builder, castvals)
        return self.context.cast(self.builder, res, signature.return_type, resty)

    elif expr.op == "build_tuple":
        itemvals = [self.loadvar(i.name) for i in expr.items]
        itemtys = [self.typeof(i.name) for i in expr.items]
        castvals = [
            self.context.cast(self.builder, val, fromty, toty)
            for val, toty, fromty in zip(itemvals, resty, itemtys)
        ]
        tup = self.context.get_constant_undef(resty)
        for i in range(len(castvals)):
            tup = self.builder.insert_value(tup, castvals[i], i)
        return tup

    elif expr.op == "cast":
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)
        castval = self.context.cast(self.builder, val, ty, resty)
        return castval

    raise NotImplementedError(expr)


# Traceback (ValueError)
ctypes.windll.kernel32.Sleep(100)
0
ctypes.cdll.kernel32.Sleep(100)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Procedure called with not enough arguments (4 bytes missing) or wron
g calling convention

# Fixed code
def lower_expr(self, resty, expr):
    if expr.op == "binop":
        return self.lower_binop(resty, expr)
    elif expr.op == "inplace_binop":
        lty = self.typeof(expr.lhs.name)
        if not lty.mutable:
            # inplace operators on non-mutable types reuse the same
            # definition as the corresponding copying operators.
            return self.lower_binop(resty, expr)
    elif expr.op == "unary":
        val = self.loadvar(expr.value.name)
        typ = self.typeof(expr.value.name)
        # Get function
        signature = self.fndesc.calltypes[expr]
        impl = self.context.get_function(expr.fn, signature)
        # Convert argument to match
        val = self.context.cast(self.builder, val, typ, signature.args[0])
        res = impl(self.builder, [val])
        return self.context.cast(self.builder, res, signature.return_type, resty)

    elif expr.op == "call":
        argvals = [self.loadvar(a.name) for a in expr.args]
        argtyps = [self.typeof(a.name) for a in expr.args]
        signature = self.fndesc.calltypes[expr]

        if isinstance(expr.func, ir.Intrinsic):
            fnty = expr.func.name
            castvals = expr.func.args
        else:
            assert not expr.kws, expr.kws
            fnty = self.typeof(expr.func.name)

            castvals = [
                self.context.cast(self.builder, av, at, ft)
                for av, at, ft in zip(argvals, argtyps, signature.args)
            ]

        if isinstance(fnty, types.Method):
            # Method of objects are handled differently
            fnobj = self.loadvar(expr.func.name)
            res = self.context.call_class_method(
                self.builder, fnobj, signature, castvals
            )

        elif isinstance(fnty, types.FunctionPointer):
            # Handle function pointer
            pointer = fnty.funcptr
            res = self.context.call_function_pointer(
                self.builder, pointer, signature, castvals, fnty.cconv
            )

        elif isinstance(fnty, cffi_support.ExternCFunction):
            # XXX unused?
            fndesc = ExternalFunctionDescriptor(
                fnty.symbol, fnty.restype, fnty.argtypes
            )
            func = self.context.declare_external_function(
                cgutils.get_module(self.builder), fndesc
            )
            res = self.context.call_external_function(
                self.builder, func, fndesc.argtypes, castvals
            )

        else:
            # Normal function resolution
            impl = self.context.get_function(fnty, signature)
            if signature.recvr:
                # The "self" object is passed as the function object
                # for bounded function
                the_self = self.loadvar(expr.func.name)
                # Prepend the self reference
                castvals = [the_self] + castvals

            res = impl(self.builder, castvals)
            libs = getattr(impl, "libs", ())
            for lib in libs:
                self.library.add_linking_library(lib)
        return self.context.cast(self.builder, res, signature.return_type, resty)

    elif expr.op == "pair_first":
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)
        item = self.context.pair_first(self.builder, val, ty)
        return self.context.get_argument_value(self.builder, ty.first_type, item)

    elif expr.op == "pair_second":
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)
        item = self.context.pair_second(self.builder, val, ty)
        return self.context.get_argument_value(self.builder, ty.second_type, item)

    elif expr.op in ("getiter", "iternext"):
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)
        signature = self.fndesc.calltypes[expr]
        impl = self.context.get_function(expr.op, signature)
        [fty] = signature.args
        castval = self.context.cast(self.builder, val, ty, fty)
        res = impl(self.builder, (castval,))
        return self.context.cast(self.builder, res, signature.return_type, resty)

    elif expr.op == "exhaust_iter":
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)
        # If we have a heterogenous tuple, we needn't do anything,
        # and we can't iterate over it anyway.
        if isinstance(ty, types.Tuple):
            return val

        itemty = ty.iterator_type.yield_type
        tup = self.context.get_constant_undef(resty)
        pairty = types.Pair(itemty, types.boolean)
        getiter_sig = typing.signature(ty.iterator_type, ty)
        getiter_impl = self.context.get_function("getiter", getiter_sig)
        iternext_sig = typing.signature(pairty, ty.iterator_type)
        iternext_impl = self.context.get_function("iternext", iternext_sig)
        iterobj = getiter_impl(self.builder, (val,))
        excid = self.add_exception(ValueError)
        # We call iternext() as many times as desired (`expr.count`).
        for i in range(expr.count):
            pair = iternext_impl(self.builder, (iterobj,))
            is_valid = self.context.pair_second(self.builder, pair, pairty)
            with cgutils.if_unlikely(self.builder, self.builder.not_(is_valid)):
                self.context.return_user_exc(self.builder, excid)
            item = self.context.pair_first(self.builder, pair, pairty)
            tup = self.builder.insert_value(tup, item, i)

        # Call iternext() once more to check that the iterator
        # is exhausted.
        pair = iternext_impl(self.builder, (iterobj,))
        is_valid = self.context.pair_second(self.builder, pair, pairty)
        with cgutils.if_unlikely(self.builder, is_valid):
            self.context.return_user_exc(self.builder, excid)

        return tup

    elif expr.op == "getattr":
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)

        if isinstance(resty, types.BoundFunction):
            # if we are getting out a method, assume we have typed this
            # properly and just build a bound function object
            res = self.context.get_bound_function(self.builder, val, ty)
        else:
            impl = self.context.get_attribute(val, ty, expr.attr)

            if impl is None:
                # ignore the attribute
                res = self.context.get_dummy_value()
            else:
                res = impl(self.context, self.builder, ty, val, expr.attr)
        return res

    elif expr.op == "static_getitem":
        baseval = self.loadvar(expr.value.name)
        indexval = self.context.get_constant(types.intp, expr.index)
        if cgutils.is_struct(baseval.type):
            # Statically extract the given element from the structure
            # (structures aren't dynamically indexable).
            return self.builder.extract_value(baseval, expr.index)
        else:
            # Fall back on the generic getitem() implementation
            # for this type.
            signature = typing.signature(
                resty, self.typeof(expr.value.name), types.intp
            )
            impl = self.context.get_function("getitem", signature)
            argvals = (baseval, indexval)
            res = impl(self.builder, argvals)
            return self.context.cast(self.builder, res, signature.return_type, resty)

    elif expr.op == "getitem":
        baseval = self.loadvar(expr.value.name)
        indexval = self.loadvar(expr.index.name)
        signature = self.fndesc.calltypes[expr]
        impl = self.context.get_function("getitem", signature)
        argvals = (baseval, indexval)
        argtyps = (self.typeof(expr.value.name), self.typeof(expr.index.name))
        castvals = [
            self.context.cast(self.builder, av, at, ft)
            for av, at, ft in zip(argvals, argtyps, signature.args)
        ]
        res = impl(self.builder, castvals)
        return self.context.cast(self.builder, res, signature.return_type, resty)

    elif expr.op == "build_tuple":
        itemvals = [self.loadvar(i.name) for i in expr.items]
        itemtys = [self.typeof(i.name) for i in expr.items]
        castvals = [
            self.context.cast(self.builder, val, fromty, toty)
            for val, toty, fromty in zip(itemvals, resty, itemtys)
        ]
        tup = self.context.get_constant_undef(resty)
        for i in range(len(castvals)):
            tup = self.builder.insert_value(tup, castvals[i], i)
        return tup

    elif expr.op == "cast":
        val = self.loadvar(expr.value.name)
        ty = self.typeof(expr.value.name)
        castval = self.context.cast(self.builder, val, ty, resty)
        return castval

    raise NotImplementedError(expr)