Skip to content

Compiler segfault when enum field definition uses @This() in a function call #24269

Open
@fardragon

Description

@fardragon

Zig Version

0.15.0-dev.876+8eca338c2

Steps to Reproduce and Observed Behavior

  1. Create repro.zig with following content:
const std = @import("std");

const P9Tag = enum(u16) {
    NoTag = std.math.maxInt(std.meta.Tag(@This())),
    _,
};

comptime {
    _ = P9Tag;
}
  1. Run zig build-obj repro.zig
zig build-obj ./repro.zig
zsh: segmentation fault (core dumped)  zig build-obj ./repro.zig
Stack trace
/home/fardragon/Workspace/zig/src/InternPool.zig:1509:22: 0x52c431e in getLocalShared (main.zig)
    return &ip.locals[@intFromEnum(tid)].shared;
                     ^
/home/fardragon/Workspace/zig/src/InternPool.zig:4787:44: 0x5da8716 in itemPtr (main.zig)
            const slice = ip.getLocalShared(unwrapped.tid).items.acquire().view().slice();
                                           ^
/home/fardragon/Workspace/zig/src/InternPool.zig:4768:47: 0x588d9d2 in getItem (main.zig)
            const item_ptr = unwrapped.itemPtr(ip);
                                              ^
/home/fardragon/Workspace/zig/src/InternPool.zig:6917:41: 0x5655c16 in indexToKey (main.zig)
    const item = unwrapped_index.getItem(ip);
                                        ^
/home/fardragon/Workspace/zig/src/Sema.zig:17676:38: 0x816d595 in zirTypeInfo (main.zig)
                        ip.indexToKey(enum_type.values.get(ip)[tag_index]).int,
                                     ^
/home/fardragon/Workspace/zig/src/Sema.zig:1253:66: 0x74fba08 in analyzeBodyInner (main.zig)
            .type_info                    => try sema.zirTypeInfo(block, inst),
                                                                 ^
/home/fardragon/Workspace/zig/src/Sema.zig:1044:26: 0x6d1ecd2 in analyzeFnBody (main.zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/fardragon/Workspace/zig/src/Sema.zig:8331:27: 0x8bda29b in analyzeCall (main.zig)
        sema.analyzeFnBody(&child_block, fn_zir_info.body) catch |err| switch (err) {
                          ^
/home/fardragon/Workspace/zig/src/Sema.zig:7297:43: 0x8112671 in zirCall__anon_507330 (main.zig)
    const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
                                          ^
/home/fardragon/Workspace/zig/src/Sema.zig:1183:62: 0x74f7908 in analyzeBodyInner (main.zig)
            .field_call                   => try sema.zirCall(block, inst, .field),
                                                             ^
/home/fardragon/Workspace/zig/src/Sema.zig:1062:30: 0x753df57 in analyzeInlineBody (main.zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/fardragon/Workspace/zig/src/Sema.zig:1095:39: 0x6d27f29 in resolveInlineBody (main.zig)
    return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
                                      ^
/home/fardragon/Workspace/zig/src/Sema.zig:7596:65: 0x955be73 in analyzeArg (main.zig)
                const uncoerced_arg = try sema.resolveInlineBody(block, arg_body, zir_call.call_inst);
                                                                ^
/home/fardragon/Workspace/zig/src/Sema.zig:7837:41: 0x8bcc155 in analyzeCall (main.zig)
        arg.* = try args_info.analyzeArg(sema, block, arg_idx, param_ty, func_ty_info, callee, maybe_func_inst);
                                        ^
/home/fardragon/Workspace/zig/src/Sema.zig:7297:43: 0x8112671 in zirCall__anon_507330 (main.zig)
    const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
                                          ^
/home/fardragon/Workspace/zig/src/Sema.zig:1183:62: 0x74f7908 in analyzeBodyInner (main.zig)
            .field_call                   => try sema.zirCall(block, inst, .field),
                                                             ^
/home/fardragon/Workspace/zig/src/Sema.zig:1062:30: 0x753df57 in analyzeInlineBody (main.zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/fardragon/Workspace/zig/src/Sema.zig:37717:43: 0x758d75b in resolveDeclaredEnumInner (main.zig)
            _ = try sema.analyzeInlineBody(block, body, inst);
                                          ^
/home/fardragon/Workspace/zig/src/Sema.zig:37665:34: 0x6d4e174 in resolveDeclaredEnum (main.zig)
    sema.resolveDeclaredEnumInner(
                                 ^
/home/fardragon/Workspace/zig/src/Sema.zig:3250:33: 0x81ff890 in zirEnumDecl (main.zig)
    try Sema.resolveDeclaredEnum(
                                ^
/home/fardragon/Workspace/zig/src/Sema.zig:1384:64: 0x7501dba in analyzeBodyInner (main.zig)
                    .enum_decl          => try sema.zirEnumDecl(          block, extended, inst),
                                                               ^
/home/fardragon/Workspace/zig/src/Sema.zig:1062:30: 0x753df57 in analyzeInlineBody (main.zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/fardragon/Workspace/zig/src/Sema.zig:1095:39: 0x6d27f29 in resolveInlineBody (main.zig)
    return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
                                      ^
/home/fardragon/Workspace/zig/src/Zcu/PerThread.zig:1147:58: 0x63f8e86 in analyzeNavVal (main.zig)
            const result_ref = try sema.resolveInlineBody(&block, value_body, inst_resolved.inst);
                                                         ^
/home/fardragon/Workspace/zig/src/Zcu/PerThread.zig:982:80: 0x5e79f03 in ensureNavValUpToDate (main.zig)
    const invalidate_value: bool, const new_failed: bool = if (pt.analyzeNavVal(nav_id)) |result| res: {
                                                                               ^
/home/fardragon/Workspace/zig/src/Sema.zig:31701:49: 0x6d36551 in ensureNavResolved (main.zig)
        .fully => return pt.ensureNavValUpToDate(nav_index),
                                                ^
/home/fardragon/Workspace/zig/src/Sema.zig:31729:31: 0x82f477c in analyzeNavRefInner (main.zig)
    try sema.ensureNavResolved(block, src, orig_nav_index, if (is_ref) .type else .fully);
                              ^
/home/fardragon/Workspace/zig/src/Sema.zig:31617:44: 0x759159e in analyzeNavVal (main.zig)
    const ref = try sema.analyzeNavRefInner(block, src, nav_index, false);
                                           ^
/home/fardragon/Workspace/zig/src/Sema.zig:6948:30: 0x8116aa4 in zirDeclVal (main.zig)
    return sema.analyzeNavVal(block, src, nav);
                             ^
/home/fardragon/Workspace/zig/src/Sema.zig:1191:65: 0x74f80e0 in analyzeBodyInner (main.zig)
            .decl_val                     => try sema.zirDeclVal(block, inst),
                                                                ^
/home/fardragon/Workspace/zig/src/Sema.zig:1062:30: 0x753df57 in analyzeInlineBody (main.zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/fardragon/Workspace/zig/src/Sema.zig:1095:39: 0x6d27f29 in resolveInlineBody (main.zig)
    return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
                                      ^
/home/fardragon/Workspace/zig/src/Zcu/PerThread.zig:898:50: 0x63eef1e in analyzeComptimeUnit (main.zig)
    const result_ref = try sema.resolveInlineBody(&block, value_body, inst_resolved.inst);
                                                 ^
/home/fardragon/Workspace/zig/src/Zcu/PerThread.zig:802:34: 0x5e7723d in ensureComptimeUnitUpToDate (main.zig)
    return pt.analyzeComptimeUnit(cu_id) catch |err| switch (err) {
                                 ^
/home/fardragon/Workspace/zig/src/Compilation.zig:4756:67: 0x592bedf in processOneJob (main.zig)
                .@"comptime" => |cu| pt.ensureComptimeUnitUpToDate(cu),
                                                                  ^
/home/fardragon/Workspace/zig/src/Compilation.zig:4613:30: 0x56b6550 in performAllTheWork (main.zig)
            try processOneJob(@intFromEnum(Zcu.PerThread.Id.main), comp, job);
                             ^
/home/fardragon/Workspace/zig/src/Compilation.zig:2835:31: 0x54d99af in update (main.zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/fardragon/Workspace/zig/src/main.zig:4433:20: 0x5520680 in updateModule (main.zig)
    try comp.update(prog_node);
                   ^
/home/fardragon/Workspace/zig/src/main.zig:3603:21: 0x559a3b7 in buildOutputType (main.zig)
        updateModule(comp, color, root_prog_node) catch |err| switch (err) {
                    ^
/home/fardragon/Workspace/zig/src/main.zig:264:31: 0x55fb726 in mainArgs (main.zig)
        return buildOutputType(gpa, arena, args, .{ .build = .Obj });
                              ^
/home/fardragon/Workspace/zig/src/main.zig:199:20: 0x5443cab in main (main.zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/fardragon/Workspace/zig/lib/std/start.zig:681:37: 0x5441681 in main (std.zig)
            const result = root.main() catch |err| {
                                    ^
???:?:?: 0x7f346fb9b6b4 in ??? (libc.so.6)
Unwind information for `libc.so.6:0x7f346fb9b6b4` was not available, trace may be incomplete

???:?:?: 0x7f346fb9b768 in ??? (libc.so.6)
???:?:?: 0xab39164 in ??? (???)
AIR
thread 156292 panic: index out of bounds: index 42, len 33
Analyzing Analyzing '/home/fardragon/Workspace/zig/lib/std/meta.zig'
      %3542 = dbg_stmt(2, 5)
      %3543 = block_comptime(reason=type, {
        %3544 = break_inline(%3543, %3541)
      }) 
    > %3545 = type_info(%3543) 
      %3546 = dbg_stmt(2, 20)
      %3548 = enum_literal("enum") 
      %3554 = enum_literal("union") 
      %3547 = switch_block(%3545,
        else => {
          %3571 = block_comptime(reason=compile_error_string, {
            %3572 = str("expected enum or union type, found '")
            %3573 = type_name(%3541) 
            %3574 = array_cat(%3572, %3573) 
            %3575 = str("'")
            %3576 = array_cat(%3574, %3575) 
            %3577 = break_inline(%3571, %3576)
          }) 
          %3578 = compile_error(%3571) 
        },
        by_val %3548 => {
          %3549 = dbg_var_val(%3547, "info")
          %3550 = dbg_stmt(3, 32)
          %3551 = field_val(%3547, "tag_type") 
          %3552 = as_node(@type_type, %3551) 
          %3553 = break(%3547, %3552)
        },
        by_val %3554 => {
          %3555 = dbg_var_val(%3547, "info")
          %3560 = block({
            %3556 = dbg_stmt(4, 33)
            %3557 = field_val(%3547, "tag_type") 
            %3558 = is_non_null(%3557) 
            %3559 = condbr(%3558, {
              %3561 = optional_payload_unsafe(%3557) 
              %3562 = as_node(@type_type, %3561) 
              %3563 = break(%3560, %3562)
            }, {
              %3564 = block_comptime(reason=compile_error_string, {
                %3565 = type_name(%3541) 
                %3566 = str(" has no tag type")
                %3567 = array_cat(%3565, %3566) 
                %3568 = break_inline(%3564, %3567)
              }) 
              %3569 = compile_error(%3564) 
            }) 
          }) 
          %3570 = break(%3547, %3560)
        }) 
      %3579 = dbg_stmt(2, 5)
      %3580 = restore_err_ret_index_fn_entry(%3547) 
      %3581 = ret_node(%3547) 
    For full context, use the command
      zig ast-check -t /home/fardragon/Workspace/zig/lib/std/meta.zig

  in repro.zig
    > %13 = field_call(.auto, %11, "Tag", [
        {%14, %15},
      ]) 
  in repro.zig
    > %9 = field_call(.auto, %7, "maxInt", [
        {%10..%16},
      ]) 
  in repro.zig
    > %5 = extended(enum_decl(hash(8ad7bc0e12b2059586490e0828b24192) parent, nonexhaustive, {}, {}, @u16_type, {%6..%18}, {
        NoTag = %17,
      }) 
  in repro.zig
    > %21 = decl_val("P9Tag")

Expected Behavior

Not really sure if this should work (probably not), but at least I'd expect the same error as when the enum's name is stated explicitly.

Trying:

const std = @import("std");

const P9Tag = enum(u16) {
    NoTag = std.math.maxInt(std.meta.Tag(P9Tag)),
    _,
};

comptime {
    _ = P9Tag;
}

Results in:

repro.zig:3:1: error: dependency loop detected
const P9Tag = enum(u16) {
^~~~~
referenced by:
    P9Tag: repro.zig:3:15
    comptime: repro.zig:9:9
    4 reference(s) hidden; use '-freference-trace=6' to see all references

As a side note: Shouldn't this error be pointing at the line that causes the loop instead of the type's definition?

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