Repository navigation
Panic when running sema on an error union switch. #25037
Copy link
Copy link
Open
Labels
bugObserved behavior contradicts documented or intended behaviorObserved behavior contradicts documented or intended behavior
Description
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.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugObserved behavior contradicts documented or intended behaviorObserved behavior contradicts documented or intended behavior
Activity
JackoCoolio commentedon Aug 28, 2025
Minimal repro:
Weirdly, it compiles just fine if you wrap the switch in another block, because that causes AstGen to generate a
switch_blockinstr rather than aswitch_block_err_union: