ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
35.21k stars 2.57k forks source link

Compiler panic when use `await async call()` #10343

Open TheWaWaR opened 2 years ago

TheWaWaR commented 2 years ago

Zig Version

0.9.0-dev.1980+877a1f2a2

Steps to Reproduce

Save zig code as try-async-await.zig

const net = @import("std").net;

pub const io_mode = .evented;

pub fn main() !void {
    const addr = try net.Address.parseIp("127.0.0.1", 7000);
    var sendFrame = async send_message(addr);
    try await sendFrame;
}

fn send_message(addr: net.Address) !void {
    var socket = try net.tcpConnectToAddress(addr);
    defer socket.close();

    _ = await async socket.write("Hello World!\n");
}

Then run follow command in one terminal:

$ nc -lk 7000

And run follow command in another terminal:

$ zig run try-async-await.zig
Code Generation [308/759] std.os.linux.mmap... when analyzing /opt/zig-linux-x86_64-0.9.0-dev.1980+877a1f2a2/lib/std/net.zig:1646:51 in compiler source at ../src/stage1/codegen.cpp:4420: thread 2170962 panic: assertion failed. This is a bug in the Zig compiler.
Unable to dump stack trace: debug info stripped
[1]    2170962 abort (core dumped)  zig run try-async-await.zig

If change the zig code to follow, it just work as expected:

const net = @import("std").net;

pub const io_mode = .evented;

pub fn main() !void {
    const addr = try net.Address.parseIp("127.0.0.1", 7000);
    var sendFrame = async send_message(addr);
    try await sendFrame;
}

fn send_message(addr: net.Address) !void {
    var socket = try net.tcpConnectToAddress(addr);
    defer socket.close();

    var size_frame = async socket.write("Hello World!\n");
    _ = await size_frame;
}

Or, just change io_mode to .blocking will also work just fine.

Expected Behavior

Success without output.

Actual Behavior

Code Generation [308/759] std.os.linux.mmap... when analyzing /opt/zig-linux-x86_64-0.9.0-dev.1980+877a1f2a2/lib/std/net.zig:1646:51 in compiler source at ../src/stage1/codegen.cpp:4420: thread 2170962 panic: assertion failed. This is a bug in the Zig compiler.
Unable to dump stack trace: debug info stripped
[1]    2170962 abort (core dumped)  zig run try-async-await.zig
fogti commented 2 years ago

code snippets

codegen.cpp:4420:

if (instruction->modifier == CallModifierAsync) {
    frame_result_loc = result_loc;
} else {
    ir_assert(instruction->frame_result_loc != nullptr, &instruction->base); // <-- assert hit
    frame_result_loc_uncasted = ir_llvm_value(g, instruction->frame_result_loc);
    ir_assert(instruction->fn_entry != nullptr, &instruction->base);
    frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted,
            LLVMPointerType(get_llvm_type(g, instruction->fn_entry->frame_type), 0), "");
}

net.zig:1646

if (std.io.is_async) {
    return std.event.Loop.instance.?.write(self.handle, buffer, false); // <--
} else {
    return os.write(self.handle, buffer);
}