authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-09 19:23:36-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-09 19:23:36-07:00
log32c90cb5539c3b340ae1b0b13d2b1521ebb6b1b0
tree149e21f6afdce496a95d29d97a1d6e3ccd6d0f4d
parentf1cff4fa4a28d42ac9055f94ee9a8f7fd2831cd7

stage2: fix handling of aggregates with mixed comptime-only fields


4 files changed, 37 insertions(+), 16 deletions(-)

src/Sema.zig+1-3
......@@ -25048,9 +25048,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ
2504825048}
2504925049
2505025050pub fn typeHasRuntimeBits(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
25051 if ((try sema.typeHasOnePossibleValue(block, src, ty)) != null) return false;
25052 if (try sema.typeRequiresComptime(block, src, ty)) return false;
25053 return true;
25051 return ty.hasRuntimeBitsAdvanced(false, sema.kit(block, src));
2505425052}
2505525053
2505625054fn typeAbiSize(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u64 {
src/codegen/llvm.zig+3-3
......@@ -9185,7 +9185,7 @@ fn isByRef(ty: Type) bool {
91859185 .AnyFrame,
91869186 => return false,
91879187
9188 .Array, .Frame => return ty.hasRuntimeBitsIgnoreComptime(),
9188 .Array, .Frame => return ty.hasRuntimeBits(),
91899189 .Struct => {
91909190 // Packed structs are represented to LLVM as integers.
91919191 if (ty.containerLayout() == .Packed) return false;
......@@ -9204,7 +9204,7 @@ fn isByRef(ty: Type) bool {
92049204 var count: usize = 0;
92059205 const fields = ty.structFields();
92069206 for (fields.values()) |field| {
9207 if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime()) continue;
9207 if (field.is_comptime or !field.ty.hasRuntimeBits()) continue;
92089208
92099209 count += 1;
92109210 if (count > max_fields_byval) return true;
......@@ -9212,7 +9212,7 @@ fn isByRef(ty: Type) bool {
92129212 }
92139213 return false;
92149214 },
9215 .Union => return ty.hasRuntimeBitsIgnoreComptime(),
9215 .Union => return ty.hasRuntimeBits(),
92169216 .ErrorUnion => return isByRef(ty.errorUnionPayload()),
92179217 .Optional => {
92189218 var buf: Type.Payload.ElemType = undefined;
src/type.zig+1-9
......@@ -2365,6 +2365,7 @@ pub const Type = extern union {
23652365 .@"anyframe",
23662366 .anyopaque,
23672367 .@"opaque",
2368 .type_info,
23682369 => return true,
23692370
23702371 // These are false because they are comptime-only types.
......@@ -2379,7 +2380,6 @@ pub const Type = extern union {
23792380 .enum_literal,
23802381 .empty_struct,
23812382 .empty_struct_literal,
2382 .type_info,
23832383 .bound_fn,
23842384 // These are function *bodies*, not pointers.
23852385 // Special exceptions have to be made when emitting functions due to
......@@ -2464,14 +2464,6 @@ pub const Type = extern union {
24642464
24652465 .@"struct" => {
24662466 const struct_obj = ty.castTag(.@"struct").?.data;
2467 if (sema_kit) |sk| {
2468 _ = try sk.sema.typeRequiresComptime(sk.block, sk.src, ty);
2469 }
2470 switch (struct_obj.requires_comptime) {
2471 .yes => return false,
2472 .wip, .no => if (struct_obj.known_non_opv) return true,
2473 .unknown => {},
2474 }
24752467 if (struct_obj.status == .field_types_wip) {
24762468 // In this case, we guess that hasRuntimeBits() for this type is true,
24772469 // and then later if our guess was incorrect, we emit a compile error.
test/behavior/eval.zig+32-1
......@@ -1196,7 +1196,9 @@ test "equality of pointers to comptime const" {
11961196}
11971197
11981198test "storing an array of type in a field" {
1199 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
1199 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1200 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1201 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12001202
12011203 const S = struct {
12021204 fn doTheTest() void {
......@@ -1221,3 +1223,32 @@ test "storing an array of type in a field" {
12211223
12221224 S.doTheTest();
12231225}
1226
1227test "pass pointer to field of comptime-only type as a runtime parameter" {
1228 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1229 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1230 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1231
1232 const S = struct {
1233 const Mixed = struct {
1234 T: type,
1235 x: i32,
1236 };
1237 const bag: Mixed = .{
1238 .T = bool,
1239 .x = 1234,
1240 };
1241
1242 var ok = false;
1243
1244 fn doTheTest() !void {
1245 foo(&bag.x);
1246 try expect(ok);
1247 }
1248
1249 fn foo(ptr: *const i32) void {
1250 ok = ptr.* == 1234;
1251 }
1252 };
1253 try S.doTheTest();
1254}