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) {...@@ -382,6 +382,7 @@ pub const Key = union(enum) {
382382
383 pub const ComptimeBits = struct {383 pub const ComptimeBits = struct {
384 start: u32,384 start: u32,
385 /// This is the number of u32 elements, not the number of struct fields.
385 len: u32,386 len: u32,
386387
387 pub fn get(this: @This(), ip: *const InternPool) []u32 {388 pub fn get(this: @This(), ip: *const InternPool) []u32 {
...@@ -505,12 +506,23 @@ pub const Key = union(enum) {...@@ -505,12 +506,23 @@ pub const Key = union(enum) {
505 return false;506 return false;
506 }507 }
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
508 pub fn setLayoutWip(s: @This(), ip: *InternPool) bool {522 pub fn setLayoutWip(s: @This(), ip: *InternPool) bool {
509 if (s.layout == .Packed) return false;523 if (s.layout == .Packed) return false;
510 const flags_ptr = s.flagsPtr(ip);524 const flags_ptr = s.flagsPtr(ip);
511 if (flags_ptr.field_types_wip or flags_ptr.layout_wip) {525 if (flags_ptr.layout_wip) return true;
512 return true;
513 }
514 flags_ptr.layout_wip = true;526 flags_ptr.layout_wip = true;
515 return false;527 return false;
516 }528 }
...@@ -527,14 +539,6 @@ pub const Key = union(enum) {...@@ -527,14 +539,6 @@ pub const Key = union(enum) {
527 s.flagsPtr(ip).fully_resolved = false;539 s.flagsPtr(ip).fully_resolved = false;
528 }540 }
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
538 /// The returned pointer expires with any addition to the `InternPool`.542 /// The returned pointer expires with any addition to the `InternPool`.
539 /// Asserts the struct is not packed.543 /// Asserts the struct is not packed.
540 pub fn size(self: @This(), ip: *InternPool) *u32 {544 pub fn size(self: @This(), ip: *InternPool) *u32 {
...@@ -567,7 +571,7 @@ pub const Key = union(enum) {...@@ -567,7 +571,7 @@ pub const Key = union(enum) {
567571
568 pub fn haveLayout(s: @This(), ip: *InternPool) bool {572 pub fn haveLayout(s: @This(), ip: *InternPool) bool {
569 return switch (s.layout) {573 return switch (s.layout) {
570 .Packed => s.haveFieldTypes(ip),574 .Packed => s.backingIntType(ip).* != .none,
571 .Auto, .Extern => s.flagsPtr(ip).layout_resolved,575 .Auto, .Extern => s.flagsPtr(ip).layout_resolved,
572 };576 };
573 }577 }
...@@ -3149,7 +3153,15 @@ pub const Alignment = enum(u6) {...@@ -3149,7 +3153,15 @@ pub const Alignment = enum(u6) {
3149 return std.math.order(@intFromEnum(lhs), @intFromEnum(rhs));3153 return std.math.order(@intFromEnum(lhs), @intFromEnum(rhs));
3150 }3154 }
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.
3152 pub fn compare(lhs: Alignment, op: std.math.CompareOperator, rhs: Alignment) bool {3160 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 {
3153 assert(lhs != .none);3165 assert(lhs != .none);
3154 assert(rhs != .none);3166 assert(rhs != .none);
3155 return std.math.compare(@intFromEnum(lhs), op, @intFromEnum(rhs));3167 return std.math.compare(@intFromEnum(lhs), op, @intFromEnum(rhs));
...@@ -3194,6 +3206,7 @@ pub const Alignment = enum(u6) {...@@ -3194,6 +3206,7 @@ pub const Alignment = enum(u6) {
3194 /// not invalidated when items are added to the `InternPool`.3206 /// not invalidated when items are added to the `InternPool`.
3195 pub const Slice = struct {3207 pub const Slice = struct {
3196 start: u32,3208 start: u32,
3209 /// This is the number of alignment values, not the number of u32 elements.
3197 len: u32,3210 len: u32,
31983211
3199 pub fn get(slice: Slice, ip: *const InternPool) []Alignment {3212 pub fn get(slice: Slice, ip: *const InternPool) []Alignment {
...@@ -3204,6 +3217,13 @@ pub const Alignment = enum(u6) {...@@ -3204,6 +3217,13 @@ pub const Alignment = enum(u6) {
3204 }3217 }
3205 };3218 };
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
3207 const LlvmBuilderAlignment = @import("codegen/llvm/Builder.zig").Alignment;3227 const LlvmBuilderAlignment = @import("codegen/llvm/Builder.zig").Alignment;
32083228
3209 pub fn toLlvm(this: @This()) LlvmBuilderAlignment {3229 pub fn toLlvm(this: @This()) LlvmBuilderAlignment {
...@@ -4067,16 +4087,14 @@ fn extraStructType(ip: *const InternPool, extra_index: u32) Key.StructType {...@@ -4067,16 +4087,14 @@ fn extraStructType(ip: *const InternPool, extra_index: u32) Key.StructType {
4067 };4087 };
4068 const field_aligns: Alignment.Slice = t: {4088 const field_aligns: Alignment.Slice = t: {
4069 if (!s.data.flags.any_aligned_fields) break :t .{ .start = 0, .len = 0 };4089 if (!s.data.flags.any_aligned_fields) break :t .{ .start = 0, .len = 0 };
4070 const len = (fields_len + 3) / 4;4090 const aligns: Alignment.Slice = .{ .start = index, .len = fields_len };
4071 const aligns: Alignment.Slice = .{ .start = index, .len = len };4091 index += (fields_len + 3) / 4;
4072 index += len;
4073 break :t aligns;4092 break :t aligns;
4074 };4093 };
4075 const comptime_bits: Key.StructType.ComptimeBits = t: {4094 const comptime_bits: Key.StructType.ComptimeBits = t: {
4076 if (!s.data.flags.any_comptime_fields) break :t .{ .start = 0, .len = 0 };4095 if (!s.data.flags.any_comptime_fields) break :t .{ .start = 0, .len = 0 };
4077 const len = (fields_len + 31) / 32;4096 const comptime_bits: Key.StructType.ComptimeBits = .{ .start = index, .len = fields_len };
4078 const comptime_bits: Key.StructType.ComptimeBits = .{ .start = index, .len = len };4097 index += (fields_len + 31) / 32;
4079 index += len;
4080 break :t comptime_bits;4098 break :t comptime_bits;
4081 };4099 };
4082 const runtime_order: Key.StructType.RuntimeOrder.Slice = t: {4100 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...@@ -17646,12 +17646,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17646 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);17646 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);
1764717647
17648 for (struct_field_vals, 0..) |*field_val, i| {17648 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});
17650 const field_ty = struct_type.field_types.get(ip)[i].toType();17654 const field_ty = struct_type.field_types.get(ip)[i].toType();
17651 const field_init = struct_type.fieldInit(ip, i);17655 const field_init = struct_type.fieldInit(ip, i);
17652 const field_is_comptime = struct_type.fieldIsComptime(ip, i);17656 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));
17655 const name_val = v: {17657 const name_val = v: {
17656 var anon_decl = try block.startAnonDecl();17658 var anon_decl = try block.startAnonDecl();
17657 defer anon_decl.deinit();17659 defer anon_decl.deinit();
...@@ -17676,11 +17678,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17676,11 +17678,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1767617678
17677 const opt_default_val = if (field_init == .none) null else field_init.toValue();17679 const opt_default_val = if (field_init == .none) null else field_init.toValue();
17678 const default_val_ptr = try sema.optRefValue(block, field_ty, opt_default_val);17680 const default_val_ptr = try sema.optRefValue(block, field_ty, opt_default_val);
17679 const alignment = mod.structFieldAlignment(17681 const alignment = switch (struct_type.layout) {
17680 struct_type.field_aligns.get(ip)[i],17682 .Packed => .none,
17681 field_ty,17683 else => try sema.structFieldAlignment(
17682 struct_type.layout,17684 struct_type.fieldAlign(ip, i),
17683 );17685 field_ty,
17686 struct_type.layout,
17687 ),
17688 };
1768417689
17685 const struct_field_fields = .{17690 const struct_field_fields = .{
17686 // name: []const u8,17691 // name: []const u8,
...@@ -19291,7 +19296,7 @@ fn finishStructInit(...@@ -19291,7 +19296,7 @@ fn finishStructInit(
19291 for (0..struct_type.field_types.len) |i| {19296 for (0..struct_type.field_types.len) |i| {
19292 if (field_inits[i] != .none) continue;19297 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);
19295 if (field_init == .none) {19300 if (field_init == .none) {
19296 const field_name = struct_type.field_names.get(ip)[i];19301 const field_name = struct_type.field_names.get(ip)[i];
19297 const template = "missing struct field: {}";19302 const template = "missing struct field: {}";
...@@ -20995,9 +21000,10 @@ fn reifyStruct(...@@ -20995,9 +21000,10 @@ fn reifyStruct(
20995 .fields_len = fields_len,21000 .fields_len = fields_len,
20996 .requires_comptime = .unknown,21001 .requires_comptime = .unknown,
20997 .is_tuple = is_tuple,21002 .is_tuple = is_tuple,
20998 // So that we don't have to scan ahead, we allocate space in the struct for21003 // So that we don't have to scan ahead, we allocate space in the struct
20999 // alignments, comptime fields, and default inits. This might result in wasted21004 // type for alignments, comptime fields, and default inits. This might
21000 // space, however, this is a permitted encoding of struct types.21005 // result in wasted space, however, this is a permitted encoding of
21006 // struct types.
21001 .any_comptime_fields = true,21007 .any_comptime_fields = true,
21002 .any_default_inits = true,21008 .any_default_inits = true,
21003 .any_aligned_fields = true,21009 .any_aligned_fields = true,
...@@ -21042,6 +21048,8 @@ fn reifyStruct(...@@ -21042,6 +21048,8 @@ fn reifyStruct(
21042 if (layout == .Packed) {21048 if (layout == .Packed) {
21043 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});21049 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
21044 if (is_comptime_val.toBool()) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{});21050 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);
21045 }21053 }
21046 if (layout == .Extern and is_comptime_val.toBool()) {21054 if (layout == .Extern and is_comptime_val.toBool()) {
21047 return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{});21055 return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{});
...@@ -21065,8 +21073,7 @@ fn reifyStruct(...@@ -21065,8 +21073,7 @@ fn reifyStruct(
21065 .{field_index},21073 .{field_index},
21066 );21074 );
21067 }21075 }
21068 }21076 } else if (struct_type.addFieldName(ip, field_name)) |prev_index| {
21069 if (struct_type.addFieldName(ip, field_name)) |prev_index| {
21070 _ = prev_index; // TODO: better source location21077 _ = prev_index; // TODO: better source location
21071 return sema.fail(block, src, "duplicate struct field {}", .{field_name.fmt(ip)});21078 return sema.fail(block, src, "duplicate struct field {}", .{field_name.fmt(ip)});
21072 }21079 }
...@@ -21084,7 +21091,6 @@ fn reifyStruct(...@@ -21084,7 +21091,6 @@ fn reifyStruct(
21084 }21091 }
2108521092
21086 struct_type.field_types.get(ip)[i] = field_ty.toIntern();21093 struct_type.field_types.get(ip)[i] = field_ty.toIntern();
21087 struct_type.field_aligns.get(ip)[i] = Alignment.fromByteUnits(abi_align);
21088 struct_type.field_inits.get(ip)[i] = default_val;21094 struct_type.field_inits.get(ip)[i] = default_val;
21089 if (is_comptime_val.toBool())21095 if (is_comptime_val.toBool())
21090 struct_type.setFieldComptime(ip, i);21096 struct_type.setFieldComptime(ip, i);
...@@ -23772,7 +23778,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -23772,7 +23778,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
23772 } else {23778 } else {
23773 ptr_ty_data.flags.alignment = blk: {23779 ptr_ty_data.flags.alignment = blk: {
23774 if (mod.typeToStruct(parent_ty)) |struct_type| {23780 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);
23776 } else if (mod.typeToUnion(parent_ty)) |union_obj| {23782 } else if (mod.typeToUnion(parent_ty)) |union_obj| {
23777 break :blk union_obj.fieldAlign(ip, field_index);23783 break :blk union_obj.fieldAlign(ip, field_index);
23778 } else {23784 } else {
...@@ -26670,7 +26676,7 @@ fn structFieldPtrByIndex(...@@ -26670,7 +26676,7 @@ fn structFieldPtrByIndex(
26670 if (parent_align != .none and ptr_ty_data.packed_offset.bit_offset % 8 == 0 and26676 if (parent_align != .none and ptr_ty_data.packed_offset.bit_offset % 8 == 0 and
26671 target.cpu.arch.endian() == .Little)26677 target.cpu.arch.endian() == .Little)
26672 {26678 {
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());
26674 const elem_size_bits = ptr_ty_data.child.toType().bitSize(mod);26680 const elem_size_bits = ptr_ty_data.child.toType().bitSize(mod);
26675 if (elem_size_bytes * 8 == elem_size_bits) {26681 if (elem_size_bytes * 8 == elem_size_bits) {
26676 const byte_offset = ptr_ty_data.packed_offset.bit_offset / 8;26682 const byte_offset = ptr_ty_data.packed_offset.bit_offset / 8;
...@@ -26691,7 +26697,7 @@ fn structFieldPtrByIndex(...@@ -26691,7 +26697,7 @@ fn structFieldPtrByIndex(
26691 } else {26697 } else {
26692 // Our alignment is capped at the field alignment26698 // Our alignment is capped at the field alignment
26693 const field_align = try sema.structFieldAlignment(26699 const field_align = try sema.structFieldAlignment(
26694 struct_type.field_aligns.get(ip)[field_index],26700 struct_type.fieldAlign(ip, field_index),
26695 field_ty.toType(),26701 field_ty.toType(),
26696 struct_type.layout,26702 struct_type.layout,
26697 );26703 );
...@@ -26700,7 +26706,7 @@ fn structFieldPtrByIndex(...@@ -26700,7 +26706,7 @@ fn structFieldPtrByIndex(
2670026706
26701 const ptr_field_ty = try mod.ptrType(ptr_ty_data);26707 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)) {
26704 const val = try mod.intern(.{ .ptr = .{26710 const val = try mod.intern(.{ .ptr = .{
26705 .ty = ptr_field_ty.toIntern(),26711 .ty = ptr_field_ty.toIntern(),
26706 .addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] },26712 .addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] },
...@@ -26744,7 +26750,7 @@ fn structFieldVal(...@@ -26744,7 +26750,7 @@ fn structFieldVal(
2674426750
26745 const field_index = struct_type.nameIndex(ip, field_name) orelse26751 const field_index = struct_type.nameIndex(ip, field_name) orelse
26746 return sema.failWithBadStructFieldAccess(block, struct_type, field_name_src, field_name);26752 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)) {
26748 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);26754 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);
26749 }26755 }
2675026756
...@@ -29199,12 +29205,12 @@ fn coerceInMemoryAllowedPtrs(...@@ -29199,12 +29205,12 @@ fn coerceInMemoryAllowedPtrs(
29199 const src_align = if (src_info.flags.alignment != .none)29205 const src_align = if (src_info.flags.alignment != .none)
29200 src_info.flags.alignment29206 src_info.flags.alignment
29201 else29207 else
29202 src_info.child.toType().abiAlignment(mod);29208 try sema.typeAbiAlignment(src_info.child.toType());
2920329209
29204 const dest_align = if (dest_info.flags.alignment != .none)29210 const dest_align = if (dest_info.flags.alignment != .none)
29205 dest_info.flags.alignment29211 dest_info.flags.alignment
29206 else29212 else
29207 dest_info.child.toType().abiAlignment(mod);29213 try sema.typeAbiAlignment(dest_info.child.toType());
2920829214
29209 if (dest_align.compare(.gt, src_align)) {29215 if (dest_align.compare(.gt, src_align)) {
29210 return InMemoryCoercionResult{ .ptr_alignment = .{29216 return InMemoryCoercionResult{ .ptr_alignment = .{
...@@ -30969,7 +30975,7 @@ fn coerceTupleToStruct(...@@ -30969,7 +30975,7 @@ fn coerceTupleToStruct(
30969 const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, field_i);30975 const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, field_i);
30970 const coerced = try sema.coerce(block, field_ty, elem_ref, field_src);30976 const coerced = try sema.coerce(block, field_ty, elem_ref, field_src);
30971 field_refs[field_index] = coerced;30977 field_refs[field_index] = coerced;
30972 if (struct_type.comptime_bits.getBit(ip, field_index)) {30978 if (struct_type.fieldIsComptime(ip, field_index)) {
30973 const init_val = (try sema.resolveMaybeUndefVal(coerced)) orelse {30979 const init_val = (try sema.resolveMaybeUndefVal(coerced)) orelse {
30974 return sema.failWithNeededComptime(block, field_src, .{30980 return sema.failWithNeededComptime(block, field_src, .{
30975 .needed_comptime_reason = "value stored in comptime field must be comptime-known",30981 .needed_comptime_reason = "value stored in comptime field must be comptime-known",
...@@ -30998,7 +31004,7 @@ fn coerceTupleToStruct(...@@ -30998,7 +31004,7 @@ fn coerceTupleToStruct(
30998 if (field_ref.* != .none) continue;31004 if (field_ref.* != .none) continue;
3099931005
31000 const field_name = struct_type.field_names.get(ip)[i];31006 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);
31002 const field_src = inst_src; // TODO better source location31008 const field_src = inst_src; // TODO better source location
31003 if (field_default_val == .none) {31009 if (field_default_val == .none) {
31004 const template = "missing struct field: {}";31010 const template = "missing struct field: {}";
...@@ -31088,7 +31094,7 @@ fn coerceTupleToTuple(...@@ -31088,7 +31094,7 @@ fn coerceTupleToTuple(
31088 };31094 };
31089 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {31095 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
31090 .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[field_index_usize],31096 .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),
31092 else => unreachable,31098 else => unreachable,
31093 };31099 };
3109431100
...@@ -31126,7 +31132,7 @@ fn coerceTupleToTuple(...@@ -31126,7 +31132,7 @@ fn coerceTupleToTuple(
3112631132
31127 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {31133 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
31128 .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[i],31134 .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),
31130 else => unreachable,31136 else => unreachable,
31131 };31137 };
3113231138
...@@ -33332,12 +33338,12 @@ fn resolvePeerTypesInner(...@@ -33332,12 +33338,12 @@ fn resolvePeerTypesInner(
33332 if (ptr_info.flags.alignment != .none)33338 if (ptr_info.flags.alignment != .none)
33333 ptr_info.flags.alignment33339 ptr_info.flags.alignment
33334 else33340 else
33335 ptr_info.child.toType().abiAlignment(mod),33341 try sema.typeAbiAlignment(ptr_info.child.toType()),
3333633342
33337 if (peer_info.flags.alignment != .none)33343 if (peer_info.flags.alignment != .none)
33338 peer_info.flags.alignment33344 peer_info.flags.alignment
33339 else33345 else
33340 peer_info.child.toType().abiAlignment(mod),33346 try sema.typeAbiAlignment(peer_info.child.toType()),
33341 );33347 );
3334233348
33343 if (ptr_info.flags.address_space != peer_info.flags.address_space) {33349 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
...@@ -34288,14 +34294,16 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -34288,14 +34294,16 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
34288 return sema.failWithOwnedErrorMsg(null, msg);34294 return sema.failWithOwnedErrorMsg(null, msg);
34289 }34295 }
3429034296
34291 if (try sema.typeRequiresComptime(ty))
34292 return;
34293
34294 const aligns = try sema.arena.alloc(Alignment, struct_type.field_types.len);34297 const aligns = try sema.arena.alloc(Alignment, struct_type.field_types.len);
34295 const sizes = try sema.arena.alloc(u64, struct_type.field_types.len);34298 const sizes = try sema.arena.alloc(u64, struct_type.field_types.len);
3429634299
34297 for (aligns, sizes, 0..) |*field_align, *field_size, i| {34300 for (aligns, sizes, 0..) |*field_align, *field_size, i| {
34298 const field_ty = struct_type.field_types.get(ip)[i].toType();34301 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 }
34299 field_size.* = sema.typeAbiSize(field_ty) catch |err| switch (err) {34307 field_size.* = sema.typeAbiSize(field_ty) catch |err| switch (err) {
34300 error.AnalysisFail => {34308 error.AnalysisFail => {
34301 const msg = sema.err orelse return err;34309 const msg = sema.err orelse return err;
...@@ -34322,7 +34330,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -34322,7 +34330,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
34322 }34330 }
3432334331
34324 if (struct_type.hasReorderedFields()) {34332 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| {
34326 ro.* = if (size != 0) @enumFromInt(i) else .omitted;34336 ro.* = if (size != 0) @enumFromInt(i) else .omitted;
34327 }34337 }
3432834338
...@@ -34339,7 +34349,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -34339,7 +34349,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
34339 return a_align.compare(.gt, b_align);34349 return a_align.compare(.gt, b_align);
34340 }34350 }
34341 };34351 };
34342 mem.sortUnstable(RuntimeOrder, struct_type.runtime_order.get(ip), AlignSortContext{34352 mem.sortUnstable(RuntimeOrder, runtime_order, AlignSortContext{
34343 .aligns = aligns,34353 .aligns = aligns,
34344 }, AlignSortContext.lessThan);34354 }, AlignSortContext.lessThan);
34345 }34355 }
...@@ -34348,7 +34358,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -34348,7 +34358,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
34348 const offsets = struct_type.offsets.get(ip);34358 const offsets = struct_type.offsets.get(ip);
34349 var it = struct_type.iterateRuntimeOrder(ip);34359 var it = struct_type.iterateRuntimeOrder(ip);
34350 var offset: u64 = 0;34360 var offset: u64 = 0;
34351 var big_align: Alignment = .none;34361 var big_align: Alignment = .@"1";
34352 while (it.next()) |i| {34362 while (it.next()) |i| {
34353 big_align = big_align.max(aligns[i]);34363 big_align = big_align.max(aligns[i]);
34354 offsets[i] = @intCast(aligns[i].forward(offset));34364 offsets[i] = @intCast(aligns[i].forward(offset));
...@@ -34358,22 +34368,61 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -34358,22 +34368,61 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
34358 const flags = struct_type.flagsPtr(ip);34368 const flags = struct_type.flagsPtr(ip);
34359 flags.alignment = big_align;34369 flags.alignment = big_align;
34360 flags.layout_resolved = true;34370 flags.layout_resolved = true;
34371 _ = try sema.typeRequiresComptime(ty);
34361}34372}
3436234373
34363fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) CompileError!void {34374fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) CompileError!void {
34364 const gpa = mod.gpa;34375 const gpa = mod.gpa;
34365 const ip = &mod.intern_pool;34376 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
34373 const decl_index = struct_type.decl.unwrap().?;34378 const decl_index = struct_type.decl.unwrap().?;
34374 const decl = mod.declPtr(decl_index);34379 const decl = mod.declPtr(decl_index);
3437534380
34376 const zir = mod.namespacePtr(struct_type.namespace.unwrap().?).file_scope.zir;34381 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
34377 const extended = zir.instructions.items(.data)[struct_type.zir_index].extended;34426 const extended = zir.instructions.items(.data)[struct_type.zir_index].extended;
34378 assert(extended.opcode == .struct_decl);34427 assert(extended.opcode == .struct_decl);
34379 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);34428 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
...@@ -34387,40 +34436,6 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp...@@ -34387,40 +34436,6 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
34387 const backing_int_body_len = zir.extra[extra_index];34436 const backing_int_body_len = zir.extra[extra_index];
34388 extra_index += 1;34437 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
34424 const backing_int_src: LazySrcLoc = .{ .node_offset_container_tag = 0 };34439 const backing_int_src: LazySrcLoc = .{ .node_offset_container_tag = 0 };
34425 const backing_int_ty = blk: {34440 const backing_int_ty = blk: {
34426 if (backing_int_body_len == 0) {34441 if (backing_int_body_len == 0) {
...@@ -34435,44 +34450,18 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp...@@ -34435,44 +34450,18 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
3443534450
34436 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);34451 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);
34437 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();34452 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 }
34442 } else {34453 } else {
34443 if (fields_bit_sum > std.math.maxInt(u16)) {34454 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 };
34471 return sema.fail(&block, LazySrcLoc.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});34455 return sema.fail(&block, LazySrcLoc.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});
34472 }34456 }
34473 const backing_int_ty = try mod.intType(.unsigned, @intCast(fields_bit_sum));34457 const backing_int_ty = try mod.intType(.unsigned, @intCast(fields_bit_sum));
34474 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();34458 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
34475 }34459 }
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 }
34476}34465}
3447734466
34478fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void {34467fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void {
...@@ -34813,10 +34802,9 @@ fn resolveTypeFieldsStruct(...@@ -34813,10 +34802,9 @@ fn resolveTypeFieldsStruct(
34813 else => {},34802 else => {},
34814 }34803 }
3481534804
34816 if (struct_type.haveFieldTypes(ip))34805 if (struct_type.haveFieldTypes(ip)) return;
34817 return;
3481834806
34819 if (struct_type.flagsPtr(ip).field_types_wip) {34807 if (struct_type.setTypesWip(ip)) {
34820 const msg = try Module.ErrorMsg.create(34808 const msg = try Module.ErrorMsg.create(
34821 sema.gpa,34809 sema.gpa,
34822 mod.declPtr(owner_decl).srcLoc(mod),34810 mod.declPtr(owner_decl).srcLoc(mod),
...@@ -34825,9 +34813,7 @@ fn resolveTypeFieldsStruct(...@@ -34825,9 +34813,7 @@ fn resolveTypeFieldsStruct(
34825 );34813 );
34826 return sema.failWithOwnedErrorMsg(null, msg);34814 return sema.failWithOwnedErrorMsg(null, msg);
34827 }34815 }
3482834816 errdefer struct_type.clearTypesWip(ip);
34829 struct_type.flagsPtr(ip).field_types_wip = true;
34830 errdefer struct_type.flagsPtr(ip).field_types_wip = false;
3483134817
34832 try semaStructFields(mod, sema.arena, struct_type);34818 try semaStructFields(mod, sema.arena, struct_type);
34833}34819}
...@@ -36175,7 +36161,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36175,7 +36161,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36175 struct_type.field_types.len,36161 struct_type.field_types.len,
36176 );36162 );
36177 for (field_vals, 0..) |*field_val, i| {36163 for (field_vals, 0..) |*field_val, i| {
36178 if (struct_type.comptime_bits.getBit(ip, i)) {36164 if (struct_type.fieldIsComptime(ip, i)) {
36179 field_val.* = struct_type.field_inits.get(ip)[i];36165 field_val.* = struct_type.field_inits.get(ip)[i];
36180 continue;36166 continue;
36181 }36167 }
...@@ -36679,7 +36665,11 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -36679,7 +36665,11 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
36679 if (struct_type.fieldIsComptime(ip, i)) continue;36665 if (struct_type.fieldIsComptime(ip, i)) continue;
36680 const field_ty = struct_type.field_types.get(ip)[i];36666 const field_ty = struct_type.field_types.get(ip)[i];
36681 if (try sema.typeRequiresComptime(field_ty.toType())) {36667 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;
36683 return true;36673 return true;
36684 }36674 }
36685 }36675 }
src/codegen/c.zig+6-6
...@@ -1310,21 +1310,21 @@ pub const DeclGen = struct {...@@ -1310,21 +1310,21 @@ pub const DeclGen = struct {
13101310
1311 try writer.writeByte('{');1311 try writer.writeByte('{');
1312 var empty = true;1312 var empty = true;
1313 const field_types = struct_type.field_types.get(ip);1313 for (0..struct_type.field_types.len) |field_i| {
1314 for (struct_type.runtime_order.get(ip)) |runtime_order| {1314 const field_ty = struct_type.field_types.get(ip)[field_i].toType();
1315 const field_i = runtime_order.toInt() orelse break;1315 if (struct_type.fieldIsComptime(ip, field_i)) continue;
1316 const field_ty = field_types[field_i];1316 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
13171317
1318 if (!empty) try writer.writeByte(',');1318 if (!empty) try writer.writeByte(',');
1319 const field_val = switch (ip.indexToKey(val.ip_index).aggregate.storage) {1319 const field_val = switch (ip.indexToKey(val.ip_index).aggregate.storage) {
1320 .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{1320 .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
1321 .ty = field_ty,1321 .ty = field_ty.toIntern(),
1322 .storage = .{ .u64 = bytes[field_i] },1322 .storage = .{ .u64 = bytes[field_i] },
1323 } }),1323 } }),
1324 .elems => |elems| elems[field_i],1324 .elems => |elems| elems[field_i],
1325 .repeated_elem => |elem| elem,1325 .repeated_elem => |elem| elem,
1326 };1326 };
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
1329 empty = false;1329 empty = false;
1330 }1330 }
src/codegen/llvm.zig+10-10
...@@ -2493,7 +2493,6 @@ pub const Object = struct {...@@ -2493,7 +2493,6 @@ pub const Object = struct {
24932493
2494 const struct_type = mod.typeToStruct(ty).?;2494 const struct_type = mod.typeToStruct(ty).?;
2495 const field_types = struct_type.field_types.get(ip);2495 const field_types = struct_type.field_types.get(ip);
2496 const field_names = struct_type.field_names.get(ip);
24972496
2498 var di_fields: std.ArrayListUnmanaged(*llvm.DIType) = .{};2497 var di_fields: std.ArrayListUnmanaged(*llvm.DIType) = .{};
2499 defer di_fields.deinit(gpa);2498 defer di_fields.deinit(gpa);
...@@ -2514,18 +2513,21 @@ pub const Object = struct {...@@ -2514,18 +2513,21 @@ pub const Object = struct {
2514 const field_offset = field_align.forward(offset);2513 const field_offset = field_align.forward(offset);
2515 offset = field_offset + field_size;2514 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
2519 try di_fields.append(gpa, dib.createMemberType(2521 try di_fields.append(gpa, dib.createMemberType(
2520 fwd_decl.toScope(),2522 fwd_decl.toScope(),
2521 field_name,2523 ip.stringToSlice(field_name),
2522 null, // file2524 null, // file
2523 0, // line2525 0, // line
2524 field_size * 8, // size in bits2526 field_size * 8, // size in bits
2525 field_align.toByteUnits(0) * 8, // align in bits2527 field_align.toByteUnits(0) * 8, // align in bits
2526 field_offset * 8, // offset in bits2528 field_offset * 8, // offset in bits
2527 0, // flags2529 0, // flags
2528 try o.lowerDebugType(field_ty, .full),2530 field_di_ty,
2529 ));2531 ));
2530 }2532 }
25312533
...@@ -3301,13 +3303,11 @@ pub const Object = struct {...@@ -3301,13 +3303,11 @@ pub const Object = struct {
3301 var offset: u64 = 0;3303 var offset: u64 = 0;
3302 var big_align: InternPool.Alignment = .@"1";3304 var big_align: InternPool.Alignment = .@"1";
3303 var struct_kind: Builder.Type.Structure.Kind = .normal;3305 var struct_kind: Builder.Type.Structure.Kind = .normal;
33043306 var it = struct_type.iterateRuntimeOrder(ip);
3305 for (struct_type.runtime_order.get(ip)) |runtime_index| {3307 while (it.next()) |field_index| {
3306 const field_index = runtime_index.toInt() orelse break;
3307 const field_ty = struct_type.field_types.get(ip)[field_index].toType();3308 const field_ty = struct_type.field_types.get(ip)[field_index].toType();
3308 const field_aligns = struct_type.field_aligns.get(ip);
3309 const field_align = mod.structFieldAlignment(3309 const field_align = mod.structFieldAlignment(
3310 if (field_aligns.len == 0) .none else field_aligns[field_index],3310 struct_type.fieldAlign(ip, field_index),
3311 field_ty,3311 field_ty,
3312 struct_type.layout,3312 struct_type.layout,
3313 );3313 );
...@@ -4012,7 +4012,7 @@ pub const Object = struct {...@@ -4012,7 +4012,7 @@ pub const Object = struct {
4012 comptime assert(struct_layout_version == 2);4012 comptime assert(struct_layout_version == 2);
4013 var llvm_index: usize = 0;4013 var llvm_index: usize = 0;
4014 var offset: u64 = 0;4014 var offset: u64 = 0;
4015 var big_align: InternPool.Alignment = .none;4015 var big_align: InternPool.Alignment = .@"1";
4016 var need_unnamed = false;4016 var need_unnamed = false;
4017 var field_it = struct_type.iterateRuntimeOrder(ip);4017 var field_it = struct_type.iterateRuntimeOrder(ip);
4018 while (field_it.next()) |field_index| {4018 while (field_it.next()) |field_index| {
src/type.zig+14-22
...@@ -843,7 +843,7 @@ pub const Type = struct {...@@ -843,7 +843,7 @@ pub const Type = struct {
843 pub fn lazyAbiAlignment(ty: Type, mod: *Module) !Value {843 pub fn lazyAbiAlignment(ty: Type, mod: *Module) !Value {
844 switch (try ty.abiAlignmentAdvanced(mod, .lazy)) {844 switch (try ty.abiAlignmentAdvanced(mod, .lazy)) {
845 .val => |val| return val,845 .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)),
847 }847 }
848 }848 }
849849
...@@ -997,8 +997,7 @@ pub const Type = struct {...@@ -997,8 +997,7 @@ pub const Type = struct {
997 }997 }
998998
999 const flags = struct_type.flagsPtr(ip).*;999 const flags = struct_type.flagsPtr(ip).*;
1000 if (flags.layout_resolved)1000 if (flags.layout_resolved) return .{ .scalar = flags.alignment };
1001 return .{ .scalar = flags.alignment };
10021001
1003 switch (strat) {1002 switch (strat) {
1004 .eager => unreachable, // struct layout not resolved1003 .eager => unreachable, // struct layout not resolved
...@@ -1423,20 +1422,12 @@ pub const Type = struct {...@@ -1423,20 +1422,12 @@ pub const Type = struct {
1423 },1422 },
1424 .eager => {},1423 .eager => {},
1425 }1424 }
1426 switch (struct_type.layout) {1425 return switch (struct_type.layout) {
1427 .Packed => {1426 .Packed => .{
1428 return .{1427 .scalar = struct_type.backingIntType(ip).toType().abiSize(mod),
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) };
1438 },1428 },
1439 }1429 .Auto, .Extern => .{ .scalar = struct_type.size(ip).* },
1430 };
1440 },1431 },
1441 .anon_struct_type => |tuple| {1432 .anon_struct_type => |tuple| {
1442 switch (strat) {1433 switch (strat) {
...@@ -1655,19 +1646,19 @@ pub const Type = struct {...@@ -1655,19 +1646,19 @@ pub const Type = struct {
1655 },1646 },
1656 .struct_type => |struct_type| {1647 .struct_type => |struct_type| {
1657 if (struct_type.layout == .Packed) {1648 if (struct_type.layout == .Packed) {
1658 if (opt_sema) |sema| _ = try sema.resolveTypeLayout(ty);1649 if (opt_sema) |sema| try sema.resolveTypeLayout(ty);
1659 return try struct_type.backingIntType(ip).*.toType().bitSizeAdvanced(mod, opt_sema);1650 return try struct_type.backingIntType(ip).*.toType().bitSizeAdvanced(mod, opt_sema);
1660 }1651 }
1661 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;1652 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
1662 },1653 },
16631654
1664 .anon_struct_type => {1655 .anon_struct_type => {
1665 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);1656 if (opt_sema) |sema| try sema.resolveTypeFields(ty);
1666 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;1657 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
1667 },1658 },
16681659
1669 .union_type => |union_type| {1660 .union_type => |union_type| {
1670 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);1661 if (opt_sema) |sema| try sema.resolveTypeFields(ty);
1671 if (ty.containerLayout(mod) != .Packed) {1662 if (ty.containerLayout(mod) != .Packed) {
1672 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;1663 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
1673 }1664 }
...@@ -2091,6 +2082,7 @@ pub const Type = struct {...@@ -2091,6 +2082,7 @@ pub const Type = struct {
2091 return switch (ip.indexToKey(ty.toIntern())) {2082 return switch (ip.indexToKey(ty.toIntern())) {
2092 .vector_type => |vector_type| vector_type.len,2083 .vector_type => |vector_type| vector_type.len,
2093 .array_type => |array_type| array_type.len,2084 .array_type => |array_type| array_type.len,
2085 .struct_type => |struct_type| struct_type.field_types.len,
2094 .anon_struct_type => |tuple| tuple.types.len,2086 .anon_struct_type => |tuple| tuple.types.len,
20952087
2096 else => unreachable,2088 else => unreachable,
...@@ -2964,7 +2956,7 @@ pub const Type = struct {...@@ -2964,7 +2956,7 @@ pub const Type = struct {
2964 switch (ip.indexToKey(ty.toIntern())) {2956 switch (ip.indexToKey(ty.toIntern())) {
2965 .struct_type => |struct_type| {2957 .struct_type => |struct_type| {
2966 assert(struct_type.layout != .Packed);2958 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);
2968 const field_ty = struct_type.field_types.get(ip)[index].toType();2960 const field_ty = struct_type.field_types.get(ip)[index].toType();
2969 return mod.structFieldAlignment(explicit_align, field_ty, struct_type.layout);2961 return mod.structFieldAlignment(explicit_align, field_ty, struct_type.layout);
2970 },2962 },
...@@ -2983,7 +2975,7 @@ pub const Type = struct {...@@ -2983,7 +2975,7 @@ pub const Type = struct {
2983 const ip = &mod.intern_pool;2975 const ip = &mod.intern_pool;
2984 switch (ip.indexToKey(ty.toIntern())) {2976 switch (ip.indexToKey(ty.toIntern())) {
2985 .struct_type => |struct_type| {2977 .struct_type => |struct_type| {
2986 const val = struct_type.field_inits.get(ip)[index];2978 const val = struct_type.fieldInit(ip, index);
2987 // TODO: avoid using `unreachable` to indicate this.2979 // TODO: avoid using `unreachable` to indicate this.
2988 if (val == .none) return Value.@"unreachable";2980 if (val == .none) return Value.@"unreachable";
2989 return val.toValue();2981 return val.toValue();
...@@ -3002,7 +2994,7 @@ pub const Type = struct {...@@ -3002,7 +2994,7 @@ pub const Type = struct {
3002 const ip = &mod.intern_pool;2994 const ip = &mod.intern_pool;
3003 switch (ip.indexToKey(ty.toIntern())) {2995 switch (ip.indexToKey(ty.toIntern())) {
3004 .struct_type => |struct_type| {2996 .struct_type => |struct_type| {
3005 if (struct_type.comptime_bits.getBit(ip, index)) {2997 if (struct_type.fieldIsComptime(ip, index)) {
3006 return struct_type.field_inits.get(ip)[index].toValue();2998 return struct_type.field_inits.get(ip)[index].toValue();
3007 } else {2999 } else {
3008 return struct_type.field_types.get(ip)[index].toType().onePossibleValue(mod);3000 return struct_type.field_types.get(ip)[index].toType().onePossibleValue(mod);