@@ -463,6 +463,7 @@ pub const Key = union(enum) {
463463
464464 pub fn fieldInit (s : @This (), ip : * const InternPool , i : usize ) Index {
465465 if (s .field_inits .len == 0 ) return .none ;
466+ assert (s .haveFieldInits (ip ));
466467 return s .field_inits .get (ip )[i ];
467468 }
468469
@@ -497,6 +498,14 @@ pub const Key = union(enum) {
497498 return @ptrCast (& ip .extra .items [self .extra_index + flags_field_index ]);
498499 }
499500
501+ /// The returned pointer expires with any addition to the `InternPool`.
502+ /// Asserts that the struct is packed.
503+ pub fn packedFlagsPtr (self : @This (), ip : * const InternPool ) * Tag.TypeStructPacked.Flags {
504+ assert (self .layout == .Packed );
505+ const flags_field_index = std .meta .fieldIndex (Tag .TypeStructPacked , "flags" ).? ;
506+ return @ptrCast (& ip .extra .items [self .extra_index + flags_field_index ]);
507+ }
508+
500509 pub fn assumeRuntimeBitsIfFieldTypesWip (s : @This (), ip : * InternPool ) bool {
501510 if (s .layout == .Packed ) return false ;
502511 const flags_ptr = s .flagsPtr (ip );
@@ -546,6 +555,30 @@ pub const Key = union(enum) {
546555 s .flagsPtr (ip ).alignment_wip = false ;
547556 }
548557
558+ pub fn setInitsWip (s : @This (), ip : * InternPool ) bool {
559+ switch (s .layout ) {
560+ .Packed = > {
561+ const flag = & s .packedFlagsPtr (ip ).field_inits_wip ;
562+ if (flag .* ) return true ;
563+ flag .* = true ;
564+ return false ;
565+ },
566+ .Auto , .Extern = > {
567+ const flag = & s .flagsPtr (ip ).field_inits_wip ;
568+ if (flag .* ) return true ;
569+ flag .* = true ;
570+ return false ;
571+ },
572+ }
573+ }
574+
575+ pub fn clearInitsWip (s : @This (), ip : * InternPool ) void {
576+ switch (s .layout ) {
577+ .Packed = > s .packedFlagsPtr (ip ).field_inits_wip = false ,
578+ .Auto , .Extern = > s .flagsPtr (ip ).field_inits_wip = false ,
579+ }
580+ }
581+
549582 pub fn setFullyResolved (s : @This (), ip : * InternPool ) bool {
550583 if (s .layout == .Packed ) return true ;
551584 const flags_ptr = s .flagsPtr (ip );
@@ -588,6 +621,20 @@ pub const Key = union(enum) {
588621 return types .len == 0 or types [0 ] != .none ;
589622 }
590623
624+ pub fn haveFieldInits (s : @This (), ip : * const InternPool ) bool {
625+ return switch (s .layout ) {
626+ .Packed = > s .packedFlagsPtr (ip ).inits_resolved ,
627+ .Auto , .Extern = > s .flagsPtr (ip ).inits_resolved ,
628+ };
629+ }
630+
631+ pub fn setHaveFieldInits (s : @This (), ip : * InternPool ) void {
632+ switch (s .layout ) {
633+ .Packed = > s .packedFlagsPtr (ip ).inits_resolved = true ,
634+ .Auto , .Extern = > s .flagsPtr (ip ).inits_resolved = true ,
635+ }
636+ }
637+
591638 pub fn haveLayout (s : @This (), ip : * InternPool ) bool {
592639 return switch (s .layout ) {
593640 .Packed = > s .backingIntType (ip ).* != .none ,
@@ -3000,6 +3047,14 @@ pub const Tag = enum(u8) {
30003047 namespace : Module.Namespace.OptionalIndex ,
30013048 backing_int_ty : Index ,
30023049 names_map : MapIndex ,
3050+ flags : Flags ,
3051+
3052+ pub const Flags = packed struct (u32 ) {
3053+ /// Dependency loop detection when resolving field inits.
3054+ field_inits_wip : bool ,
3055+ inits_resolved : bool ,
3056+ _ : u30 = 0 ,
3057+ };
30033058 };
30043059
30053060 /// At first I thought of storing the denormalized data externally, such as...
@@ -3045,6 +3100,7 @@ pub const Tag = enum(u8) {
30453100 requires_comptime : RequiresComptime ,
30463101 is_tuple : bool ,
30473102 assumed_runtime_bits : bool ,
3103+ assumed_pointer_aligned : bool ,
30483104 has_namespace : bool ,
30493105 any_comptime_fields : bool ,
30503106 any_default_inits : bool ,
@@ -3057,14 +3113,18 @@ pub const Tag = enum(u8) {
30573113 field_types_wip : bool ,
30583114 /// Dependency loop detection when resolving struct layout.
30593115 layout_wip : bool ,
3060- /// Determines whether `size`, `alignment`, runtime field order, and
3116+ /// Indicates whether `size`, `alignment`, runtime field order, and
30613117 /// field offets are populated.
30623118 layout_resolved : bool ,
3119+ /// Dependency loop detection when resolving field inits.
3120+ field_inits_wip : bool ,
3121+ /// Indicates whether `field_inits` has been resolved.
3122+ inits_resolved : bool ,
30633123 // The types and all its fields have had their layout resolved. Even through pointer,
30643124 // which `layout_resolved` does not ensure.
30653125 fully_resolved : bool ,
30663126
3067- _ : u11 = 0 ,
3127+ _ : u8 = 0 ,
30683128 };
30693129 };
30703130};
@@ -5347,6 +5407,7 @@ pub const StructTypeInit = struct {
53475407 is_tuple : bool ,
53485408 any_comptime_fields : bool ,
53495409 any_default_inits : bool ,
5410+ inits_resolved : bool ,
53505411 any_aligned_fields : bool ,
53515412};
53525413
@@ -5399,6 +5460,10 @@ pub fn getStructType(
53995460 .namespace = ini .namespace ,
54005461 .backing_int_ty = .none ,
54015462 .names_map = names_map ,
5463+ .flags = .{
5464+ .field_inits_wip = false ,
5465+ .inits_resolved = ini .inits_resolved ,
5466+ },
54025467 }),
54035468 });
54045469 ip .extra .appendNTimesAssumeCapacity (@intFromEnum (Index .none ), ini .fields_len );
@@ -5431,6 +5496,7 @@ pub fn getStructType(
54315496 .requires_comptime = ini .requires_comptime ,
54325497 .is_tuple = ini .is_tuple ,
54335498 .assumed_runtime_bits = false ,
5499+ .assumed_pointer_aligned = false ,
54345500 .has_namespace = ini .namespace != .none ,
54355501 .any_comptime_fields = ini .any_comptime_fields ,
54365502 .any_default_inits = ini .any_default_inits ,
@@ -5440,6 +5506,8 @@ pub fn getStructType(
54405506 .field_types_wip = false ,
54415507 .layout_wip = false ,
54425508 .layout_resolved = false ,
5509+ .field_inits_wip = false ,
5510+ .inits_resolved = ini .inits_resolved ,
54435511 .fully_resolved = false ,
54445512 },
54455513 }),
@@ -6451,6 +6519,7 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
64516519 Tag .TypePointer .PackedOffset ,
64526520 Tag .TypeUnion .Flags ,
64536521 Tag .TypeStruct .Flags ,
6522+ Tag .TypeStructPacked .Flags ,
64546523 Tag .Variable .Flags ,
64556524 = > @bitCast (@field (extra , field .name )),
64566525
@@ -6525,6 +6594,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
65256594 Tag .TypePointer .PackedOffset ,
65266595 Tag .TypeUnion .Flags ,
65276596 Tag .TypeStruct .Flags ,
6597+ Tag .TypeStructPacked .Flags ,
65286598 Tag .Variable .Flags ,
65296599 FuncAnalysis ,
65306600 = > @bitCast (int32 ),
0 commit comments