ziglang / zig

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

`undefined` E to E!T cast causes access of inactive union field panic #21706

Open Vexu opened 1 month ago

Vexu commented 1 month ago
pub export fn entry() void {
    const a: anyerror = undefined;
    const b: anyerror!u16 = a;
    @compileLog(b);
}
thread 11960 panic: access of union field 'err' while field 'undef' is active
Analyzing a.zig
      %5 = dbg_stmt(2, 5)
      %6 = as_node(@anyerror_type, @undef) node_offset:5:25 to :5:34
      %7 = dbg_var_val(%6, "a")
      %8 = dbg_stmt(3, 5)
      %9 = block_comptime({
        %10 = error_union_type(@anyerror_type, @u16_type) node_offset:6:14 to :6:26
        %11 = break(%9, %10)
      }) node_offset:6:14 to :6:26
    > %12 = as_node(%9, %6) node_offset:6:29 to :6:30
      %13 = dbg_var_val(%12, "b")
      %14 = dbg_stmt(4, 5)
      %15 = extended(compile_log(%12)) node_offset:7:5 to :7:19
      %16 = ensure_result_used(%15) node_offset:7:5 to :7:19
      %17 = restore_err_ret_index_unconditional(.none) node_offset:4:1 to :4:14
      %18 = ret_implicit(@void_value) token_offset:8:1 to :8:1
    For full context, use the command
      zig ast-check -t a.zig

/home/vexu/Documents/zig/zig/src/Sema.zig:34027:73: 0xb4a3cd3 in wrapErrorUnionSet (zig)
        const expected_name = zcu.intern_pool.indexToKey(val.toIntern()).err.name;
                                                                        ^
/home/vexu/Documents/zig/zig/src/Sema.zig:30264:46: 0xb08b046 in coerceExtra (zig)
                return sema.wrapErrorUnionSet(block, dest_ty, inst, inst_src);
                                             ^
/home/vexu/Documents/zig/zig/src/Sema.zig:10353:28: 0xbdaa8cf in analyzeAs (zig)
    return sema.coerceExtra(block, dest_ty, operand, src, .{ .is_ret = is_ret, .no_cast_to_comptime_int = no_cast_to_comptime_int }) catch |err| switch (err) {
                           ^
/home/vexu/Documents/zig/zig/src/Sema.zig:10305:26: 0xb94b12c in zirAsNode (zig)
    return sema.analyzeAs(block, src, extra.dest_type, extra.operand, false);
                         ^
/home/vexu/Documents/zig/zig/src/Sema.zig:1061:64: 0xb478bf5 in analyzeBodyInner (zig)
            .as_node                      => try sema.zirAsNode(block, inst),
                                                               ^
/home/vexu/Documents/zig/zig/src/Sema.zig:935:26: 0xb8e9331 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
mlugg commented 1 month ago

Hm, we currently don't actually have a way to represent an error union which is an undefined error in the InternPool. In fact, I think this cast should either be a compile error (and IB at runtime) or create an undefined error union, since an error index of 0 would, at runtime, result in a non-error E!T value.