mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 00:08:56 +00:00
stage2: fix handling of aggregates with mixed comptime-only fields
This commit is contained in:
parent
f1cff4fa4a
commit
32c90cb553
@ -25048,9 +25048,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ
|
||||
}
|
||||
|
||||
pub fn typeHasRuntimeBits(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
|
||||
if ((try sema.typeHasOnePossibleValue(block, src, ty)) != null) return false;
|
||||
if (try sema.typeRequiresComptime(block, src, ty)) return false;
|
||||
return true;
|
||||
return ty.hasRuntimeBitsAdvanced(false, sema.kit(block, src));
|
||||
}
|
||||
|
||||
fn typeAbiSize(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u64 {
|
||||
|
||||
@ -9185,7 +9185,7 @@ fn isByRef(ty: Type) bool {
|
||||
.AnyFrame,
|
||||
=> return false,
|
||||
|
||||
.Array, .Frame => return ty.hasRuntimeBitsIgnoreComptime(),
|
||||
.Array, .Frame => return ty.hasRuntimeBits(),
|
||||
.Struct => {
|
||||
// Packed structs are represented to LLVM as integers.
|
||||
if (ty.containerLayout() == .Packed) return false;
|
||||
@ -9204,7 +9204,7 @@ fn isByRef(ty: Type) bool {
|
||||
var count: usize = 0;
|
||||
const fields = ty.structFields();
|
||||
for (fields.values()) |field| {
|
||||
if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime()) continue;
|
||||
if (field.is_comptime or !field.ty.hasRuntimeBits()) continue;
|
||||
|
||||
count += 1;
|
||||
if (count > max_fields_byval) return true;
|
||||
@ -9212,7 +9212,7 @@ fn isByRef(ty: Type) bool {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
.Union => return ty.hasRuntimeBitsIgnoreComptime(),
|
||||
.Union => return ty.hasRuntimeBits(),
|
||||
.ErrorUnion => return isByRef(ty.errorUnionPayload()),
|
||||
.Optional => {
|
||||
var buf: Type.Payload.ElemType = undefined;
|
||||
|
||||
10
src/type.zig
10
src/type.zig
@ -2365,6 +2365,7 @@ pub const Type = extern union {
|
||||
.@"anyframe",
|
||||
.anyopaque,
|
||||
.@"opaque",
|
||||
.type_info,
|
||||
=> return true,
|
||||
|
||||
// These are false because they are comptime-only types.
|
||||
@ -2379,7 +2380,6 @@ pub const Type = extern union {
|
||||
.enum_literal,
|
||||
.empty_struct,
|
||||
.empty_struct_literal,
|
||||
.type_info,
|
||||
.bound_fn,
|
||||
// These are function *bodies*, not pointers.
|
||||
// Special exceptions have to be made when emitting functions due to
|
||||
@ -2464,14 +2464,6 @@ pub const Type = extern union {
|
||||
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
if (sema_kit) |sk| {
|
||||
_ = try sk.sema.typeRequiresComptime(sk.block, sk.src, ty);
|
||||
}
|
||||
switch (struct_obj.requires_comptime) {
|
||||
.yes => return false,
|
||||
.wip, .no => if (struct_obj.known_non_opv) return true,
|
||||
.unknown => {},
|
||||
}
|
||||
if (struct_obj.status == .field_types_wip) {
|
||||
// In this case, we guess that hasRuntimeBits() for this type is true,
|
||||
// and then later if our guess was incorrect, we emit a compile error.
|
||||
|
||||
@ -1196,7 +1196,9 @@ test "equality of pointers to comptime const" {
|
||||
}
|
||||
|
||||
test "storing an array of type in a field" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() void {
|
||||
@ -1221,3 +1223,32 @@ test "storing an array of type in a field" {
|
||||
|
||||
S.doTheTest();
|
||||
}
|
||||
|
||||
test "pass pointer to field of comptime-only type as a runtime parameter" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
const Mixed = struct {
|
||||
T: type,
|
||||
x: i32,
|
||||
};
|
||||
const bag: Mixed = .{
|
||||
.T = bool,
|
||||
.x = 1234,
|
||||
};
|
||||
|
||||
var ok = false;
|
||||
|
||||
fn doTheTest() !void {
|
||||
foo(&bag.x);
|
||||
try expect(ok);
|
||||
}
|
||||
|
||||
fn foo(ptr: *const i32) void {
|
||||
ok = ptr.* == 1234;
|
||||
}
|
||||
};
|
||||
try S.doTheTest();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user