@@ -463,6 +463,7 @@ pub const Key = union(enum) {
463
463
464
464
pub fn fieldInit (s : @This (), ip : * const InternPool , i : usize ) Index {
465
465
if (s .field_inits .len == 0 ) return .none ;
466
+ assert (s .haveFieldInits (ip ));
466
467
return s .field_inits .get (ip )[i ];
467
468
}
468
469
@@ -497,6 +498,14 @@ pub const Key = union(enum) {
497
498
return @ptrCast (& ip .extra .items [self .extra_index + flags_field_index ]);
498
499
}
499
500
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
+
500
509
pub fn assumeRuntimeBitsIfFieldTypesWip (s : @This (), ip : * InternPool ) bool {
501
510
if (s .layout == .Packed ) return false ;
502
511
const flags_ptr = s .flagsPtr (ip );
@@ -546,6 +555,30 @@ pub const Key = union(enum) {
546
555
s .flagsPtr (ip ).alignment_wip = false ;
547
556
}
548
557
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
+
549
582
pub fn setFullyResolved (s : @This (), ip : * InternPool ) bool {
550
583
if (s .layout == .Packed ) return true ;
551
584
const flags_ptr = s .flagsPtr (ip );
@@ -588,6 +621,20 @@ pub const Key = union(enum) {
588
621
return types .len == 0 or types [0 ] != .none ;
589
622
}
590
623
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
+
591
638
pub fn haveLayout (s : @This (), ip : * InternPool ) bool {
592
639
return switch (s .layout ) {
593
640
.Packed = > s .backingIntType (ip ).* != .none ,
@@ -3000,6 +3047,14 @@ pub const Tag = enum(u8) {
3000
3047
namespace : Module.Namespace.OptionalIndex ,
3001
3048
backing_int_ty : Index ,
3002
3049
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
+ };
3003
3058
};
3004
3059
3005
3060
/// At first I thought of storing the denormalized data externally, such as...
@@ -3045,6 +3100,7 @@ pub const Tag = enum(u8) {
3045
3100
requires_comptime : RequiresComptime ,
3046
3101
is_tuple : bool ,
3047
3102
assumed_runtime_bits : bool ,
3103
+ assumed_pointer_aligned : bool ,
3048
3104
has_namespace : bool ,
3049
3105
any_comptime_fields : bool ,
3050
3106
any_default_inits : bool ,
@@ -3057,14 +3113,18 @@ pub const Tag = enum(u8) {
3057
3113
field_types_wip : bool ,
3058
3114
/// Dependency loop detection when resolving struct layout.
3059
3115
layout_wip : bool ,
3060
- /// Determines whether `size`, `alignment`, runtime field order, and
3116
+ /// Indicates whether `size`, `alignment`, runtime field order, and
3061
3117
/// field offets are populated.
3062
3118
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 ,
3063
3123
// The types and all its fields have had their layout resolved. Even through pointer,
3064
3124
// which `layout_resolved` does not ensure.
3065
3125
fully_resolved : bool ,
3066
3126
3067
- _ : u11 = 0 ,
3127
+ _ : u8 = 0 ,
3068
3128
};
3069
3129
};
3070
3130
};
@@ -5347,6 +5407,7 @@ pub const StructTypeInit = struct {
5347
5407
is_tuple : bool ,
5348
5408
any_comptime_fields : bool ,
5349
5409
any_default_inits : bool ,
5410
+ inits_resolved : bool ,
5350
5411
any_aligned_fields : bool ,
5351
5412
};
5352
5413
@@ -5399,6 +5460,10 @@ pub fn getStructType(
5399
5460
.namespace = ini .namespace ,
5400
5461
.backing_int_ty = .none ,
5401
5462
.names_map = names_map ,
5463
+ .flags = .{
5464
+ .field_inits_wip = false ,
5465
+ .inits_resolved = ini .inits_resolved ,
5466
+ },
5402
5467
}),
5403
5468
});
5404
5469
ip .extra .appendNTimesAssumeCapacity (@intFromEnum (Index .none ), ini .fields_len );
@@ -5431,6 +5496,7 @@ pub fn getStructType(
5431
5496
.requires_comptime = ini .requires_comptime ,
5432
5497
.is_tuple = ini .is_tuple ,
5433
5498
.assumed_runtime_bits = false ,
5499
+ .assumed_pointer_aligned = false ,
5434
5500
.has_namespace = ini .namespace != .none ,
5435
5501
.any_comptime_fields = ini .any_comptime_fields ,
5436
5502
.any_default_inits = ini .any_default_inits ,
@@ -5440,6 +5506,8 @@ pub fn getStructType(
5440
5506
.field_types_wip = false ,
5441
5507
.layout_wip = false ,
5442
5508
.layout_resolved = false ,
5509
+ .field_inits_wip = false ,
5510
+ .inits_resolved = ini .inits_resolved ,
5443
5511
.fully_resolved = false ,
5444
5512
},
5445
5513
}),
@@ -6451,6 +6519,7 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
6451
6519
Tag .TypePointer .PackedOffset ,
6452
6520
Tag .TypeUnion .Flags ,
6453
6521
Tag .TypeStruct .Flags ,
6522
+ Tag .TypeStructPacked .Flags ,
6454
6523
Tag .Variable .Flags ,
6455
6524
= > @bitCast (@field (extra , field .name )),
6456
6525
@@ -6525,6 +6594,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
6525
6594
Tag .TypePointer .PackedOffset ,
6526
6595
Tag .TypeUnion .Flags ,
6527
6596
Tag .TypeStruct .Flags ,
6597
+ Tag .TypeStructPacked .Flags ,
6528
6598
Tag .Variable .Flags ,
6529
6599
FuncAnalysis ,
6530
6600
= > @bitCast (int32 ),
0 commit comments