Skip to content

Panic when running sema on an error union switch. #25037

@EdAyers

Description

@EdAyers

Zig Version

0.16.0-dev.45+d57b1e355

Steps to Reproduce and Observed Behavior

(also observed on 0.15.1 release )

Made a new project with zig init.

Pasted this into main.zig (probably can be reduced further)

const std = @import("std");
const posix = std.posix;
const net = std.net;
const io = std.io;
const OOM = std.mem.Allocator.Error;

const PORT = 7797;

const Error = error{
    /// Transport closed gracefully
    TransportClosed,
    /// Something went wrong with the transport layer.
    /// Details will be logged.
    TransportError,
    OutOfMemory
};

const ClientConnection = struct {
    allocator: std.mem.Allocator,
    // ... deleted fields

    pub fn create(fd: posix.socket_t, addr: net.Address, allocator: std.mem.Allocator) OOM!*ClientConnection {
        _ = fd;
        _ = addr;
        const ccp = try allocator.create(ClientConnection);
        ccp.allocator = allocator;
        return ccp;
    }

    pub fn destroy(self: *ClientConnection) void {
        self.allocator.destroy(self);
    }

    pub fn read_message(self : *ClientConnection) Error![]const u8 {
        _ = self;
        return "minimal repro placeholder";
    }

    pub fn run_forever(self : *ClientConnection) Error!noreturn {
        while (true) {
            const msg = try self.read_message();
            defer self.allocator.free(msg);
            std.log.info("Received message: {s}", .{msg});
        }
    }


    /// Entry point for the lsp thread
    pub fn serve(self : *ClientConnection) void {
        defer self.destroy();
        self.run_forever() catch |err| switch (err) {
            error.TransportClosed => {
                std.log.info("Client {f} disconnected gracefully", .{self.addr});
                return;
            },
            error.TransportError => {
                // error will already have been logged
                return;
            },
            else => {
                std.log.err("Error consuming client data: {t}\n", .{err});
                return;
            },
        };
    }
};

pub fn main() !void {
    // Create a server socket
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();
    const address = try net.Address.parseIp("0.0.0.0", PORT);

    // Listen for incoming connections
    var server = try address.listen(.{
        .kernel_backlog = 128,
        .reuse_address = true,
    });
    defer server.deinit();

    std.log.info("Server listening on port {d}...", .{PORT});

    // Main event loop
    while (true) {
        // Wait for activity on any of the sockets
        const connection = server.accept() catch |err| {
                std.log.err("Error accepting connection: {t}", .{err});
                continue;
        };
        std.log.info("New connection from {f} on FD-{d}", .{connection.address, connection.stream.handle});
        const client = try ClientConnection.create(
                connection.stream.handle, connection.address, allocator,);
        const thread = try std.Thread.spawn(.{}, ClientConnection.serve, .{client});
        thread.detach();
    }
}

Running zig build (observed using latest 0.15.1 and 0.16.0-dev.45+d57b1e355 (I built locally from source))

We hit an unreachable code branch:

~/zigstuff/zig/build/stage3/bin/zig build
install
└─ install spike3
   └─ compile exe spike3 Debug native failure
error: thread 12972562 panic: reached unreachable code
Analyzing Analyzing 'src/main.zig'
    > %184 = err_union_payload_unsafe(%181) 
      %185 = break(%183, %184)
    For full context, use the command
      zig ast-check -t src/main.zig

  in src/main.zig
    > %183 = switch_block_err_union(%181, err_capture=%186,
        non_err => {%184, %185},
        else => {%217..%236},
        %187 => {%188..%208},
        %209 => {%210..%216}) 

???:?:?: 0x106d71263 in _debug.assert (???)
???:?:?: 0x107b0c367 in _Sema.analyzeBodyInner (???)
???:?:?: 0x1086197c3 in _Sema.analyzeBodyRuntimeBreak (???)
???:?:?: 0x10819be3f in _Sema.zirSwitchBlockErrUnion (???)
???:?:?: 0x107b0032f in _Sema.analyzeBodyInner (???)
???:?:?: 0x107afedcb in _Sema.analyzeFnBody (???)
???:?:?: 0x1076a6edf in _Zcu.PerThread.analyzeFnBodyInner (???)
???:?:?: 0x107363d1b in _Zcu.PerThread.analyzeFuncBody (???)
???:?:?: 0x107181f4b in _Zcu.PerThread.ensureFuncBodyUpToDate (???)
???:?:?: 0x10706604f in _Compilation.processOneJob (???)
???:?:?: 0x106fae8bb in _Compilation.performAllTheWork (???)
???:?:?: 0x106e9a54f in _Compilation.update (???)
???:?:?: 0x106edc1db in _main.serve (???)
???:?:?: 0x106efc08f in _main.buildOutputType (???)
???:?:?: 0x106e5d417 in _main.mainArgs (???)
???:?:?: 0x106e5bd67 in _main.main (???)
???:?:?: 0x106e5bb13 in _main (???)
???:?:?: 0x197462b97 in ??? (???)
???:?:?: 0x0 in ??? (???)

error: the following command terminated unexpectedly:
/Users/edward/zigstuff/zig/build/stage3/bin/zig build-exe -ODebug --dep spike3 -Mroot=/Users/edward/zigstuff/spike3/src/main.zig -Mspike3=/Users/edward/zigstuff/spike3/src/root.zig --cache-dir .zig-cache --global-cache-dir /Users/edward/.cache/zig --name spike3 --zig-lib-dir /Users/edward/zigstuff/zig/build/stage3/lib/zig/ --listen=-

Build Summary: 0/3 steps succeeded; 1 failed
install transitive failure
└─ install spike3 transitive failure
   └─ compile exe spike3 Debug native failure

error: the following build command failed with exit code 1:
.zig-cache/o/c25fe6c3fe28c9518e536a677700f29d/build /Users/edward/zigstuff/zig/build/stage3/bin/zig /Users/edward/zigstuff/zig/build/stage3/lib/zig /Users/edward/zigstuff/spike3 .zig-cache /Users/edward/.cache/zig --seed 0xd218860b -Z7b89149d60b5ad0c

Expected Behavior

I'm not sure if the file is valid syntax but should produce a user-facing error diagnostic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions