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

Segmentation fault compiling field access of comptime struct at comptime #16468

Open
amp-59 opened this issue Jul 21, 2023 · 3 comments
Open
Labels
bug Observed behavior contradicts documented or intended behavior
Milestone

Comments

@amp-59
Copy link
Contributor

amp-59 commented Jul 21, 2023

Zig Version

0.11.0-dev.4059+17255bed4

Steps to Reproduce and Observed Behavior

Compile example program with zig build-obj comptime_state_error.zig
comptime_state_error.zig:

const Features = struct {
    f0: bool = false,
};
const features: *Features = blk: {
    var val: Features = .{};
    break :blk &val;
};
export fn useFeature0() void {
    comptime {
        features.f0 = true;
    }
}

Workaround:

const features_alt = struct {
    const f0: *bool = blk: {
        var val: bool = false;
        break :blk &val;
    };
};
export fn useFeature0Alt() void {
    comptime {
        features_alt.f0.* = true;
    }
}

Expected Behavior

@amp-59 amp-59 added the bug Observed behavior contradicts documented or intended behavior label Jul 21, 2023
@rohlem
Copy link
Contributor

rohlem commented Jul 21, 2023

From what I can tell neither of those examples are supposed to work:

  • comptime memory is supposed to become const once it goes out of scope - see make closure over comptime var a compile error; comptime vars become immutable when they go out of scope #7396 .
    In this case, because expressions initializing declarations are evaluated in a comptime context, blk is a comptime block in both cases, therefore var val should become immutable.
    This should in the future trigger a compile error for both examples, mentioning that these variables can only be referred to via pointers-to-const after the scope ends (types *const Features and *const bool in this examples).
  • The value a declaration is initialized with in Zig can not be overwritten by a different comptime block.
    However, you can assign to var declarations at runtime.

If you want your example to work as intended by the language, the location that the pointer points to needs to be its own var declaration, and the modification needs to happen at runtime (outside of comptime blocks):

// first example
const Features = struct {
    f0: bool = false,
};
var features_storage: Features = .{};
const features: *Features = &features_storage;
export fn useFeature0() void {
    features.f0 = true;
}

// second example
const features_alt = struct {
    var f0_storage: bool = false;
    const f0: *bool = &f0_storage;
};
export fn useFeature0Alt() void {
    features_alt.f0.* = true;
}

(Note that the pointers are not necessary here; you could remove them and directly assign values to features_storage and features_alt.f0_storage instead.)

@amp-59
Copy link
Contributor Author

amp-59 commented Jul 21, 2023

The significance of the source code posted above is that it will crash the compiler.

@andrewrk andrewrk added this to the 0.11.1 milestone Jul 21, 2023
@Pyrolistical
Copy link
Contributor

Pyrolistical commented Jul 27, 2023

This found something similar:

const S = struct {
    fn f(_: @This(), comptime comptime_value: u8) void {
        _ = comptime_value;
    }
};
fn g(comptime comptime_value: u8) void {
    _ = comptime_value;
}

pub fn main() void {
    var runtime_value: u8 = 0;

    const s = S{};
    s.f(runtime_value);

    // this errors correctly
    // g(runtime_value);
}

When running zig build-exe that file, it is expected to error: runtime-known argument passed to comptime parameter, but it segfaults instead.

@andrewrk andrewrk modified the milestones: 0.11.1, 0.12.0, 0.13.0 Jan 29, 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
Projects
None yet
Development

No branches or pull requests

4 participants