-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
LLVM backend hits unreachable
lowering pointer to comptime field
#12963
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
Comments
expected behavior is multiple compile errors |
What would the compile errors be? The code compiles and passes in stage 1. |
Another variation: const std = @import("std");
test {
const T = std.meta.Tuple(&[_]type{struct {}});
var t: T = undefined;
var ptr = &t.@"0";
_ = ptr;
} It seems to me that getting a pointer to a zero-sized field is the problem. |
This is not specific to tuples: const std = @import("std");
test {
const T = struct {
comptime a: struct{} = .{},
};
var t: T = undefined;
inline for (std.meta.fields(T)) |f| {
var ptr = &@field(t, f.name);
_ = ptr;
}
} |
This seems like a separate issue that is hitting the same TODO. It should produce a compile error that you can't use T in a runtime context...but it doesn't. The main issue with tuples/anonStructs is that the logic for zero-sized field pointers in sema is flawed. In
#12977 fixed tuples/ |
Sure you can, all the operations on them just end up being comptime known since they can only have one possible value.
Zero-sized fields are comptime since they have only one possible value which is know at comptime. I think the correct solution is to generate |
Yes, for values. But shouldn't a pointer to field have a runtime value, even if it's zero-sized? const Foo = struct {
a: struct{} = .{},
};
// This is fine in stage1 and stage2, no comptime_field_ptr
var foo: Foo = .{};
var ptr = &foo.a;
_ = ptr;
//This doesn't work in stage2, produces comptime_field_ptr
const T = std.meta.Tuple(&[_]type{struct {}});
var t: T = .{ .@"0" = .{} };
var ptr2 = &t.@"0";
_ = ptr2; Both are essentially the same, but the first example works while the other doesn't. edit: I suspect that:
From what I understood, comptime_field_ptrs should never reach llvm. If is does then there is something wrong in sema. |
This is also not specific to zero-bit types: test {
const T = struct {
comptime a: u32 = 2,
};
var t: T = undefined;
var ptr = &t.a;
_ = ptr;
}
Pointers to comptime fields should behave same as pointers to container-level variables so that above example should behave same as: test {
const T = struct {
var a: u32 = 2;
};
var ptr = &T.a;
_ = ptr;
} |
Oh, so stage2 allows structs with comptime fields to be a runtime variable. Didn't know that.
Will this mean that |
That has always been allowed, I think you might be confusing comptime fields with fields with comptime only types: const S = struct {
// comptime field
comptime a: i32 = 2,
// field with a comptime only type
b: comptime_int,
}; The key difference is that comptime fields are tied to the type while fields with comptime only types are tied to an instance.
No, but it does mean that |
Running into this in Bun The code causing the issue: else if (comptime strings.eqlComptime(function_name_literal, "hasProperty")) {
def.hasProperty = @field(staticFunctions, "hasProperty").rfn;
} else if (comptime strings.eqlComptime(function_name_literal, "getProperty")) {
def.getProperty = @field(staticFunctions, "getProperty").rfn;
} else if (comptime strings.eqlComptime(function_name_literal, "setProperty")) {
def.setProperty = @field(staticFunctions, "setProperty").rfn;
} else if (comptime strings.eqlComptime(function_name_literal, "deleteProperty")) {
def.deleteProperty = &@field(staticFunctions, "deleteProperty").rfn;
} else if (comptime strings.eqlComptime(function_name_literal, "getPropertyNames")) {
def.getPropertyNames = @field(staticFunctions, "getPropertyNames").rfn;
} else if (comptime strings.eqlComptime(function_name_literal, "convertToType")) {
def.convertToType = @field(staticFunctions, "convertToType").rfn; Workaround: make |
This commit resolves issue 'Resolve issue with zig self-hosted' (#32). The only pain point is ziglang/zig#12963 which forces us to predefine some types for initial state of entities.
This commit resolves issue 'Resolve issue with zig self-hosted' (#32). The only pain point is ziglang/zig#12963 which forces us to predefine some types for initial state of entities.
Hi, just an update on this issue. I tested this issue again on version 0.11.0-dev.3654+2d6d2a1d1 and the TODO is now gone; however, now Zig just crashes without any errors. I also tried this code: const std = @import("std");
test {
const T = struct {struct {}};
var t: T = undefined;
inline for (std.meta.fields(T)) |f| {
var ptr = &@field(t, f.name);
_ = ptr;
}
}
Same thing. The compiler just crashes. Edit: This crashes too. test {
const T = struct { struct {} };
var t: T = undefined;
var ptr = &t[0];
_ = ptr;
} |
Current status as of
|
unreachable
lowering pointer to comptime field
Interesting that the compiler crashes with |
Both still hit unreachable with a debug build. |
This is now an error:
|
Uh oh!
There was an error while loading. Please reload this page.
Zig Version
0.10.0-dev.4060+61aaef0b0
Steps to Reproduce
Expected Behavior
Actual Behavior
The text was updated successfully, but these errors were encountered: