authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-19 23:39:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-21 14:48:40-07:00
logbaea62a8ad019bd7ad52324b932dd7d69683b80a
treef2e296977e6177e1df3edad8b723766a99735335
parent483b3a334487a60320296b876c12ccfc05d4a9fb

fix regressions from this branch


5 files changed, 169 insertions(+), 169 deletions(-)

src/InternPool.zig+36-18
......@@ -382,6 +382,7 @@ pub const Key = union(enum) {
382382
383383 pub const ComptimeBits = struct {
384384 start: u32,
385 /// This is the number of u32 elements, not the number of struct fields.
385386 len: u32,
386387
387388 pub fn get(this: @This(), ip: *const InternPool) []u32 {
......@@ -505,12 +506,23 @@ pub const Key = union(enum) {
505506 return false;
506507 }
507508
509 pub fn setTypesWip(s: @This(), ip: *InternPool) bool {
510 if (s.layout == .Packed) return false;
511 const flags_ptr = s.flagsPtr(ip);
512 if (flags_ptr.field_types_wip) return true;
513 flags_ptr.field_types_wip = true;
514 return false;
515 }
516
517 pub fn clearTypesWip(s: @This(), ip: *InternPool) void {
518 if (s.layout == .Packed) return;
519 s.flagsPtr(ip).field_types_wip = false;
520 }
521
508522 pub fn setLayoutWip(s: @This(), ip: *InternPool) bool {
509523 if (s.layout == .Packed) return false;
510524 const flags_ptr = s.flagsPtr(ip);
511 if (flags_ptr.field_types_wip or flags_ptr.layout_wip) {
512 return true;
513 }
525 if (flags_ptr.layout_wip) return true;
514526 flags_ptr.layout_wip = true;
515527 return false;
516528 }
......@@ -527,14 +539,6 @@ pub const Key = union(enum) {
527539 s.flagsPtr(ip).fully_resolved = false;
528540 }
529541
530 pub fn setRequiresComptime(s: @This(), ip: *InternPool) void {
531 assert(s.layout != .Packed);
532 const flags_ptr = s.flagsPtr(ip);
533 // Layout is resolved (and non-existent) in the case of a comptime-known struct.
534 flags_ptr.layout_resolved = true;
535 flags_ptr.requires_comptime = .yes;
536 }
537
538542 /// The returned pointer expires with any addition to the `InternPool`.
539543 /// Asserts the struct is not packed.
540544 pub fn size(self: @This(), ip: *InternPool) *u32 {
......@@ -567,7 +571,7 @@ pub const Key = union(enum) {
567571
568572 pub fn haveLayout(s: @This(), ip: *InternPool) bool {
569573 return switch (s.layout) {
570 .Packed => s.haveFieldTypes(ip),
574 .Packed => s.backingIntType(ip).* != .none,
571575 .Auto, .Extern => s.flagsPtr(ip).layout_resolved,
572576 };
573577 }
......@@ -3149,7 +3153,15 @@ pub const Alignment = enum(u6) {
31493153 return std.math.order(@intFromEnum(lhs), @intFromEnum(rhs));
31503154 }
31513155
3156 /// Relaxed comparison. We have this as default because a lot of callsites
3157 /// were upgraded from directly using comparison operators on byte units,
3158 /// with the `none` value represented by zero.
3159 /// Prefer `compareStrict` if possible.
31523160 pub fn compare(lhs: Alignment, op: std.math.CompareOperator, rhs: Alignment) bool {
3161 return std.math.compare(lhs.toRelaxedCompareUnits(), op, rhs.toRelaxedCompareUnits());
3162 }
3163
3164 pub fn compareStrict(lhs: Alignment, op: std.math.CompareOperator, rhs: Alignment) bool {
31533165 assert(lhs != .none);
31543166 assert(rhs != .none);
31553167 return std.math.compare(@intFromEnum(lhs), op, @intFromEnum(rhs));
......@@ -3194,6 +3206,7 @@ pub const Alignment = enum(u6) {
31943206 /// not invalidated when items are added to the `InternPool`.
31953207 pub const Slice = struct {
31963208 start: u32,
3209 /// This is the number of alignment values, not the number of u32 elements.
31973210 len: u32,
31983211
31993212 pub fn get(slice: Slice, ip: *const InternPool) []Alignment {
......@@ -3204,6 +3217,13 @@ pub const Alignment = enum(u6) {
32043217 }
32053218 };
32063219
3220 pub fn toRelaxedCompareUnits(a: Alignment) u8 {
3221 const n: u8 = @intFromEnum(a);
3222 assert(n <= @intFromEnum(Alignment.none));
3223 if (n == @intFromEnum(Alignment.none)) return 0;
3224 return n + 1;
3225 }
3226
32073227 const LlvmBuilderAlignment = @import("codegen/llvm/Builder.zig").Alignment;
32083228
32093229 pub fn toLlvm(this: @This()) LlvmBuilderAlignment {
......@@ -4067,16 +4087,14 @@ fn extraStructType(ip: *const InternPool, extra_index: u32) Key.StructType {
40674087 };
40684088 const field_aligns: Alignment.Slice = t: {
40694089 if (!s.data.flags.any_aligned_fields) break :t .{ .start = 0, .len = 0 };
4070 const len = (fields_len + 3) / 4;
4071 const aligns: Alignment.Slice = .{ .start = index, .len = len };
4072 index += len;
4090 const aligns: Alignment.Slice = .{ .start = index, .len = fields_len };
4091 index += (fields_len + 3) / 4;
40734092 break :t aligns;
40744093 };
40754094 const comptime_bits: Key.StructType.ComptimeBits = t: {
40764095 if (!s.data.flags.any_comptime_fields) break :t .{ .start = 0, .len = 0 };
4077 const len = (fields_len + 31) / 32;
4078 const comptime_bits: Key.StructType.ComptimeBits = .{ .start = index, .len = len };
4079 index += len;
4096 const comptime_bits: Key.StructType.ComptimeBits = .{ .start = index, .len = fields_len };
4097 index += (fields_len + 31) / 32;
40804098 break :t comptime_bits;
40814099 };
40824100 const runtime_order: Key.StructType.RuntimeOrder.Slice = t: {
src/Sema.zig+103-113
......@@ -17646,12 +17646,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1764617646 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);
1764717647
1764817648 for (struct_field_vals, 0..) |*field_val, i| {
17649 const name_nts = struct_type.fieldName(ip, i).unwrap().?;
17649 // TODO: write something like getCoercedInts to avoid needing to dupe
17650 const name = if (struct_type.fieldName(ip, i).unwrap()) |name_nts|
17651 try sema.arena.dupe(u8, ip.stringToSlice(name_nts))
17652 else
17653 try std.fmt.allocPrintZ(gpa, "{d}", .{i});
1765017654 const field_ty = struct_type.field_types.get(ip)[i].toType();
1765117655 const field_init = struct_type.fieldInit(ip, i);
1765217656 const field_is_comptime = struct_type.fieldIsComptime(ip, i);
17653 // TODO: write something like getCoercedInts to avoid needing to dupe
17654 const name = try sema.arena.dupe(u8, ip.stringToSlice(name_nts));
1765517657 const name_val = v: {
1765617658 var anon_decl = try block.startAnonDecl();
1765717659 defer anon_decl.deinit();
......@@ -17676,11 +17678,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1767617678
1767717679 const opt_default_val = if (field_init == .none) null else field_init.toValue();
1767817680 const default_val_ptr = try sema.optRefValue(block, field_ty, opt_default_val);
17679 const alignment = mod.structFieldAlignment(
17680 struct_type.field_aligns.get(ip)[i],
17681 field_ty,
17682 struct_type.layout,
17683 );
17681 const alignment = switch (struct_type.layout) {
17682 .Packed => .none,
17683 else => try sema.structFieldAlignment(
17684 struct_type.fieldAlign(ip, i),
17685 field_ty,
17686 struct_type.layout,
17687 ),
17688 };
1768417689
1768517690 const struct_field_fields = .{
1768617691 // name: []const u8,
......@@ -19291,7 +19296,7 @@ fn finishStructInit(
1929119296 for (0..struct_type.field_types.len) |i| {
1929219297 if (field_inits[i] != .none) continue;
1929319298
19294 const field_init = struct_type.field_inits.get(ip)[i];
19299 const field_init = struct_type.fieldInit(ip, i);
1929519300 if (field_init == .none) {
1929619301 const field_name = struct_type.field_names.get(ip)[i];
1929719302 const template = "missing struct field: {}";
......@@ -20995,9 +21000,10 @@ fn reifyStruct(
2099521000 .fields_len = fields_len,
2099621001 .requires_comptime = .unknown,
2099721002 .is_tuple = is_tuple,
20998 // So that we don't have to scan ahead, we allocate space in the struct for
20999 // alignments, comptime fields, and default inits. This might result in wasted
21000 // space, however, this is a permitted encoding of struct types.
21003 // So that we don't have to scan ahead, we allocate space in the struct
21004 // type for alignments, comptime fields, and default inits. This might
21005 // result in wasted space, however, this is a permitted encoding of
21006 // struct types.
2100121007 .any_comptime_fields = true,
2100221008 .any_default_inits = true,
2100321009 .any_aligned_fields = true,
......@@ -21042,6 +21048,8 @@ fn reifyStruct(
2104221048 if (layout == .Packed) {
2104321049 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
2104421050 if (is_comptime_val.toBool()) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{});
21051 } else {
21052 struct_type.field_aligns.get(ip)[i] = Alignment.fromByteUnits(abi_align);
2104521053 }
2104621054 if (layout == .Extern and is_comptime_val.toBool()) {
2104721055 return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{});
......@@ -21065,8 +21073,7 @@ fn reifyStruct(
2106521073 .{field_index},
2106621074 );
2106721075 }
21068 }
21069 if (struct_type.addFieldName(ip, field_name)) |prev_index| {
21076 } else if (struct_type.addFieldName(ip, field_name)) |prev_index| {
2107021077 _ = prev_index; // TODO: better source location
2107121078 return sema.fail(block, src, "duplicate struct field {}", .{field_name.fmt(ip)});
2107221079 }
......@@ -21084,7 +21091,6 @@ fn reifyStruct(
2108421091 }
2108521092
2108621093 struct_type.field_types.get(ip)[i] = field_ty.toIntern();
21087 struct_type.field_aligns.get(ip)[i] = Alignment.fromByteUnits(abi_align);
2108821094 struct_type.field_inits.get(ip)[i] = default_val;
2108921095 if (is_comptime_val.toBool())
2109021096 struct_type.setFieldComptime(ip, i);
......@@ -23772,7 +23778,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2377223778 } else {
2377323779 ptr_ty_data.flags.alignment = blk: {
2377423780 if (mod.typeToStruct(parent_ty)) |struct_type| {
23775 break :blk struct_type.field_aligns.get(ip)[field_index];
23781 break :blk struct_type.fieldAlign(ip, field_index);
2377623782 } else if (mod.typeToUnion(parent_ty)) |union_obj| {
2377723783 break :blk union_obj.fieldAlign(ip, field_index);
2377823784 } else {
......@@ -26670,7 +26676,7 @@ fn structFieldPtrByIndex(
2667026676 if (parent_align != .none and ptr_ty_data.packed_offset.bit_offset % 8 == 0 and
2667126677 target.cpu.arch.endian() == .Little)
2667226678 {
26673 const elem_size_bytes = ptr_ty_data.child.toType().abiSize(mod);
26679 const elem_size_bytes = try sema.typeAbiSize(ptr_ty_data.child.toType());
2667426680 const elem_size_bits = ptr_ty_data.child.toType().bitSize(mod);
2667526681 if (elem_size_bytes * 8 == elem_size_bits) {
2667626682 const byte_offset = ptr_ty_data.packed_offset.bit_offset / 8;
......@@ -26691,7 +26697,7 @@ fn structFieldPtrByIndex(
2669126697 } else {
2669226698 // Our alignment is capped at the field alignment
2669326699 const field_align = try sema.structFieldAlignment(
26694 struct_type.field_aligns.get(ip)[field_index],
26700 struct_type.fieldAlign(ip, field_index),
2669526701 field_ty.toType(),
2669626702 struct_type.layout,
2669726703 );
......@@ -26700,7 +26706,7 @@ fn structFieldPtrByIndex(
2670026706
2670126707 const ptr_field_ty = try mod.ptrType(ptr_ty_data);
2670226708
26703 if (struct_type.comptime_bits.getBit(ip, field_index)) {
26709 if (struct_type.fieldIsComptime(ip, field_index)) {
2670426710 const val = try mod.intern(.{ .ptr = .{
2670526711 .ty = ptr_field_ty.toIntern(),
2670626712 .addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] },
......@@ -26744,7 +26750,7 @@ fn structFieldVal(
2674426750
2674526751 const field_index = struct_type.nameIndex(ip, field_name) orelse
2674626752 return sema.failWithBadStructFieldAccess(block, struct_type, field_name_src, field_name);
26747 if (struct_type.comptime_bits.getBit(ip, field_index)) {
26753 if (struct_type.fieldIsComptime(ip, field_index)) {
2674826754 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);
2674926755 }
2675026756
......@@ -29199,12 +29205,12 @@ fn coerceInMemoryAllowedPtrs(
2919929205 const src_align = if (src_info.flags.alignment != .none)
2920029206 src_info.flags.alignment
2920129207 else
29202 src_info.child.toType().abiAlignment(mod);
29208 try sema.typeAbiAlignment(src_info.child.toType());
2920329209
2920429210 const dest_align = if (dest_info.flags.alignment != .none)
2920529211 dest_info.flags.alignment
2920629212 else
29207 dest_info.child.toType().abiAlignment(mod);
29213 try sema.typeAbiAlignment(dest_info.child.toType());
2920829214
2920929215 if (dest_align.compare(.gt, src_align)) {
2921029216 return InMemoryCoercionResult{ .ptr_alignment = .{
......@@ -30969,7 +30975,7 @@ fn coerceTupleToStruct(
3096930975 const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, field_i);
3097030976 const coerced = try sema.coerce(block, field_ty, elem_ref, field_src);
3097130977 field_refs[field_index] = coerced;
30972 if (struct_type.comptime_bits.getBit(ip, field_index)) {
30978 if (struct_type.fieldIsComptime(ip, field_index)) {
3097330979 const init_val = (try sema.resolveMaybeUndefVal(coerced)) orelse {
3097430980 return sema.failWithNeededComptime(block, field_src, .{
3097530981 .needed_comptime_reason = "value stored in comptime field must be comptime-known",
......@@ -30998,7 +31004,7 @@ fn coerceTupleToStruct(
3099831004 if (field_ref.* != .none) continue;
3099931005
3100031006 const field_name = struct_type.field_names.get(ip)[i];
31001 const field_default_val = struct_type.field_inits.get(ip)[i];
31007 const field_default_val = struct_type.fieldInit(ip, i);
3100231008 const field_src = inst_src; // TODO better source location
3100331009 if (field_default_val == .none) {
3100431010 const template = "missing struct field: {}";
......@@ -31088,7 +31094,7 @@ fn coerceTupleToTuple(
3108831094 };
3108931095 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
3109031096 .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[field_index_usize],
31091 .struct_type => |struct_type| struct_type.field_inits.get(ip)[field_index_usize],
31097 .struct_type => |struct_type| struct_type.fieldInit(ip, field_index_usize),
3109231098 else => unreachable,
3109331099 };
3109431100
......@@ -31126,7 +31132,7 @@ fn coerceTupleToTuple(
3112631132
3112731133 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
3112831134 .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[i],
31129 .struct_type => |struct_type| struct_type.field_inits.get(ip)[i],
31135 .struct_type => |struct_type| struct_type.fieldInit(ip, i),
3113031136 else => unreachable,
3113131137 };
3113231138
......@@ -33332,12 +33338,12 @@ fn resolvePeerTypesInner(
3333233338 if (ptr_info.flags.alignment != .none)
3333333339 ptr_info.flags.alignment
3333433340 else
33335 ptr_info.child.toType().abiAlignment(mod),
33341 try sema.typeAbiAlignment(ptr_info.child.toType()),
3333633342
3333733343 if (peer_info.flags.alignment != .none)
3333833344 peer_info.flags.alignment
3333933345 else
33340 peer_info.child.toType().abiAlignment(mod),
33346 try sema.typeAbiAlignment(peer_info.child.toType()),
3334133347 );
3334233348
3334333349 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
......@@ -34288,14 +34294,16 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3428834294 return sema.failWithOwnedErrorMsg(null, msg);
3428934295 }
3429034296
34291 if (try sema.typeRequiresComptime(ty))
34292 return;
34293
3429434297 const aligns = try sema.arena.alloc(Alignment, struct_type.field_types.len);
3429534298 const sizes = try sema.arena.alloc(u64, struct_type.field_types.len);
3429634299
3429734300 for (aligns, sizes, 0..) |*field_align, *field_size, i| {
3429834301 const field_ty = struct_type.field_types.get(ip)[i].toType();
34302 if (struct_type.fieldIsComptime(ip, i) or !(try sema.typeHasRuntimeBits(field_ty))) {
34303 field_size.* = 0;
34304 field_align.* = .none;
34305 continue;
34306 }
3429934307 field_size.* = sema.typeAbiSize(field_ty) catch |err| switch (err) {
3430034308 error.AnalysisFail => {
3430134309 const msg = sema.err orelse return err;
......@@ -34322,7 +34330,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3432234330 }
3432334331
3432434332 if (struct_type.hasReorderedFields()) {
34325 for (sizes, struct_type.runtime_order.get(ip), 0..) |size, *ro, i| {
34333 const runtime_order = struct_type.runtime_order.get(ip);
34334
34335 for (sizes, runtime_order, 0..) |size, *ro, i| {
3432634336 ro.* = if (size != 0) @enumFromInt(i) else .omitted;
3432734337 }
3432834338
......@@ -34339,7 +34349,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3433934349 return a_align.compare(.gt, b_align);
3434034350 }
3434134351 };
34342 mem.sortUnstable(RuntimeOrder, struct_type.runtime_order.get(ip), AlignSortContext{
34352 mem.sortUnstable(RuntimeOrder, runtime_order, AlignSortContext{
3434334353 .aligns = aligns,
3434434354 }, AlignSortContext.lessThan);
3434534355 }
......@@ -34348,7 +34358,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3434834358 const offsets = struct_type.offsets.get(ip);
3434934359 var it = struct_type.iterateRuntimeOrder(ip);
3435034360 var offset: u64 = 0;
34351 var big_align: Alignment = .none;
34361 var big_align: Alignment = .@"1";
3435234362 while (it.next()) |i| {
3435334363 big_align = big_align.max(aligns[i]);
3435434364 offsets[i] = @intCast(aligns[i].forward(offset));
......@@ -34358,22 +34368,61 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3435834368 const flags = struct_type.flagsPtr(ip);
3435934369 flags.alignment = big_align;
3436034370 flags.layout_resolved = true;
34371 _ = try sema.typeRequiresComptime(ty);
3436134372}
3436234373
3436334374fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) CompileError!void {
3436434375 const gpa = mod.gpa;
3436534376 const ip = &mod.intern_pool;
3436634377
34367 var fields_bit_sum: u64 = 0;
34368 for (0..struct_type.field_types.len) |i| {
34369 const field_ty = struct_type.field_types.get(ip)[i].toType();
34370 fields_bit_sum += field_ty.bitSize(mod);
34371 }
34372
3437334378 const decl_index = struct_type.decl.unwrap().?;
3437434379 const decl = mod.declPtr(decl_index);
3437534380
3437634381 const zir = mod.namespacePtr(struct_type.namespace.unwrap().?).file_scope.zir;
34382
34383 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
34384 defer analysis_arena.deinit();
34385
34386 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
34387 defer comptime_mutable_decls.deinit();
34388
34389 var sema: Sema = .{
34390 .mod = mod,
34391 .gpa = gpa,
34392 .arena = analysis_arena.allocator(),
34393 .code = zir,
34394 .owner_decl = decl,
34395 .owner_decl_index = decl_index,
34396 .func_index = .none,
34397 .func_is_naked = false,
34398 .fn_ret_ty = Type.void,
34399 .fn_ret_ty_ies = null,
34400 .owner_func_index = .none,
34401 .comptime_mutable_decls = &comptime_mutable_decls,
34402 };
34403 defer sema.deinit();
34404
34405 var block: Block = .{
34406 .parent = null,
34407 .sema = &sema,
34408 .src_decl = decl_index,
34409 .namespace = struct_type.namespace.unwrap() orelse decl.src_namespace,
34410 .wip_capture_scope = try mod.createCaptureScope(decl.src_scope),
34411 .instructions = .{},
34412 .inlining = null,
34413 .is_comptime = true,
34414 };
34415 defer assert(block.instructions.items.len == 0);
34416
34417 const fields_bit_sum = blk: {
34418 var accumulator: u64 = 0;
34419 for (0..struct_type.field_types.len) |i| {
34420 const field_ty = struct_type.field_types.get(ip)[i].toType();
34421 accumulator += try field_ty.bitSizeAdvanced(mod, &sema);
34422 }
34423 break :blk accumulator;
34424 };
34425
3437734426 const extended = zir.instructions.items(.data)[struct_type.zir_index].extended;
3437834427 assert(extended.opcode == .struct_decl);
3437934428 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
......@@ -34387,40 +34436,6 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
3438734436 const backing_int_body_len = zir.extra[extra_index];
3438834437 extra_index += 1;
3438934438
34390 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
34391 defer analysis_arena.deinit();
34392
34393 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
34394 defer comptime_mutable_decls.deinit();
34395
34396 var sema: Sema = .{
34397 .mod = mod,
34398 .gpa = gpa,
34399 .arena = analysis_arena.allocator(),
34400 .code = zir,
34401 .owner_decl = decl,
34402 .owner_decl_index = decl_index,
34403 .func_index = .none,
34404 .func_is_naked = false,
34405 .fn_ret_ty = Type.void,
34406 .fn_ret_ty_ies = null,
34407 .owner_func_index = .none,
34408 .comptime_mutable_decls = &comptime_mutable_decls,
34409 };
34410 defer sema.deinit();
34411
34412 var block: Block = .{
34413 .parent = null,
34414 .sema = &sema,
34415 .src_decl = decl_index,
34416 .namespace = struct_type.namespace.unwrap() orelse decl.src_namespace,
34417 .wip_capture_scope = try mod.createCaptureScope(decl.src_scope),
34418 .instructions = .{},
34419 .inlining = null,
34420 .is_comptime = true,
34421 };
34422 defer assert(block.instructions.items.len == 0);
34423
3442434439 const backing_int_src: LazySrcLoc = .{ .node_offset_container_tag = 0 };
3442534440 const backing_int_ty = blk: {
3442634441 if (backing_int_body_len == 0) {
......@@ -34435,44 +34450,18 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
3443534450
3443634451 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);
3443734452 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
34438 for (comptime_mutable_decls.items) |ct_decl_index| {
34439 const ct_decl = mod.declPtr(ct_decl_index);
34440 _ = try ct_decl.internValue(mod);
34441 }
3444234453 } else {
3444334454 if (fields_bit_sum > std.math.maxInt(u16)) {
34444 var sema: Sema = .{
34445 .mod = mod,
34446 .gpa = gpa,
34447 .arena = undefined,
34448 .code = zir,
34449 .owner_decl = decl,
34450 .owner_decl_index = decl_index,
34451 .func_index = .none,
34452 .func_is_naked = false,
34453 .fn_ret_ty = Type.void,
34454 .fn_ret_ty_ies = null,
34455 .owner_func_index = .none,
34456 .comptime_mutable_decls = undefined,
34457 };
34458 defer sema.deinit();
34459
34460 var block: Block = .{
34461 .parent = null,
34462 .sema = &sema,
34463 .src_decl = decl_index,
34464 .namespace = struct_type.namespace.unwrap() orelse
34465 mod.declPtr(struct_type.decl.unwrap().?).src_namespace,
34466 .wip_capture_scope = undefined,
34467 .instructions = .{},
34468 .inlining = null,
34469 .is_comptime = true,
34470 };
3447134455 return sema.fail(&block, LazySrcLoc.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});
3447234456 }
3447334457 const backing_int_ty = try mod.intType(.unsigned, @intCast(fields_bit_sum));
3447434458 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
3447534459 }
34460
34461 for (comptime_mutable_decls.items) |ct_decl_index| {
34462 const ct_decl = mod.declPtr(ct_decl_index);
34463 _ = try ct_decl.internValue(mod);
34464 }
3447634465}
3447734466
3447834467fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void {
......@@ -34813,10 +34802,9 @@ fn resolveTypeFieldsStruct(
3481334802 else => {},
3481434803 }
3481534804
34816 if (struct_type.haveFieldTypes(ip))
34817 return;
34805 if (struct_type.haveFieldTypes(ip)) return;
3481834806
34819 if (struct_type.flagsPtr(ip).field_types_wip) {
34807 if (struct_type.setTypesWip(ip)) {
3482034808 const msg = try Module.ErrorMsg.create(
3482134809 sema.gpa,
3482234810 mod.declPtr(owner_decl).srcLoc(mod),
......@@ -34825,9 +34813,7 @@ fn resolveTypeFieldsStruct(
3482534813 );
3482634814 return sema.failWithOwnedErrorMsg(null, msg);
3482734815 }
34828
34829 struct_type.flagsPtr(ip).field_types_wip = true;
34830 errdefer struct_type.flagsPtr(ip).field_types_wip = false;
34816 errdefer struct_type.clearTypesWip(ip);
3483134817
3483234818 try semaStructFields(mod, sema.arena, struct_type);
3483334819}
......@@ -36175,7 +36161,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3617536161 struct_type.field_types.len,
3617636162 );
3617736163 for (field_vals, 0..) |*field_val, i| {
36178 if (struct_type.comptime_bits.getBit(ip, i)) {
36164 if (struct_type.fieldIsComptime(ip, i)) {
3617936165 field_val.* = struct_type.field_inits.get(ip)[i];
3618036166 continue;
3618136167 }
......@@ -36679,7 +36665,11 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3667936665 if (struct_type.fieldIsComptime(ip, i)) continue;
3668036666 const field_ty = struct_type.field_types.get(ip)[i];
3668136667 if (try sema.typeRequiresComptime(field_ty.toType())) {
36682 struct_type.setRequiresComptime(ip);
36668 // Note that this does not cause the layout to
36669 // be considered resolved. Comptime-only types
36670 // still maintain a layout of their
36671 // runtime-known fields.
36672 struct_type.flagsPtr(ip).requires_comptime = .yes;
3668336673 return true;
3668436674 }
3668536675 }
src/codegen/c.zig+6-6
......@@ -1310,21 +1310,21 @@ pub const DeclGen = struct {
13101310
13111311 try writer.writeByte('{');
13121312 var empty = true;
1313 const field_types = struct_type.field_types.get(ip);
1314 for (struct_type.runtime_order.get(ip)) |runtime_order| {
1315 const field_i = runtime_order.toInt() orelse break;
1316 const field_ty = field_types[field_i];
1313 for (0..struct_type.field_types.len) |field_i| {
1314 const field_ty = struct_type.field_types.get(ip)[field_i].toType();
1315 if (struct_type.fieldIsComptime(ip, field_i)) continue;
1316 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
13171317
13181318 if (!empty) try writer.writeByte(',');
13191319 const field_val = switch (ip.indexToKey(val.ip_index).aggregate.storage) {
13201320 .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
1321 .ty = field_ty,
1321 .ty = field_ty.toIntern(),
13221322 .storage = .{ .u64 = bytes[field_i] },
13231323 } }),
13241324 .elems => |elems| elems[field_i],
13251325 .repeated_elem => |elem| elem,
13261326 };
1327 try dg.renderValue(writer, field_ty.toType(), field_val.toValue(), initializer_type);
1327 try dg.renderValue(writer, field_ty, field_val.toValue(), initializer_type);
13281328
13291329 empty = false;
13301330 }
src/codegen/llvm.zig+10-10
......@@ -2493,7 +2493,6 @@ pub const Object = struct {
24932493
24942494 const struct_type = mod.typeToStruct(ty).?;
24952495 const field_types = struct_type.field_types.get(ip);
2496 const field_names = struct_type.field_names.get(ip);
24972496
24982497 var di_fields: std.ArrayListUnmanaged(*llvm.DIType) = .{};
24992498 defer di_fields.deinit(gpa);
......@@ -2514,18 +2513,21 @@ pub const Object = struct {
25142513 const field_offset = field_align.forward(offset);
25152514 offset = field_offset + field_size;
25162515
2517 const field_name = ip.stringToSlice(field_names[field_index]);
2516 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
2517 try ip.getOrPutStringFmt(gpa, "{d}", .{field_index});
2518
2519 const field_di_ty = try o.lowerDebugType(field_ty, .full);
25182520
25192521 try di_fields.append(gpa, dib.createMemberType(
25202522 fwd_decl.toScope(),
2521 field_name,
2523 ip.stringToSlice(field_name),
25222524 null, // file
25232525 0, // line
25242526 field_size * 8, // size in bits
25252527 field_align.toByteUnits(0) * 8, // align in bits
25262528 field_offset * 8, // offset in bits
25272529 0, // flags
2528 try o.lowerDebugType(field_ty, .full),
2530 field_di_ty,
25292531 ));
25302532 }
25312533
......@@ -3301,13 +3303,11 @@ pub const Object = struct {
33013303 var offset: u64 = 0;
33023304 var big_align: InternPool.Alignment = .@"1";
33033305 var struct_kind: Builder.Type.Structure.Kind = .normal;
3304
3305 for (struct_type.runtime_order.get(ip)) |runtime_index| {
3306 const field_index = runtime_index.toInt() orelse break;
3306 var it = struct_type.iterateRuntimeOrder(ip);
3307 while (it.next()) |field_index| {
33073308 const field_ty = struct_type.field_types.get(ip)[field_index].toType();
3308 const field_aligns = struct_type.field_aligns.get(ip);
33093309 const field_align = mod.structFieldAlignment(
3310 if (field_aligns.len == 0) .none else field_aligns[field_index],
3310 struct_type.fieldAlign(ip, field_index),
33113311 field_ty,
33123312 struct_type.layout,
33133313 );
......@@ -4012,7 +4012,7 @@ pub const Object = struct {
40124012 comptime assert(struct_layout_version == 2);
40134013 var llvm_index: usize = 0;
40144014 var offset: u64 = 0;
4015 var big_align: InternPool.Alignment = .none;
4015 var big_align: InternPool.Alignment = .@"1";
40164016 var need_unnamed = false;
40174017 var field_it = struct_type.iterateRuntimeOrder(ip);
40184018 while (field_it.next()) |field_index| {
src/type.zig+14-22
......@@ -843,7 +843,7 @@ pub const Type = struct {
843843 pub fn lazyAbiAlignment(ty: Type, mod: *Module) !Value {
844844 switch (try ty.abiAlignmentAdvanced(mod, .lazy)) {
845845 .val => |val| return val,
846 .scalar => |x| return mod.intValue(Type.comptime_int, x.toByteUnitsOptional().?),
846 .scalar => |x| return mod.intValue(Type.comptime_int, x.toByteUnits(0)),
847847 }
848848 }
849849
......@@ -997,8 +997,7 @@ pub const Type = struct {
997997 }
998998
999999 const flags = struct_type.flagsPtr(ip).*;
1000 if (flags.layout_resolved)
1001 return .{ .scalar = flags.alignment };
1000 if (flags.layout_resolved) return .{ .scalar = flags.alignment };
10021001
10031002 switch (strat) {
10041003 .eager => unreachable, // struct layout not resolved
......@@ -1423,20 +1422,12 @@ pub const Type = struct {
14231422 },
14241423 .eager => {},
14251424 }
1426 switch (struct_type.layout) {
1427 .Packed => {
1428 return .{
1429 .scalar = struct_type.backingIntType(ip).toType().abiSize(mod),
1430 };
1431 },
1432 .Auto, .Extern => {
1433 const field_count = ty.structFieldCount(mod);
1434 if (field_count == 0) {
1435 return .{ .scalar = 0 };
1436 }
1437 return .{ .scalar = ty.structFieldOffset(field_count, mod) };
1425 return switch (struct_type.layout) {
1426 .Packed => .{
1427 .scalar = struct_type.backingIntType(ip).toType().abiSize(mod),
14381428 },
1439 }
1429 .Auto, .Extern => .{ .scalar = struct_type.size(ip).* },
1430 };
14401431 },
14411432 .anon_struct_type => |tuple| {
14421433 switch (strat) {
......@@ -1655,19 +1646,19 @@ pub const Type = struct {
16551646 },
16561647 .struct_type => |struct_type| {
16571648 if (struct_type.layout == .Packed) {
1658 if (opt_sema) |sema| _ = try sema.resolveTypeLayout(ty);
1649 if (opt_sema) |sema| try sema.resolveTypeLayout(ty);
16591650 return try struct_type.backingIntType(ip).*.toType().bitSizeAdvanced(mod, opt_sema);
16601651 }
16611652 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
16621653 },
16631654
16641655 .anon_struct_type => {
1665 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
1656 if (opt_sema) |sema| try sema.resolveTypeFields(ty);
16661657 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
16671658 },
16681659
16691660 .union_type => |union_type| {
1670 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
1661 if (opt_sema) |sema| try sema.resolveTypeFields(ty);
16711662 if (ty.containerLayout(mod) != .Packed) {
16721663 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
16731664 }
......@@ -2091,6 +2082,7 @@ pub const Type = struct {
20912082 return switch (ip.indexToKey(ty.toIntern())) {
20922083 .vector_type => |vector_type| vector_type.len,
20932084 .array_type => |array_type| array_type.len,
2085 .struct_type => |struct_type| struct_type.field_types.len,
20942086 .anon_struct_type => |tuple| tuple.types.len,
20952087
20962088 else => unreachable,
......@@ -2964,7 +2956,7 @@ pub const Type = struct {
29642956 switch (ip.indexToKey(ty.toIntern())) {
29652957 .struct_type => |struct_type| {
29662958 assert(struct_type.layout != .Packed);
2967 const explicit_align = struct_type.field_aligns.get(ip)[index];
2959 const explicit_align = struct_type.fieldAlign(ip, index);
29682960 const field_ty = struct_type.field_types.get(ip)[index].toType();
29692961 return mod.structFieldAlignment(explicit_align, field_ty, struct_type.layout);
29702962 },
......@@ -2983,7 +2975,7 @@ pub const Type = struct {
29832975 const ip = &mod.intern_pool;
29842976 switch (ip.indexToKey(ty.toIntern())) {
29852977 .struct_type => |struct_type| {
2986 const val = struct_type.field_inits.get(ip)[index];
2978 const val = struct_type.fieldInit(ip, index);
29872979 // TODO: avoid using `unreachable` to indicate this.
29882980 if (val == .none) return Value.@"unreachable";
29892981 return val.toValue();
......@@ -3002,7 +2994,7 @@ pub const Type = struct {
30022994 const ip = &mod.intern_pool;
30032995 switch (ip.indexToKey(ty.toIntern())) {
30042996 .struct_type => |struct_type| {
3005 if (struct_type.comptime_bits.getBit(ip, index)) {
2997 if (struct_type.fieldIsComptime(ip, index)) {
30062998 return struct_type.field_inits.get(ip)[index].toValue();
30072999 } else {
30083000 return struct_type.field_types.get(ip)[index].toType().onePossibleValue(mod);