Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuples with default fields allowed by mistake, crash in self hosted #20277

Open
MasonRemaley opened this issue Jun 12, 2024 · 1 comment
Open
Labels
bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Milestone

Comments

@MasonRemaley
Copy link
Contributor

Zig Version

0.14.0-dev.453+eda846b86

Steps to Reproduce and Observed Behavior

The compiler currently allows code like this:

    const Tuple = struct {
        u8 = 1,
        u8 = 2,
        u8 = 3,
    };

This would not be a crazy feature, I am personally indifferent to whether or not it should be supported.

However, the actual behavior of these default field tuples is not what one would reasonably expect. This leads me to believe that we don't actually intend to support them right now, but are failing to reject them by mistake.

For example, this case fails to compile:

test "tuple issue" {
    const Tuple = struct {
        u8 = 1,
        u8 = 2,
        u8 = 3,
    };
    const temp = Tuple{ 1, 2 };
    std.debug.print("\n\ntuple: {}\n\n", .{temp});
}
src/main.zig:38:23: error: missing tuple field with index 2
    const temp = Tuple{ 1, 2 };

Furthermore, if instead of building Zig from C++ I self host it, the compiler crashes on the same code (0.14.0-dev.437+d9bd34fd0):

test
└─ run test
   └─ zig test Debug native failure
error: thread 64473 panic: reached unreachable code
Analyzing src/main.zig: main.zig:test.tuple issue
      %11 = dbg_stmt(2, 5)
      %12 = extended(struct_decl(hash(fcc5cad6a58e325ccaea84049d669e0a) known_non_opv, tuple, dbg_var, {}, auto, {}, {
        @"0": @u8_type = {%13},
        @"1": @u8_type = {%14, %15},
        @"2": @u8_type = {%16, %17},
      }) node_offset:33:19 to :33:25
      %18 = dbg_var_val(%12, "Tuple")
      %19 = dbg_stmt(7, 5)
      %20 = block_comptime({
        %21 = break(%20, %12)
      }) node_offset:38:18 to :38:23
      %22 = validate_array_init_ty(%20, 2) node_offset:38:18 to :38:31
      %23 = array_init_elem_type(%20, 0)
      %24 = array_init_elem_type(%20, 1)
      %25 = int(2)
    > %26 = array_init(%20{@one, %25}) node_offset:38:18 to :38:31
      %27 = dbg_var_val(%26, "temp")
      %28 = dbg_stmt(8, 5)
      %29 = decl_ref("std") token_offset:39:5 to :39:8
      %30 = dbg_stmt(8, 8)
      %31 = field_ptr(%29, "debug") node_offset:39:5 to :39:14
      %32 = dbg_stmt(8, 20)
      %33 = field_call(nodiscard .auto, %31, "print", [
        {
          %34 = str("\n\ntuple: {}\n\n")
          %35 = break_inline(%33, %34)
        },
        {
          %36 = validate_array_init_result_ty(%33, 1) node_offset:39:42 to :39:49
          %37 = array_init_elem_type(%33, 0)
          %38 = array_init(%33{%26}) node_offset:39:42 to :39:49
          %39 = break_inline(%33, %38)
        },
      ]) node_offset:39:5 to :39:50
      %40 = restore_err_ret_index_unconditional(.none) node_offset:32:1 to :32:5
      %41 = ret_implicit(@void_value) token_offset:40:1 to :40:1
    For full context, use the command
      zig ast-check -t src/main.zig


/home/mason/Documents/zon/zig/lib/std/debug.zig:412:14: 0x5ae68bc in assert (zig)
    if (!ok) unreachable; // assertion failure
             ^
/home/mason/Documents/zon/zig/src/InternPool.zig:2104:15: 0x649279c in fieldInit (zig)
        assert(s.haveFieldInits(ip));
              ^
/home/mason/Documents/zon/zig/src/type.zig:3217:50: 0x6d4e350 in structFieldDefaultValue (zig)
                const val = struct_type.fieldInit(ip, index);
                                                 ^
/home/mason/Documents/zon/zig/src/Sema.zig:20681:65: 0x68c840f in zirArrayInit (zig)
    const is_tuple = array_ty.zigTypeTag(mod) == .Struct;
                                                                ^
/home/mason/Documents/zon/zig/src/Sema.zig:1098:67: 0x6381fdb in analyzeBodyInner (zig)
            .array_init                   => try sema.zirArrayInit(block, inst, false),
                                                                  ^
/home/mason/Documents/zon/zig/src/Sema.zig:892:26: 0x637d7e1 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/mason/Documents/zon/zig/src/Module.zig:4640:23: 0x606dc96 in analyzeFnBody (zig)

                      ^
/home/mason/Documents/zon/zig/src/Module.zig:3144:32: 0x5dd1788 in ensureFuncBodyAnalyzed (zig)
        .inline_only => unreachable, // don't queue work for this
                               ^
/home/mason/Documents/zon/zig/src/Compilation.zig:3405:42: 0x5dcf29b in processOneJob (zig)

                                         ^
/home/mason/Documents/zon/zig/src/Compilation.zig:3345:30: 0x5c0885c in performAllTheWork (zig)
    while (true) {
                             ^
/home/mason/Documents/zon/zig/src/Compilation.zig:2132:31: 0x5c0441c in update (zig)
    }
                              ^
/home/mason/Documents/zon/zig/src/main.zig:4074:32: 0x5c7e07b in serve (zig)
                try comp.update(main_progress_node);
                               ^
/home/mason/Documents/zon/zig/src/main.zig:3373:22: 0x5c9c8d4 in buildOutputType (zig)
            try serve(
                     ^
/home/mason/Documents/zon/zig/src/main.zig:269:31: 0x5ae8d2b in mainArgs (zig)
        return buildOutputType(gpa, arena, args, .zig_test);
                              ^
/home/mason/Documents/zon/zig/src/main.zig:209:20: 0x5ae5a85 in main (zig)
 temp ➜ ~/Documents/zon/zig/build/stage4/bin/zig build test
test
└─ run test
   └─ zig test Debug native failure
error: thread 64550 panic: reached unreachable code
Analyzing src/main.zig: main.zig:test.tuple issue
      %11 = dbg_stmt(2, 5)
      %12 = extended(struct_decl(hash(fcc5cad6a58e325ccaea84049d669e0a) known_non_opv, tuple, dbg_var, {}, auto, {}, {
        @"0": @u8_type = {%13},
        @"1": @u8_type = {%14, %15},
        @"2": @u8_type = {%16, %17},
      }) node_offset:33:19 to :33:25
      %18 = dbg_var_val(%12, "Tuple")
      %19 = dbg_stmt(7, 5)
      %20 = block_comptime({
        %21 = break(%20, %12)
      }) node_offset:38:18 to :38:23
      %22 = validate_array_init_ty(%20, 2) node_offset:38:18 to :38:31
      %23 = array_init_elem_type(%20, 0)
      %24 = array_init_elem_type(%20, 1)
      %25 = int(2)
    > %26 = array_init(%20{@one, %25}) node_offset:38:18 to :38:31
      %27 = dbg_var_val(%26, "temp")
      %28 = dbg_stmt(8, 5)
      %29 = decl_ref("std") token_offset:39:5 to :39:8
      %30 = dbg_stmt(8, 8)
      %31 = field_ptr(%29, "debug") node_offset:39:5 to :39:14
      %32 = dbg_stmt(8, 20)
      %33 = field_call(nodiscard .auto, %31, "print", [
        {
          %34 = str("\n\ntuple: {}\n\n")
          %35 = break_inline(%33, %34)
        },
        {
          %36 = validate_array_init_result_ty(%33, 1) node_offset:39:42 to :39:49
          %37 = array_init_elem_type(%33, 0)
          %38 = array_init(%33{%26}) node_offset:39:42 to :39:49
          %39 = break_inline(%33, %38)
        },
      ]) node_offset:39:5 to :39:50
      %40 = restore_err_ret_index_unconditional(.none) node_offset:32:1 to :32:5
      %41 = ret_implicit(@void_value) token_offset:40:1 to :40:1
    For full context, use the command
      zig ast-check -t src/main.zig


/home/mason/Documents/zon/zig/lib/std/debug.zig:412:14: 0x5ae68bc in assert (zig)
    if (!ok) unreachable; // assertion failure
             ^
/home/mason/Documents/zon/zig/src/InternPool.zig:2104:15: 0x649279c in fieldInit (zig)
        assert(s.haveFieldInits(ip));
              ^
/home/mason/Documents/zon/zig/src/type.zig:3217:50: 0x6d4e350 in structFieldDefaultValue (zig)
                const val = struct_type.fieldInit(ip, index);
                                                 ^
/home/mason/Documents/zon/zig/src/Sema.zig:20681:65: 0x68c840f in zirArrayInit (zig)
    const is_tuple = array_ty.zigTypeTag(mod) == .Struct;
                                                                ^
/home/mason/Documents/zon/zig/src/Sema.zig:1098:67: 0x6381fdb in analyzeBodyInner (zig)
            .array_init                   => try sema.zirArrayInit(block, inst, false),
                                                                  ^
/home/mason/Documents/zon/zig/src/Sema.zig:892:26: 0x637d7e1 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/mason/Documents/zon/zig/src/Module.zig:4640:23: 0x606dc96 in analyzeFnBody (zig)

                      ^
/home/mason/Documents/zon/zig/src/Module.zig:3144:32: 0x5dd1788 in ensureFuncBodyAnalyzed (zig)
        .inline_only => unreachable, // don't queue work for this
                               ^
/home/mason/Documents/zon/zig/src/Compilation.zig:3405:42: 0x5dcf29b in processOneJob (zig)

                                         ^
/home/mason/Documents/zon/zig/src/Compilation.zig:3345:30: 0x5c0885c in performAllTheWork (zig)
    while (true) {
                             ^
/home/mason/Documents/zon/zig/src/Compilation.zig:2132:31: 0x5c0441c in update (zig)
    }
                              ^
/home/mason/Documents/zon/zig/src/main.zig:4074:32: 0x5c7e07b in serve (zig)
                try comp.update(main_progress_node);
                               ^
/home/mason/Documents/zon/zig/src/main.zig:3373:22: 0x5c9c8d4 in buildOutputType (zig)
            try serve(
                     ^
/home/mason/Documents/zon/zig/src/main.zig:269:31: 0x5ae8d2b in mainArgs (zig)
        return buildOutputType(gpa, arena, args, .zig_test);
                              ^
/home/mason/Documents/zon/zig/src/main.zig:209:20: 0x5ae5a85 in main (zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/mason/Documents/zon/zig/lib/std/start.zig:524:37: 0x5ae551e in main (zig)
            const result = root.main() catch |err| {
                                    ^
../sysdeps/nptl/libc_start_call_main.h:58:16: 0x72ebc8029d8f in __libc_start_call_main (../sysdeps/x86/libc-start.c)
../csu/libc-start.c:392:3: 0x72ebc8029e3f in __libc_start_main_impl (../sysdeps/x86/libc-start.c)
???:?:?: 0x5ae5164 in ??? (???)
???:?:?: 0x0 in ??? (???)

error: the following command terminated unexpectedly:
/home/mason/Documents/zon/zig/build/stage4/bin/zig test -ODebug -Mroot=/home/mason/Downloads/zig-linux-x86_64-0.14.0-dev.23+d9bd34fd0/temp/src/main.zig --cache-dir /home/mason/Downloads/zig-linux-x86_64-0.14.0-dev.23+d9bd34fd0/temp/.zig-cache --global-cache-dir /home/mason/.cache/zig --name test --listen=-
Build Summary: 2/5 steps succeeded; 1 failed (disable with --summary none)
test transitive failure
└─ run test transitive failure
   └─ zig test Debug native failure
error: the following build command failed with exit code 1:
/home/mason/Downloads/zig-linux-x86_64-0.14.0-dev.23+d9bd34fd0/temp/.zig-cache/o/98bf75858b188f353668d0358e0cbc68/build /home/mason/Documents/zon/zig/build/stage4/bin/zig /home/mason/Downloads/zig-linux-x86_64-0.14.0-dev.23+d9bd34fd0/temp /home/mason/Downloads/zig-linux-x86_64-0.14.0-dev.23+d9bd34fd0/temp/.zig-cache /home/mason/.cache/zig --seed 0x8d4d9aa9 -Z6370c73436a66bfc test

Expected Behavior

I expected default tuple fields to be rejected by the compiler.

@MasonRemaley MasonRemaley added the bug Observed behavior contradicts documented or intended behavior label Jun 12, 2024
@MasonRemaley MasonRemaley mentioned this issue Jun 12, 2024
4 tasks
@mlugg
Copy link
Member

mlugg commented Jun 12, 2024

The currently intended behavior for tuples (discussed in some compiler meeting waaaaayyyy back when) is to not permit default values, except in comptime fields. This has been on my list as a part of a bigger refactor around anon structs for a while (I don't see myself getting to it soon, so others are free to take it up).

@Vexu Vexu added the frontend Tokenization, parsing, AstGen, Sema, and Liveness. label Jun 13, 2024
@Vexu Vexu added this to the 0.14.0 milestone Jun 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Projects
None yet
Development

No branches or pull requests

3 participants