authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-01-27 17:13:14+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-10 10:26:08+00:00
log911294116d5df0db3b431f9117f42bf8074a3b83
tree5cd31fd32252c20fdfeec276a252aae3d2d8e4dc
parent334189ce6d20d6d1100f115252d5589fadb064b1
signaturelock-open Commit is signed but in an unrecognized format.

compiler: make type resolution lazy

...and rework some of the incremental reference tracking. Almost all kinds of AnalUnit have one property in common: they might never be referenced in any update despite conceptually "existing", in which case we don't want to waste time semantically analyzing them. As of the lazy type resolution introduced in this commit, the only units to which this does not apply are `memoized_state` and `@"comptime"`. Previously, I had a somewhat hacky system in `Zcu` for dealing with this, but I now have a better understanding of the design incremental compilation is converging on, so can implement a better solution. By finding a few unused bits lying around (...or making them), we can represent a single bit of state indicating whether something's corresponding units have ever been referenced. This is akin to the units being in `Zcu.outdated`, with the key difference being that the compiler will *not* attempt to analyze units which are in this state. Once they are first referenced or depended on, the flag is set to true and the unit is added to `outdated` so that it can participate in the normal dependency resolution logic.

9 files changed, 515 insertions(+), 367 deletions(-)

src/InternPool.zig+339-73
...@@ -546,6 +546,8 @@ pub const Nav = struct {...@@ -546,6 +546,8 @@ pub const Nav = struct {
546 analysis: ?struct {546 analysis: ?struct {
547 namespace: NamespaceIndex,547 namespace: NamespaceIndex,
548 zir_index: TrackedInst.Index,548 zir_index: TrackedInst.Index,
549 /// Initially `false`. Set to `true` by `setWantNavAnalysis`.
550 wanted: bool,
549 },551 },
550 status: union(enum) {552 status: union(enum) {
551 /// This `Nav` is pending semantic analysis.553 /// This `Nav` is pending semantic analysis.
...@@ -743,7 +745,7 @@ pub const Nav = struct {...@@ -743,7 +745,7 @@ pub const Nav = struct {
743 const Repr = struct {745 const Repr = struct {
744 name: NullTerminatedString,746 name: NullTerminatedString,
745 fqn: NullTerminatedString,747 fqn: NullTerminatedString,
746 // The following 1 fields are either both populated, or both `.none`.748 // The following 2 fields are either both populated, or both `.none`.
747 analysis_namespace: OptionalNamespaceIndex,749 analysis_namespace: OptionalNamespaceIndex,
748 analysis_zir_index: TrackedInst.Index.Optional,750 analysis_zir_index: TrackedInst.Index.Optional,
749 /// Populated only if `bits.status != .unresolved`.751 /// Populated only if `bits.status != .unresolved`.
...@@ -762,7 +764,7 @@ pub const Nav = struct {...@@ -762,7 +764,7 @@ pub const Nav = struct {
762 @"addrspace": std.builtin.AddressSpace,764 @"addrspace": std.builtin.AddressSpace,
763 /// Populated only if `bits.status == .type_resolved`.765 /// Populated only if `bits.status == .type_resolved`.
764 is_threadlocal: bool,766 is_threadlocal: bool,
765 _: u1 = 0,767 want_analysis: bool,
766 };768 };
767769
768 fn unpack(repr: Repr) Nav {770 fn unpack(repr: Repr) Nav {
...@@ -772,6 +774,7 @@ pub const Nav = struct {...@@ -772,6 +774,7 @@ pub const Nav = struct {
772 .analysis = if (repr.analysis_namespace.unwrap()) |namespace| .{774 .analysis = if (repr.analysis_namespace.unwrap()) |namespace| .{
773 .namespace = namespace,775 .namespace = namespace,
774 .zir_index = repr.analysis_zir_index.unwrap().?,776 .zir_index = repr.analysis_zir_index.unwrap().?,
777 .wanted = repr.bits.want_analysis,
775 } else a: {778 } else a: {
776 assert(repr.analysis_zir_index == .none);779 assert(repr.analysis_zir_index == .none);
777 break :a null;780 break :a null;
...@@ -824,6 +827,7 @@ pub const Nav = struct {...@@ -824,6 +827,7 @@ pub const Nav = struct {
824 .alignment = .none,827 .alignment = .none,
825 .@"addrspace" = .generic,828 .@"addrspace" = .generic,
826 .is_threadlocal = false,829 .is_threadlocal = false,
830 .want_analysis = if (nav.analysis) |a| a.wanted else false,
827 },831 },
828 .type_resolved => |r| .{832 .type_resolved => |r| .{
829 .status = if (r.is_extern_decl) .type_resolved_extern_decl else .type_resolved,833 .status = if (r.is_extern_decl) .type_resolved_extern_decl else .type_resolved,
...@@ -831,6 +835,7 @@ pub const Nav = struct {...@@ -831,6 +835,7 @@ pub const Nav = struct {
831 .alignment = r.alignment,835 .alignment = r.alignment,
832 .@"addrspace" = r.@"addrspace",836 .@"addrspace" = r.@"addrspace",
833 .is_threadlocal = r.is_threadlocal,837 .is_threadlocal = r.is_threadlocal,
838 .want_analysis = if (nav.analysis) |a| a.wanted else false,
834 },839 },
835 .fully_resolved => |r| .{840 .fully_resolved => |r| .{
836 .status = .fully_resolved,841 .status = .fully_resolved,
...@@ -838,6 +843,7 @@ pub const Nav = struct {...@@ -838,6 +843,7 @@ pub const Nav = struct {
838 .alignment = r.alignment,843 .alignment = r.alignment,
839 .@"addrspace" = r.@"addrspace",844 .@"addrspace" = r.@"addrspace",
840 .is_threadlocal = false,845 .is_threadlocal = false,
846 .want_analysis = if (nav.analysis) |a| a.wanted else false,
841 },847 },
842 },848 },
843 };849 };
...@@ -2412,17 +2418,6 @@ pub const Key = union(enum) {...@@ -2412,17 +2418,6 @@ pub const Key = union(enum) {
2412 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);2418 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
2413 }2419 }
24142420
2415 pub fn setAnalyzed(func: Func, ip: *InternPool, io: Io) void {
2416 const extra_mutex = &ip.getLocal(func.tid).mutate.extra.mutex;
2417 extra_mutex.lockUncancelable(io);
2418 defer extra_mutex.unlock(io);
2419
2420 const analysis_ptr = func.analysisPtr(ip);
2421 var analysis = analysis_ptr.*;
2422 analysis.is_analyzed = true;
2423 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
2424 }
2425
2426 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.2421 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
2427 fn zirBodyInstPtr(func: Func, ip: *const InternPool) *TrackedInst.Index {2422 fn zirBodyInstPtr(func: Func, ip: *const InternPool) *TrackedInst.Index {
2428 const extra = ip.getLocalShared(func.tid).extra.acquire();2423 const extra = ip.getLocalShared(func.tid).extra.acquire();
...@@ -3314,6 +3309,25 @@ pub const LoadedStructType = struct {...@@ -3314,6 +3309,25 @@ pub const LoadedStructType = struct {
3314 /// May be `undefined` if `layout != .@"packed"`.3309 /// May be `undefined` if `layout != .@"packed"`.
3315 packed_backing_mode: BackingTypeMode,3310 packed_backing_mode: BackingTypeMode,
33163311
3312 /// Initially `false`, and set to `true` once any dependency on or reference to the struct's
3313 /// layout is encountered, after which it is never reset to `false`, even across incremental
3314 /// updates.
3315 ///
3316 /// This field is purely an optimization to avoid resolving the layout of types whose layouts
3317 /// are never demanded. If this field is `true` but the layout is not actually needed, the
3318 /// compiler frontend resolves this by traversing the reference graph at the end of each update
3319 /// with `Zcu.resolveReferences` and hiding compile errors which arise from this analysis.
3320 want_layout: bool,
3321 /// Initially `false`, and set to `true` once any dependency on or reference to the struct's
3322 /// default field values is encountered, after which it is never reset to `false`, even across
3323 /// incremental updates.
3324 ///
3325 /// This field is purely an optimization to avoid resolving the layout of types whose layouts
3326 /// are never demanded. If this field is `true` but the layout is not actually needed, the
3327 /// compiler frontend resolves this by traversing the reference graph at the end of each update
3328 /// with `Zcu.resolveReferences` and hiding compile errors which arise from this analysis.
3329 want_defaults: bool,
3330
3317 // The remaining fields are only valid once the struct's layout is resolved.3331 // The remaining fields are only valid once the struct's layout is resolved.
3318 field_name_map: MapIndex,3332 field_name_map: MapIndex,
3319 field_names: NullTerminatedString.Slice,3333 field_names: NullTerminatedString.Slice,
...@@ -3490,6 +3504,16 @@ pub const LoadedUnionType = struct {...@@ -3490,6 +3504,16 @@ pub const LoadedUnionType = struct {
3490 /// or populate `enum_tag_type`.3504 /// or populate `enum_tag_type`.
3491 reified_field_names: NullTerminatedString.Slice,3505 reified_field_names: NullTerminatedString.Slice,
34923506
3507 /// Initially `false`, and set to `true` once any dependency on or reference to the struct's
3508 /// layout is encountered, after which it is never reset to `false`, even across incremental
3509 /// updates.
3510 ///
3511 /// This field is purely an optimization to avoid resolving the layout of types whose layouts
3512 /// are never demanded. If this field is `true` but the layout is not actually needed, the
3513 /// compiler frontend resolves this by traversing the reference graph at the end of each update
3514 /// with `Zcu.resolveReferences` and hiding compile errors which arise from this analysis.
3515 want_layout: bool,
3516
3493 // The remaining fields are only valid once the union's layout is resolved.3517 // The remaining fields are only valid once the union's layout is resolved.
3494 field_types: Index.Slice,3518 field_types: Index.Slice,
3495 field_aligns: Alignment.Slice,3519 field_aligns: Alignment.Slice,
...@@ -3532,6 +3556,16 @@ pub const LoadedEnumType = struct {...@@ -3532,6 +3556,16 @@ pub const LoadedEnumType = struct {
3532 int_tag_mode: BackingTypeMode,3556 int_tag_mode: BackingTypeMode,
3533 nonexhaustive: bool,3557 nonexhaustive: bool,
35343558
3559 /// Initially `false`, and set to `true` once any dependency on or reference to the struct's
3560 /// layout is encountered, after which it is never reset to `false`, even across incremental
3561 /// updates.
3562 ///
3563 /// This field is purely an optimization to avoid resolving the layout of types whose layouts
3564 /// are never demanded. If this field is `true` but the layout is not actually needed, the
3565 /// compiler frontend resolves this by traversing the reference graph at the end of each update
3566 /// with `Zcu.resolveReferences` and hiding compile errors which arise from this analysis.
3567 want_layout: bool,
3568
3535 // The remaining fields are only valid once the enum's layout is resolved.3569 // The remaining fields are only valid once the enum's layout is resolved.
3536 int_tag_type: Index,3570 int_tag_type: Index,
3537 field_name_map: MapIndex,3571 field_name_map: MapIndex,
...@@ -3669,6 +3703,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3669,6 +3703,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3669 },3703 },
3670 .packed_backing_mode = undefined,3704 .packed_backing_mode = undefined,
36713705
3706 .want_layout = extra.data.flags.want_layout,
3707 .want_defaults = extra.data.flags.want_defaults,
3708
3672 .field_name_map = extra.data.field_name_map,3709 .field_name_map = extra.data.field_name_map,
3673 .field_names = field_names,3710 .field_names = field_names,
3674 .field_types = field_types,3711 .field_types = field_types,
...@@ -3690,15 +3727,15 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3690,15 +3727,15 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3690 };3727 };
3691 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, item.data);3728 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, item.data);
3692 var extra_index = extra.end;3729 var extra_index = extra.end;
3693 const captures: CaptureValue.Slice = switch (extra.data.captures_len) {3730 const captures: CaptureValue.Slice = switch (extra.data.bits.captures_len) {
3694 .reified => captures: {3731 .reified => captures: {
3695 extra_index += 2; // type_hash: PackedU643732 extra_index += 2; // type_hash: PackedU64
3696 break :captures .empty;3733 break :captures .empty;
3697 },3734 },
3698 _ => .{3735 _ => |n| .{
3699 .tid = unwrapped_index.tid,3736 .tid = unwrapped_index.tid,
3700 .start = extra_index,3737 .start = extra_index,
3701 .len = @intFromEnum(extra.data.captures_len),3738 .len = @intFromEnum(n),
3702 },3739 },
3703 };3740 };
3704 extra_index += captures.len;3741 extra_index += captures.len;
...@@ -3723,13 +3760,16 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3723,13 +3760,16 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3723 return .{3760 return .{
3724 .zir_index = extra.data.zir_index,3761 .zir_index = extra.data.zir_index,
3725 .captures = captures,3762 .captures = captures,
3726 .is_reified = extra.data.captures_len == .reified,3763 .is_reified = extra.data.bits.captures_len == .reified,
3727 .name = extra.data.name,3764 .name = extra.data.name,
3728 .name_nav = extra.data.name_nav,3765 .name_nav = extra.data.name_nav,
3729 .namespace = extra.data.namespace,3766 .namespace = extra.data.namespace,
3730 .layout = .@"packed",3767 .layout = .@"packed",
3731 .packed_backing_mode = backing_mode,3768 .packed_backing_mode = backing_mode,
37323769
3770 .want_layout = extra.data.bits.want_layout,
3771 .want_defaults = extra.data.bits.want_defaults,
3772
3733 .field_name_map = extra.data.field_name_map,3773 .field_name_map = extra.data.field_name_map,
3734 .field_names = field_names,3774 .field_names = field_names,
3735 .field_types = field_types,3775 .field_types = field_types,
...@@ -3813,6 +3853,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {...@@ -3813,6 +3853,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
3813 .packed_backing_mode = undefined,3853 .packed_backing_mode = undefined,
3814 .packed_backing_int_type = undefined,3854 .packed_backing_int_type = undefined,
3815 .reified_field_names = reified_field_names,3855 .reified_field_names = reified_field_names,
3856 .want_layout = extra.data.flags.want_layout,
3816 .field_types = field_types,3857 .field_types = field_types,
3817 .field_aligns = field_aligns,3858 .field_aligns = field_aligns,
3818 .has_no_possible_value = extra.data.flags.has_no_possible_value,3859 .has_no_possible_value = extra.data.flags.has_no_possible_value,
...@@ -3828,19 +3869,19 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {...@@ -3828,19 +3869,19 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
3828 };3869 };
3829 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, item.data);3870 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, item.data);
3830 var extra_index = extra.end;3871 var extra_index = extra.end;
3831 const captures: CaptureValue.Slice = switch (extra.data.captures_len) {3872 const captures: CaptureValue.Slice = switch (extra.data.bits.captures_len) {
3832 .reified => captures: {3873 .reified => captures: {
3833 extra_index += 2; // type_hash: PackedU643874 extra_index += 2; // type_hash: PackedU64
3834 break :captures .empty;3875 break :captures .empty;
3835 },3876 },
3836 _ => .{3877 _ => |n| .{
3837 .tid = unwrapped_index.tid,3878 .tid = unwrapped_index.tid,
3838 .start = extra_index,3879 .start = extra_index,
3839 .len = @intFromEnum(extra.data.captures_len),3880 .len = @intFromEnum(n),
3840 },3881 },
3841 };3882 };
3842 extra_index += captures.len;3883 extra_index += captures.len;
3843 const reified_field_names: NullTerminatedString.Slice = if (extra.data.captures_len == .reified) .{3884 const reified_field_names: NullTerminatedString.Slice = if (extra.data.bits.captures_len == .reified) .{
3844 .tid = unwrapped_index.tid,3885 .tid = unwrapped_index.tid,
3845 .start = extra_index,3886 .start = extra_index,
3846 .len = extra.data.fields_len,3887 .len = extra.data.fields_len,
...@@ -3855,7 +3896,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {...@@ -3855,7 +3896,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
3855 return .{3896 return .{
3856 .zir_index = extra.data.zir_index,3897 .zir_index = extra.data.zir_index,
3857 .captures = captures,3898 .captures = captures,
3858 .is_reified = extra.data.captures_len == .reified,3899 .is_reified = extra.data.bits.captures_len == .reified,
3859 .name = extra.data.name,3900 .name = extra.data.name,
3860 .name_nav = extra.data.name_nav,3901 .name_nav = extra.data.name_nav,
3861 .namespace = extra.data.namespace,3902 .namespace = extra.data.namespace,
...@@ -3866,6 +3907,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {...@@ -3866,6 +3907,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
3866 .packed_backing_mode = backing_mode,3907 .packed_backing_mode = backing_mode,
3867 .packed_backing_int_type = extra.data.backing_int_type,3908 .packed_backing_int_type = extra.data.backing_int_type,
3868 .reified_field_names = reified_field_names,3909 .reified_field_names = reified_field_names,
3910 .want_layout = extra.data.bits.want_layout,
3869 .field_types = field_types,3911 .field_types = field_types,
3870 .field_aligns = .empty,3912 .field_aligns = .empty,
3871 .has_no_possible_value = undefined,3913 .has_no_possible_value = undefined,
...@@ -3891,7 +3933,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3891,7 +3933,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3891 };3933 };
3892 const extra = extraDataTrail(extra_list, Tag.TypeEnum, item.data);3934 const extra = extraDataTrail(extra_list, Tag.TypeEnum, item.data);
3893 var extra_index: u32 = @intCast(extra.end);3935 var extra_index: u32 = @intCast(extra.end);
3894 const zir_index: TrackedInst.Index.Optional, const captures: CaptureValue.Slice, const owner_union: Index = switch (extra.data.captures_len) {3936 const zir_index: TrackedInst.Index.Optional, const captures: CaptureValue.Slice, const owner_union: Index = switch (extra.data.bits.captures_len) {
3895 .reified => info: {3937 .reified => info: {
3896 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[extra_index]);3938 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[extra_index]);
3897 extra_index += 1;3939 extra_index += 1;
...@@ -3903,13 +3945,13 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3903,13 +3945,13 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3903 extra_index += 1;3945 extra_index += 1;
3904 break :info .{ .none, .empty, owner_union };3946 break :info .{ .none, .empty, owner_union };
3905 },3947 },
3906 _ => info: {3948 _ => |n| info: {
3907 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[extra_index]);3949 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[extra_index]);
3908 extra_index += 1;3950 extra_index += 1;
3909 const captures: CaptureValue.Slice = .{3951 const captures: CaptureValue.Slice = .{
3910 .tid = unwrapped_index.tid,3952 .tid = unwrapped_index.tid,
3911 .start = extra_index,3953 .start = extra_index,
3912 .len = @intFromEnum(extra.data.captures_len),3954 .len = @intFromEnum(n),
3913 };3955 };
3914 extra_index += captures.len;3956 extra_index += captures.len;
3915 break :info .{ zir_index.toOptional(), captures, .none };3957 break :info .{ zir_index.toOptional(), captures, .none };
...@@ -3935,7 +3977,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3935,7 +3977,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3935 return .{3977 return .{
3936 .zir_index = zir_index,3978 .zir_index = zir_index,
3937 .captures = captures,3979 .captures = captures,
3938 .is_reified = extra.data.captures_len == .reified,3980 .is_reified = extra.data.bits.captures_len == .reified,
3939 .owner_union = owner_union,3981 .owner_union = owner_union,
3940 .name = extra.data.name,3982 .name = extra.data.name,
3941 .name_nav = extra.data.name_nav,3983 .name_nav = extra.data.name_nav,
...@@ -3943,6 +3985,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3943,6 +3985,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3943 .int_tag_type = extra.data.int_tag_type,3985 .int_tag_type = extra.data.int_tag_type,
3944 .int_tag_mode = if (explicit_int_tag) .explicit else .auto,3986 .int_tag_mode = if (explicit_int_tag) .explicit else .auto,
3945 .nonexhaustive = nonexhaustive,3987 .nonexhaustive = nonexhaustive,
3988 .want_layout = extra.data.bits.want_layout,
3946 .field_name_map = extra.data.field_name_map,3989 .field_name_map = extra.data.field_name_map,
3947 .field_value_map = field_value_map,3990 .field_value_map = field_value_map,
3948 .field_names = field_names,3991 .field_names = field_names,
...@@ -5629,7 +5672,10 @@ pub const Tag = enum(u8) {...@@ -5629,7 +5672,10 @@ pub const Tag = enum(u8) {
5629 /// Alignment of the whole struct. Always `.none` until layout resolved.5672 /// Alignment of the whole struct. Always `.none` until layout resolved.
5630 alignment: Alignment,5673 alignment: Alignment,
56315674
5632 _: u16 = 0,5675 want_layout: bool,
5676 want_defaults: bool,
5677
5678 _: u14 = 0,
5633 };5679 };
5634 };5680 };
56355681
...@@ -5641,10 +5687,7 @@ pub const Tag = enum(u8) {...@@ -5641,10 +5687,7 @@ pub const Tag = enum(u8) {
5641 /// 4. field_default: Index // if item tag implies field defaults; for each `fields_len`5687 /// 4. field_default: Index // if item tag implies field defaults; for each `fields_len`
5642 pub const TypeStructPacked = struct {5688 pub const TypeStructPacked = struct {
5643 zir_index: TrackedInst.Index,5689 zir_index: TrackedInst.Index,
5644 captures_len: enum(u32) {5690 bits: Bits,
5645 reified = std.math.maxInt(u32),
5646 _,
5647 },
56485691
5649 name: NullTerminatedString,5692 name: NullTerminatedString,
5650 name_nav: Nav.Index.Optional,5693 name_nav: Nav.Index.Optional,
...@@ -5655,6 +5698,15 @@ pub const Tag = enum(u8) {...@@ -5655,6 +5698,15 @@ pub const Tag = enum(u8) {
56555698
5656 fields_len: u32,5699 fields_len: u32,
5657 field_name_map: MapIndex,5700 field_name_map: MapIndex,
5701
5702 const Bits = packed struct(u32) {
5703 captures_len: enum(u30) {
5704 reified = std.math.maxInt(u30),
5705 _,
5706 },
5707 want_layout: bool,
5708 want_defaults: bool,
5709 };
5658 };5710 };
56595711
5660 /// For declared unions, field names are intentionally omitted because they are available in5712 /// For declared unions, field names are intentionally omitted because they are available in
...@@ -5718,7 +5770,9 @@ pub const Tag = enum(u8) {...@@ -5718,7 +5770,9 @@ pub const Tag = enum(u8) {
5718 /// Alignment of the whole union. Always `.none` until layout resolved.5770 /// Alignment of the whole union. Always `.none` until layout resolved.
5719 alignment: Alignment,5771 alignment: Alignment,
57205772
5721 _: u15 = 0,5773 want_layout: bool,
5774
5775 _: u14 = 0,
5722 };5776 };
5723 };5777 };
57245778
...@@ -5734,10 +5788,7 @@ pub const Tag = enum(u8) {...@@ -5734,10 +5788,7 @@ pub const Tag = enum(u8) {
5734 /// 3. field_type: Index // for each `fields_len`5788 /// 3. field_type: Index // for each `fields_len`
5735 pub const TypeUnionPacked = struct {5789 pub const TypeUnionPacked = struct {
5736 zir_index: TrackedInst.Index,5790 zir_index: TrackedInst.Index,
5737 captures_len: enum(u32) {5791 bits: Bits,
5738 reified = std.math.maxInt(u32),
5739 _,
5740 },
57415792
5742 name: NullTerminatedString,5793 name: NullTerminatedString,
5743 name_nav: Nav.Index.Optional,5794 name_nav: Nav.Index.Optional,
...@@ -5753,6 +5804,14 @@ pub const Tag = enum(u8) {...@@ -5753,6 +5804,14 @@ pub const Tag = enum(u8) {
5753 /// to store it directly. This is also necessary for `dumpStatsFallible` to5804 /// to store it directly. This is also necessary for `dumpStatsFallible` to
5754 /// work on unresolved types.5805 /// work on unresolved types.
5755 fields_len: u32,5806 fields_len: u32,
5807
5808 const Bits = packed struct(u32) {
5809 captures_len: enum(u31) {
5810 reified = std.math.maxInt(u31),
5811 _,
5812 },
5813 want_layout: bool,
5814 };
5756 };5815 };
57575816
5758 /// Trailing:5817 /// Trailing:
...@@ -5764,11 +5823,7 @@ pub const Tag = enum(u8) {...@@ -5764,11 +5823,7 @@ pub const Tag = enum(u8) {
5764 /// 5. field_name: NullTerminatedString // for each `fields_len`5823 /// 5. field_name: NullTerminatedString // for each `fields_len`
5765 /// 6. field_value: Index // if tag is not `.type_enum_auto`; for each `fields_len`5824 /// 6. field_value: Index // if tag is not `.type_enum_auto`; for each `fields_len`
5766 pub const TypeEnum = struct {5825 pub const TypeEnum = struct {
5767 captures_len: enum(u32) {5826 bits: Bits,
5768 reified = std.math.maxInt(u32),
5769 generated_union_tag = std.math.maxInt(u32) - 1,
5770 _,
5771 },
57725827
5773 name: NullTerminatedString,5828 name: NullTerminatedString,
5774 name_nav: Nav.Index.Optional,5829 name_nav: Nav.Index.Optional,
...@@ -5780,6 +5835,15 @@ pub const Tag = enum(u8) {...@@ -5780,6 +5835,15 @@ pub const Tag = enum(u8) {
57805835
5781 fields_len: u32,5836 fields_len: u32,
5782 field_name_map: MapIndex,5837 field_name_map: MapIndex,
5838
5839 const Bits = packed struct(u32) {
5840 captures_len: enum(u31) {
5841 reified = std.math.maxInt(u31),
5842 generated_union_tag = std.math.maxInt(u31) - 1,
5843 _,
5844 },
5845 want_layout: bool,
5846 };
5783 };5847 };
57845848
5785 /// Trailing:5849 /// Trailing:
...@@ -5812,7 +5876,7 @@ pub const BackingTypeMode = enum(u1) {...@@ -5812,7 +5876,7 @@ pub const BackingTypeMode = enum(u1) {
5812/// equality or hashing, except for `inferred_error_set` which is considered5876/// equality or hashing, except for `inferred_error_set` which is considered
5813/// to be part of the type of the function.5877/// to be part of the type of the function.
5814pub const FuncAnalysis = packed struct(u32) {5878pub const FuncAnalysis = packed struct(u32) {
5815 is_analyzed: bool,5879 want_runtime_analysis: bool,
5816 branch_hint: std.builtin.BranchHint,5880 branch_hint: std.builtin.BranchHint,
5817 is_noinline: bool,5881 is_noinline: bool,
5818 has_error_trace: bool,5882 has_error_trace: bool,
...@@ -6597,17 +6661,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6597,17 +6661,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6597 => .{ .struct_type = ns: {6661 => .{ .struct_type = ns: {
6598 const extra_list = unwrapped_index.getExtra(ip);6662 const extra_list = unwrapped_index.getExtra(ip);
6599 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);6663 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
6600 break :ns switch (extra.data.captures_len) {6664 break :ns switch (extra.data.bits.captures_len) {
6601 .reified => .{ .reified = .{6665 .reified => .{ .reified = .{
6602 .zir_index = extra.data.zir_index,6666 .zir_index = extra.data.zir_index,
6603 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),6667 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
6604 } },6668 } },
6605 _ => .{ .declared = .{6669 _ => |len| .{ .declared = .{
6606 .zir_index = extra.data.zir_index,6670 .zir_index = extra.data.zir_index,
6607 .captures = .{ .owned = .{6671 .captures = .{ .owned = .{
6608 .tid = unwrapped_index.tid,6672 .tid = unwrapped_index.tid,
6609 .start = extra.end,6673 .start = extra.end,
6610 .len = @intFromEnum(extra.data.captures_len),6674 .len = @intFromEnum(len),
6611 } },6675 } },
6612 } },6676 } },
6613 };6677 };
...@@ -6637,17 +6701,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6637,17 +6701,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6637 .type_union_packed_auto, .type_union_packed_explicit => .{ .union_type = ns: {6701 .type_union_packed_auto, .type_union_packed_explicit => .{ .union_type = ns: {
6638 const extra_list = unwrapped_index.getExtra(ip);6702 const extra_list = unwrapped_index.getExtra(ip);
6639 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, data);6703 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, data);
6640 break :ns switch (extra.data.captures_len) {6704 break :ns switch (extra.data.bits.captures_len) {
6641 .reified => .{ .reified = .{6705 .reified => .{ .reified = .{
6642 .zir_index = extra.data.zir_index,6706 .zir_index = extra.data.zir_index,
6643 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),6707 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
6644 } },6708 } },
6645 _ => .{ .declared = .{6709 _ => |len| .{ .declared = .{
6646 .zir_index = extra.data.zir_index,6710 .zir_index = extra.data.zir_index,
6647 .captures = .{ .owned = .{6711 .captures = .{ .owned = .{
6648 .tid = unwrapped_index.tid,6712 .tid = unwrapped_index.tid,
6649 .start = extra.end,6713 .start = extra.end,
6650 .len = @intFromEnum(extra.data.captures_len),6714 .len = @intFromEnum(len),
6651 } },6715 } },
6652 } },6716 } },
6653 };6717 };
...@@ -6655,7 +6719,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6655,7 +6719,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6655 .type_enum_auto, .type_enum_explicit, .type_enum_nonexhaustive => .{ .enum_type = ns: {6719 .type_enum_auto, .type_enum_explicit, .type_enum_nonexhaustive => .{ .enum_type = ns: {
6656 const extra_list = unwrapped_index.getExtra(ip);6720 const extra_list = unwrapped_index.getExtra(ip);
6657 const extra = extraDataTrail(extra_list, Tag.TypeEnum, data);6721 const extra = extraDataTrail(extra_list, Tag.TypeEnum, data);
6658 break :ns switch (extra.data.captures_len) {6722 break :ns switch (extra.data.bits.captures_len) {
6659 .reified => .{ .reified = .{6723 .reified => .{ .reified = .{
6660 .zir_index = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),6724 .zir_index = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
6661 .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(),6725 .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(),
...@@ -6663,12 +6727,12 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6663,12 +6727,12 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6663 .generated_union_tag => .{ .generated_union_tag = owner_union: {6727 .generated_union_tag => .{ .generated_union_tag = owner_union: {
6664 break :owner_union @enumFromInt(extra_list.view().items(.@"0")[extra.end]);6728 break :owner_union @enumFromInt(extra_list.view().items(.@"0")[extra.end]);
6665 } },6729 } },
6666 _ => .{ .declared = .{6730 _ => |len| .{ .declared = .{
6667 .zir_index = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),6731 .zir_index = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
6668 .captures = .{ .owned = .{6732 .captures = .{ .owned = .{
6669 .tid = unwrapped_index.tid,6733 .tid = unwrapped_index.tid,
6670 .start = extra.end + 1,6734 .start = extra.end + 1,
6671 .len = @intFromEnum(extra.data.captures_len),6735 .len = @intFromEnum(len),
6672 } },6736 } },
6673 } },6737 } },
6674 };6738 };
...@@ -8138,7 +8202,11 @@ pub fn getDeclaredStructType(...@@ -8138,7 +8202,11 @@ pub fn getDeclaredStructType(
81388202
8139 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{8203 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
8140 .zir_index = ini.zir_index,8204 .zir_index = ini.zir_index,
8141 .captures_len = @enumFromInt(ini.captures.len),8205 .bits = .{
8206 .captures_len = @enumFromInt(ini.captures.len),
8207 .want_layout = false,
8208 .want_defaults = false,
8209 },
8142 .name = undefined, // set by `finish`8210 .name = undefined, // set by `finish`
8143 .name_nav = undefined, // set by `finish`8211 .name_nav = undefined, // set by `finish`
8144 .namespace = undefined, // set by `finish`8212 .namespace = undefined, // set by `finish`
...@@ -8204,6 +8272,8 @@ pub fn getDeclaredStructType(...@@ -8204,6 +8272,8 @@ pub fn getDeclaredStructType(
8204 .comptime_only = false,8272 .comptime_only = false,
8205 .has_runtime_bits = false,8273 .has_runtime_bits = false,
8206 .alignment = .none,8274 .alignment = .none,
8275 .want_layout = false,
8276 .want_defaults = false,
8207 },8277 },
8208 });8278 });
8209 if (ini.captures.len != 0) {8279 if (ini.captures.len != 0) {
...@@ -8281,7 +8351,11 @@ pub fn getReifiedStructType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Pe...@@ -8281,7 +8351,11 @@ pub fn getReifiedStructType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Pe
82818351
8282 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{8352 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
8283 .zir_index = ini.zir_index,8353 .zir_index = ini.zir_index,
8284 .captures_len = .reified,8354 .bits = .{
8355 .captures_len = .reified,
8356 .want_layout = false,
8357 .want_defaults = false,
8358 },
8285 .name = undefined, // set by `finish`8359 .name = undefined, // set by `finish`
8286 .name_nav = undefined, // set by `finish`8360 .name_nav = undefined, // set by `finish`
8287 .namespace = undefined, // set by `finish`8361 .namespace = undefined, // set by `finish`
...@@ -8352,6 +8426,8 @@ pub fn getReifiedStructType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Pe...@@ -8352,6 +8426,8 @@ pub fn getReifiedStructType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Pe
8352 .comptime_only = false,8426 .comptime_only = false,
8353 .has_runtime_bits = false,8427 .has_runtime_bits = false,
8354 .alignment = .none,8428 .alignment = .none,
8429 .want_layout = false,
8430 .want_defaults = false,
8355 },8431 },
8356 });8432 });
8357 _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash)); // type_hash8433 _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash)); // type_hash
...@@ -8451,7 +8527,10 @@ pub fn getDeclaredUnionType(...@@ -8451,7 +8527,10 @@ pub fn getDeclaredUnionType(
84518527
8452 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnionPacked{8528 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnionPacked{
8453 .zir_index = ini.zir_index,8529 .zir_index = ini.zir_index,
8454 .captures_len = @enumFromInt(ini.captures.len),8530 .bits = .{
8531 .captures_len = @enumFromInt(ini.captures.len),
8532 .want_layout = false,
8533 },
8455 .name = undefined, // set by `finish`8534 .name = undefined, // set by `finish`
8456 .name_nav = undefined, // set by `finish`8535 .name_nav = undefined, // set by `finish`
8457 .namespace = undefined, // set by `finish`8536 .namespace = undefined, // set by `finish`
...@@ -8509,6 +8588,7 @@ pub fn getDeclaredUnionType(...@@ -8509,6 +8588,7 @@ pub fn getDeclaredUnionType(
8509 .comptime_only = false,8588 .comptime_only = false,
8510 .has_runtime_bits = false,8589 .has_runtime_bits = false,
8511 .alignment = .none,8590 .alignment = .none,
8591 .want_layout = false,
8512 },8592 },
8513 });8593 });
8514 if (ini.captures.len > 0) {8594 if (ini.captures.len > 0) {
...@@ -8572,7 +8652,10 @@ pub fn getReifiedUnionType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Per...@@ -8572,7 +8652,10 @@ pub fn getReifiedUnionType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Per
85728652
8573 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnionPacked{8653 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnionPacked{
8574 .zir_index = ini.zir_index,8654 .zir_index = ini.zir_index,
8575 .captures_len = .reified,8655 .bits = .{
8656 .captures_len = .reified,
8657 .want_layout = false,
8658 },
8576 .name = undefined, // set by `finish`8659 .name = undefined, // set by `finish`
8577 .name_nav = undefined, // set by `finish`8660 .name_nav = undefined, // set by `finish`
8578 .namespace = undefined, // set by `finish`8661 .namespace = undefined, // set by `finish`
...@@ -8633,6 +8716,7 @@ pub fn getReifiedUnionType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Per...@@ -8633,6 +8716,7 @@ pub fn getReifiedUnionType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Per
8633 .comptime_only = false,8716 .comptime_only = false,
8634 .has_runtime_bits = false,8717 .has_runtime_bits = false,
8635 .alignment = .none,8718 .alignment = .none,
8719 .want_layout = false,
8636 },8720 },
8637 });8721 });
8638 _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash));8722 _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash));
...@@ -8723,7 +8807,10 @@ pub fn getDeclaredEnumType(...@@ -8723,7 +8807,10 @@ pub fn getDeclaredEnumType(
8723 (if (have_values) ini.fields_len else 0)); // field_value8807 (if (have_values) ini.fields_len else 0)); // field_value
87248808
8725 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeEnum{8809 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeEnum{
8726 .captures_len = @enumFromInt(ini.captures.len),8810 .bits = .{
8811 .captures_len = @enumFromInt(ini.captures.len),
8812 .want_layout = false,
8813 },
8727 .name = undefined, // set by `finish`8814 .name = undefined, // set by `finish`
8728 .name_nav = undefined, // set by `finish`8815 .name_nav = undefined, // set by `finish`
8729 .namespace = undefined, // set by `finish`8816 .namespace = undefined, // set by `finish`
...@@ -8795,7 +8882,10 @@ pub fn getReifiedEnumType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerT...@@ -8795,7 +8882,10 @@ pub fn getReifiedEnumType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerT
8795 (if (have_values) ini.fields_len else 0)); // field_value8882 (if (have_values) ini.fields_len else 0)); // field_value
87968883
8797 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeEnum{8884 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeEnum{
8798 .captures_len = .reified,8885 .bits = .{
8886 .captures_len = .reified,
8887 .want_layout = false,
8888 },
8799 .name = undefined, // set by `finish`8889 .name = undefined, // set by `finish`
8800 .name_nav = undefined, // set by `finish`8890 .name_nav = undefined, // set by `finish`
8801 .namespace = undefined, // set by `finish`8891 .namespace = undefined, // set by `finish`
...@@ -8865,7 +8955,10 @@ pub fn getGeneratedEnumTagType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu...@@ -8865,7 +8955,10 @@ pub fn getGeneratedEnumTagType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu
8865 (if (have_values) ini.fields_len else 0)); // field_value8955 (if (have_values) ini.fields_len else 0)); // field_value
88668956
8867 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeEnum{8957 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeEnum{
8868 .captures_len = .generated_union_tag,8958 .bits = .{
8959 .captures_len = .generated_union_tag,
8960 .want_layout = false,
8961 },
8869 .name = undefined, // set by `finish`8962 .name = undefined, // set by `finish`
8870 .name_nav = undefined, // set by `finish`8963 .name_nav = undefined, // set by `finish`
8871 .namespace = undefined, // set by `finish`8964 .namespace = undefined, // set by `finish`
...@@ -9249,7 +9342,7 @@ pub fn getFuncDecl(...@@ -9249,7 +9342,7 @@ pub fn getFuncDecl(
92499342
9250 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{9343 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
9251 .analysis = .{9344 .analysis = .{
9252 .is_analyzed = false,9345 .want_runtime_analysis = false,
9253 .branch_hint = .none,9346 .branch_hint = .none,
9254 .is_noinline = key.is_noinline,9347 .is_noinline = key.is_noinline,
9255 .has_error_trace = false,9348 .has_error_trace = false,
...@@ -9359,7 +9452,7 @@ pub fn getFuncDeclIes(...@@ -9359,7 +9452,7 @@ pub fn getFuncDeclIes(
93599452
9360 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{9453 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
9361 .analysis = .{9454 .analysis = .{
9362 .is_analyzed = false,9455 .want_runtime_analysis = false,
9363 .branch_hint = .none,9456 .branch_hint = .none,
9364 .is_noinline = key.is_noinline,9457 .is_noinline = key.is_noinline,
9365 .has_error_trace = false,9458 .has_error_trace = false,
...@@ -9557,7 +9650,7 @@ pub fn getFuncInstance(...@@ -9557,7 +9650,7 @@ pub fn getFuncInstance(
95579650
9558 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{9651 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
9559 .analysis = .{9652 .analysis = .{
9560 .is_analyzed = false,9653 .want_runtime_analysis = false,
9561 .branch_hint = .none,9654 .branch_hint = .none,
9562 .is_noinline = arg.is_noinline,9655 .is_noinline = arg.is_noinline,
9563 .has_error_trace = false,9656 .has_error_trace = false,
...@@ -9658,7 +9751,7 @@ fn getFuncInstanceIes(...@@ -9658,7 +9751,7 @@ fn getFuncInstanceIes(
96589751
9659 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{9752 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
9660 .analysis = .{9753 .analysis = .{
9661 .is_analyzed = false,9754 .want_runtime_analysis = false,
9662 .branch_hint = .none,9755 .branch_hint = .none,
9663 .is_noinline = arg.is_noinline,9756 .is_noinline = arg.is_noinline,
9664 .has_error_trace = false,9757 .has_error_trace = false,
...@@ -9902,9 +9995,6 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {...@@ -9902,9 +9995,6 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
9902 TrackedInst.Index,9995 TrackedInst.Index,
9903 TrackedInst.Index.Optional,9996 TrackedInst.Index.Optional,
9904 ComptimeAllocIndex,9997 ComptimeAllocIndex,
9905 @FieldType(Tag.TypeStructPacked, "captures_len"),
9906 @FieldType(Tag.TypeUnionPacked, "captures_len"),
9907 @FieldType(Tag.TypeEnum, "captures_len"),
9908 => @intFromEnum(@field(item, field.name)),9998 => @intFromEnum(@field(item, field.name)),
99099999
9910 u32,10000 u32,
...@@ -9916,6 +10006,9 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {...@@ -9916,6 +10006,9 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
9916 Tag.TypePointer.PackedOffset,10006 Tag.TypePointer.PackedOffset,
9917 Tag.TypeUnion.Flags,10007 Tag.TypeUnion.Flags,
9918 Tag.TypeStruct.Flags,10008 Tag.TypeStruct.Flags,
10009 Tag.TypeStructPacked.Bits,
10010 Tag.TypeUnionPacked.Bits,
10011 Tag.TypeEnum.Bits,
9919 => @bitCast(@field(item, field.name)),10012 => @bitCast(@field(item, field.name)),
992010013
9921 else => @compileError("bad field type: " ++ @typeName(field.type)),10014 else => @compileError("bad field type: " ++ @typeName(field.type)),
...@@ -9967,9 +10060,6 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat...@@ -9967,9 +10060,6 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
9967 TrackedInst.Index,10060 TrackedInst.Index,
9968 TrackedInst.Index.Optional,10061 TrackedInst.Index.Optional,
9969 ComptimeAllocIndex,10062 ComptimeAllocIndex,
9970 @FieldType(Tag.TypeStructPacked, "captures_len"),
9971 @FieldType(Tag.TypeUnionPacked, "captures_len"),
9972 @FieldType(Tag.TypeEnum, "captures_len"),
9973 => @enumFromInt(extra_item),10063 => @enumFromInt(extra_item),
997410064
9975 u32,10065 u32,
...@@ -9981,6 +10071,9 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat...@@ -9981,6 +10071,9 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
9981 Tag.TypeUnion.Flags,10071 Tag.TypeUnion.Flags,
9982 Tag.TypeStruct.Flags,10072 Tag.TypeStruct.Flags,
9983 FuncAnalysis,10073 FuncAnalysis,
10074 Tag.TypeStructPacked.Bits,
10075 Tag.TypeUnionPacked.Bits,
10076 Tag.TypeEnum.Bits,
9984 => @bitCast(extra_item),10077 => @bitCast(extra_item),
998510078
9986 else => @compileError("bad field type: " ++ @typeName(field.type)),10079 else => @compileError("bad field type: " ++ @typeName(field.type)),
...@@ -10750,7 +10843,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -10750,7 +10843,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
10750 .type_struct_packed_auto, .type_struct_packed_explicit => b: {10843 .type_struct_packed_auto, .type_struct_packed_explicit => b: {
10751 var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".fields.len;10844 var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".fields.len;
10752 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);10845 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
10753 switch (extra.data.captures_len) {10846 switch (extra.data.bits.captures_len) {
10754 .reified => n += 2, // type_hash: PackedU6410847 .reified => n += 2, // type_hash: PackedU64
10755 _ => |len| n += @intFromEnum(len), // capture: CaptureValue10848 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
10756 }10849 }
...@@ -10761,7 +10854,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -10761,7 +10854,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
10761 .type_struct_packed_auto_defaults, .type_struct_packed_explicit_defaults => b: {10854 .type_struct_packed_auto_defaults, .type_struct_packed_explicit_defaults => b: {
10762 var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".fields.len;10855 var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".fields.len;
10763 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);10856 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
10764 switch (extra.data.captures_len) {10857 switch (extra.data.bits.captures_len) {
10765 .reified => n += 2, // type_hash: PackedU6410858 .reified => n += 2, // type_hash: PackedU64
10766 _ => |len| n += @intFromEnum(len), // capture: CaptureValue10859 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
10767 }10860 }
...@@ -10790,7 +10883,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -10790,7 +10883,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
10790 .type_union_packed_auto, .type_union_packed_explicit => b: {10883 .type_union_packed_auto, .type_union_packed_explicit => b: {
10791 var n: usize = @typeInfo(Tag.TypeUnionPacked).@"struct".fields.len;10884 var n: usize = @typeInfo(Tag.TypeUnionPacked).@"struct".fields.len;
10792 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, data);10885 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, data);
10793 switch (extra.data.captures_len) {10886 switch (extra.data.bits.captures_len) {
10794 .reified => n += 2, // type_hash: PackedU6410887 .reified => n += 2, // type_hash: PackedU64
10795 _ => |len| n += @intFromEnum(len), // capture: CaptureValue10888 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
10796 }10889 }
...@@ -10800,7 +10893,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -10800,7 +10893,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
10800 .type_enum_auto => b: {10893 .type_enum_auto => b: {
10801 var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len;10894 var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len;
10802 const extra = extraData(extra_list, Tag.TypeEnum, data);10895 const extra = extraData(extra_list, Tag.TypeEnum, data);
10803 switch (extra.captures_len) {10896 switch (extra.bits.captures_len) {
10804 .generated_union_tag => n += 1, // owner_union: Index10897 .generated_union_tag => n += 1, // owner_union: Index
10805 .reified => {10898 .reified => {
10806 n += 1; // zir_index: TrackedInst.Index,10899 n += 1; // zir_index: TrackedInst.Index,
...@@ -10817,7 +10910,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo...@@ -10817,7 +10910,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
10817 .type_enum_explicit, .type_enum_nonexhaustive => b: {10910 .type_enum_explicit, .type_enum_nonexhaustive => b: {
10818 var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len;10911 var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len;
10819 const extra = extraData(extra_list, Tag.TypeEnum, data);10912 const extra = extraData(extra_list, Tag.TypeEnum, data);
10820 switch (extra.captures_len) {10913 switch (extra.bits.captures_len) {
10821 .generated_union_tag => n += 1, // owner_union: Index10914 .generated_union_tag => n += 1, // owner_union: Index
10822 .reified => {10915 .reified => {
10823 n += 1; // zir_index: TrackedInst.Index,10916 n += 1; // zir_index: TrackedInst.Index,
...@@ -11204,6 +11297,7 @@ pub fn createDeclNav(...@@ -11204,6 +11297,7 @@ pub fn createDeclNav(
11204 .analysis = .{11297 .analysis = .{
11205 .namespace = namespace,11298 .namespace = namespace,
11206 .zir_index = zir_index,11299 .zir_index = zir_index,
11300 .wanted = false,
11207 },11301 },
11208 .status = .unresolved,11302 .status = .unresolved,
11209 }));11303 }));
...@@ -12829,3 +12923,175 @@ pub fn resolveEnumLayout(...@@ -12829,3 +12923,175 @@ pub fn resolveEnumLayout(
1282912923
12830 extra_items[item.data + std.meta.fieldIndex(Tag.TypeEnum, "int_tag_type").?] = @intFromEnum(int_tag_type);12924 extra_items[item.data + std.meta.fieldIndex(Tag.TypeEnum, "int_tag_type").?] = @intFromEnum(int_tag_type);
12831}12925}
12926
12927/// Sets the "want_layout" flag on the given struct, union, or enum type. Returns true if the flag
12928/// was *not* already set, meaning we have just discovered the first reference to this type's
12929/// layout. This flag is never reset to false, and exists purely as an optimization; for details,
12930/// see doc comments in `LoadedStructType`.
12931pub fn setWantTypeLayout(ip: *InternPool, io: Io, container_type: Index) bool {
12932 const unwrapped_index = container_type.unwrap(ip);
12933
12934 const local = ip.getLocal(unwrapped_index.tid);
12935 local.mutate.extra.mutex.lockUncancelable(io);
12936 defer local.mutate.extra.mutex.unlock(io);
12937
12938 const extra_items = local.shared.extra.view().items(.@"0");
12939 const item = unwrapped_index.getItem(ip);
12940 switch (item.tag) {
12941 .type_struct_packed_auto,
12942 .type_struct_packed_explicit,
12943 .type_struct_packed_auto_defaults,
12944 .type_struct_packed_explicit_defaults,
12945 => {
12946 const bits: *Tag.TypeStructPacked.Bits = @ptrCast(&extra_items[
12947 item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "bits").?
12948 ]);
12949 if (bits.want_layout) {
12950 return false;
12951 } else {
12952 bits.want_layout = true;
12953 return true;
12954 }
12955 },
12956
12957 .type_struct => {
12958 const flags: *Tag.TypeStruct.Flags = @ptrCast(&extra_items[
12959 item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?
12960 ]);
12961 if (flags.want_layout) {
12962 return false;
12963 } else {
12964 flags.want_layout = true;
12965 return true;
12966 }
12967 },
12968
12969 .type_union_packed_auto,
12970 .type_union_packed_explicit,
12971 => {
12972 const bits: *Tag.TypeUnionPacked.Bits = @ptrCast(&extra_items[
12973 item.data + std.meta.fieldIndex(Tag.TypeUnionPacked, "bits").?
12974 ]);
12975 if (bits.want_layout) {
12976 return false;
12977 } else {
12978 bits.want_layout = true;
12979 return true;
12980 }
12981 },
12982
12983 .type_union => {
12984 const flags: *Tag.TypeUnion.Flags = @ptrCast(&extra_items[
12985 item.data + std.meta.fieldIndex(Tag.TypeUnion, "flags").?
12986 ]);
12987 if (flags.want_layout) {
12988 return false;
12989 } else {
12990 flags.want_layout = true;
12991 return true;
12992 }
12993 },
12994
12995 .type_enum_auto,
12996 .type_enum_explicit,
12997 .type_enum_nonexhaustive,
12998 => {
12999 const bits: *Tag.TypeEnum.Bits = @ptrCast(&extra_items[
13000 item.data + std.meta.fieldIndex(Tag.TypeEnum, "bits").?
13001 ]);
13002 if (bits.want_layout) {
13003 return false;
13004 } else {
13005 bits.want_layout = true;
13006 return true;
13007 }
13008 },
13009
13010 else => unreachable,
13011 }
13012}
13013
13014/// Like `setWantTypeLayout`, but for the default field values of a struct (so this sets the
13015/// `want_defaults` flag rather than the `want_layout` flag).
13016pub fn setWantStructDefaults(ip: *InternPool, io: Io, struct_type: Index) bool {
13017 const unwrapped_index = struct_type.unwrap(ip);
13018
13019 const local = ip.getLocal(unwrapped_index.tid);
13020 local.mutate.extra.mutex.lockUncancelable(io);
13021 defer local.mutate.extra.mutex.unlock(io);
13022
13023 const extra_items = local.shared.extra.view().items(.@"0");
13024 const item = unwrapped_index.getItem(ip);
13025 switch (item.tag) {
13026 .type_struct_packed_auto,
13027 .type_struct_packed_explicit,
13028 .type_struct_packed_auto_defaults,
13029 .type_struct_packed_explicit_defaults,
13030 => {
13031 const bits: *Tag.TypeStructPacked.Bits = @ptrCast(&extra_items[
13032 item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "bits").?
13033 ]);
13034 if (bits.want_defaults) {
13035 return false;
13036 } else {
13037 bits.want_defaults = true;
13038 return true;
13039 }
13040 },
13041
13042 .type_struct => {
13043 const flags: *Tag.TypeStruct.Flags = @ptrCast(&extra_items[
13044 item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?
13045 ]);
13046 if (flags.want_defaults) {
13047 return false;
13048 } else {
13049 flags.want_defaults = true;
13050 return true;
13051 }
13052 },
13053
13054 else => unreachable,
13055 }
13056}
13057
13058/// Like `setWantTypeLayout`, but for runtime analysis of a function body, using the
13059/// `FuncAnalysis.want_runtime_analysis` flag.
13060pub fn setWantRuntimeFnAnalysis(ip: *InternPool, io: Io, func_index: Index) bool {
13061 const unwrapped_index = func_index.unwrap(ip);
13062
13063 const local = ip.getLocal(unwrapped_index.tid);
13064 local.mutate.extra.mutex.lockUncancelable(io);
13065 defer local.mutate.extra.mutex.unlock(io);
13066
13067 const a = funcAnalysisPtr(ip, func_index);
13068 if (a.want_runtime_analysis) {
13069 return false;
13070 } else {
13071 a.want_runtime_analysis = true;
13072 return true;
13073 }
13074}
13075
13076/// Like `setWantTypeLayout`, but for runtime analysis of a `Nav`, using the `Nav.analysis.wanted` flag.
13077pub fn setWantNavAnalysis(ip: *InternPool, io: Io, nav_index: Nav.Index) bool {
13078 const unwrapped = nav_index.unwrap(ip);
13079
13080 const local = ip.getLocal(unwrapped.tid);
13081 local.mutate.extra.mutex.lockUncancelable(io);
13082 defer local.mutate.extra.mutex.unlock(io);
13083
13084 const navs = local.shared.navs.view();
13085
13086 if (navs.items(.analysis_namespace)[unwrapped.index] == .none) {
13087 return false;
13088 }
13089
13090 const bits = &navs.items(.bits)[unwrapped.index];
13091 if (bits.want_analysis) {
13092 return false;
13093 } else {
13094 bits.want_analysis = true;
13095 return true;
13096 }
13097}
src/Sema.zig+72-132
...@@ -3258,7 +3258,7 @@ fn zirAllocExtended(...@@ -3258,7 +3258,7 @@ fn zirAllocExtended(
3258 } else .none;3258 } else .none;
32593259
3260 if (small.has_type) {3260 if (small.has_type) {
3261 try sema.ensureLayoutResolved(var_ty);3261 try sema.ensureLayoutResolved(var_ty, ty_src);
3262 if (block.isComptime() or small.is_comptime or var_ty.comptimeOnly(zcu)) {3262 if (block.isComptime() or small.is_comptime or var_ty.comptimeOnly(zcu)) {
3263 return sema.analyzeComptimeAlloc(block, var_src, var_ty, alignment);3263 return sema.analyzeComptimeAlloc(block, var_src, var_ty, alignment);
3264 }3264 }
...@@ -3322,7 +3322,7 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -3322,7 +3322,7 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
3322 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });3322 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
3323 const var_src = block.nodeOffset(inst_data.src_node);3323 const var_src = block.nodeOffset(inst_data.src_node);
3324 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);3324 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3325 try sema.ensureLayoutResolved(var_ty);3325 try sema.ensureLayoutResolved(var_ty, ty_src);
3326 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);3326 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
3327}3327}
33283328
...@@ -3743,7 +3743,7 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -3743,7 +3743,7 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
3743 const var_src = block.nodeOffset(inst_data.src_node);3743 const var_src = block.nodeOffset(inst_data.src_node);
37443744
3745 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);3745 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3746 try sema.ensureLayoutResolved(var_ty);3746 try sema.ensureLayoutResolved(var_ty, ty_src);
3747 if (block.isComptime() or var_ty.comptimeOnly(zcu)) {3747 if (block.isComptime() or var_ty.comptimeOnly(zcu)) {
3748 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);3748 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
3749 }3749 }
...@@ -3775,7 +3775,7 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -3775,7 +3775,7 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
3775 const var_src = block.nodeOffset(inst_data.src_node);3775 const var_src = block.nodeOffset(inst_data.src_node);
37763776
3777 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);3777 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3778 try sema.ensureLayoutResolved(var_ty);3778 try sema.ensureLayoutResolved(var_ty, ty_src);
3779 if (block.isComptime()) {3779 if (block.isComptime()) {
3780 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);3780 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
3781 }3781 }
...@@ -4132,8 +4132,9 @@ fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcL...@@ -4132,8 +4132,9 @@ fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcL
4132fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4132fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
4133 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;4133 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4134 const ptr = sema.resolveInst(un_node.operand);4134 const ptr = sema.resolveInst(un_node.operand);
4135 try sema.ensureLayoutResolved(sema.typeOf(ptr).childType(sema.pt.zcu));4135 const src = block.nodeOffset(un_node.src_node);
4136 return sema.optEuBasePtrInit(block, ptr, block.nodeOffset(un_node.src_node));4136 try sema.ensureLayoutResolved(sema.typeOf(ptr).childType(sema.pt.zcu), src);
4137 return sema.optEuBasePtrInit(block, ptr, src);
4137}4138}
41384139
4139fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4140fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -4518,7 +4519,7 @@ fn validateStructInit(...@@ -4518,7 +4519,7 @@ fn validateStructInit(
4518 if (struct_ty.structFieldIsComptime(i, zcu)) continue;4519 if (struct_ty.structFieldIsComptime(i, zcu)) continue;
45194520
4520 if (!struct_ty.isTuple(zcu)) {4521 if (!struct_ty.isTuple(zcu)) {
4521 try sema.ensureStructDefaultsResolved(struct_ty);4522 try sema.ensureStructDefaultsResolved(struct_ty, init_src);
4522 }4523 }
45234524
4524 const default_val = struct_ty.structFieldDefaultValue(i, zcu) orelse {4525 const default_val = struct_ty.structFieldDefaultValue(i, zcu) orelse {
...@@ -4642,7 +4643,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -4642,7 +4643,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
4642 }4643 }
46434644
4644 const elem_ty = operand_ty.childType(zcu);4645 const elem_ty = operand_ty.childType(zcu);
4645 try sema.ensureLayoutResolved(elem_ty);4646 try sema.ensureLayoutResolved(elem_ty, src);
46464647
4647 if (try elem_ty.onePossibleValue(pt) != null) {4648 if (try elem_ty.onePossibleValue(pt) != null) {
4648 // No need to validate the actual pointer value, we don't need it!4649 // No need to validate the actual pointer value, we don't need it!
...@@ -7025,7 +7026,7 @@ fn analyzeCall(...@@ -7025,7 +7026,7 @@ fn analyzeCall(
70257026
7026 break :ret_ty full_ty;7027 break :ret_ty full_ty;
7027 };7028 };
7028 try sema.ensureLayoutResolved(resolved_ret_ty);7029 try sema.ensureLayoutResolved(resolved_ret_ty, func_ret_ty_src);
70297030
7030 // If we've discovered after evaluating arguments that a generic function instantiation is7031 // If we've discovered after evaluating arguments that a generic function instantiation is
7031 // comptime-only, then we can mark the block as comptime *now*.7032 // comptime-only, then we can mark the block as comptime *now*.
...@@ -7122,7 +7123,7 @@ fn analyzeCall(...@@ -7122,7 +7123,7 @@ fn analyzeCall(
7122 .generic_owner = func_val.?.toIntern(),7123 .generic_owner = func_val.?.toIntern(),
7123 .comptime_args = comptime_args,7124 .comptime_args = comptime_args,
7124 });7125 });
7125 try sema.ensureLayoutResolved(.fromInterned(ip.typeOf(func_instance)));7126 try sema.ensureLayoutResolved(.fromInterned(ip.typeOf(func_instance)), call_src);
7126 if (zcu.comp.debugIncremental()) {7127 if (zcu.comp.debugIncremental()) {
7127 const nav = ip.indexToKey(func_instance).func.owner_nav;7128 const nav = ip.indexToKey(func_instance).func.owner_nav;
7128 const gop = try zcu.incremental_debug_state.navs.getOrPut(gpa, nav);7129 const gop = try zcu.incremental_debug_state.navs.getOrPut(gpa, nav);
...@@ -7196,7 +7197,7 @@ fn analyzeCall(...@@ -7196,7 +7197,7 @@ fn analyzeCall(
7196 return .unreachable_value;7197 return .unreachable_value;
7197 }7198 }
71987199
7199 try sema.ensureLayoutResolved(sema.typeOf(maybe_opv));7200 try sema.ensureLayoutResolved(sema.typeOf(maybe_opv), func_ret_ty_src);
7200 if (try sema.typeOf(maybe_opv).onePossibleValue(pt)) |opv| {7201 if (try sema.typeOf(maybe_opv).onePossibleValue(pt)) |opv| {
7201 return .fromValue(opv);7202 return .fromValue(opv);
7202 } else {7203 } else {
...@@ -7270,7 +7271,7 @@ fn analyzeCall(...@@ -7270,7 +7271,7 @@ fn analyzeCall(
7270 // We're about to do an inline call; if the return type expression was generic, the return type7271 // We're about to do an inline call; if the return type expression was generic, the return type
7271 // may not be resolved yet. It's correct to resolve it because the function is going to return a7272 // may not be resolved yet. It's correct to resolve it because the function is going to return a
7272 // value of this type.7273 // value of this type.
7273 try sema.ensureLayoutResolved(resolved_ret_ty);7274 try sema.ensureLayoutResolved(resolved_ret_ty, func_ret_ty_src);
72747275
7275 // For an inline call, we depend on the source code of the whole function definition.7276 // For an inline call, we depend on the source code of the whole function definition.
7276 try sema.declareDependency(.{ .src_hash = fn_nav.analysis.?.zir_index });7277 try sema.declareDependency(.{ .src_hash = fn_nav.analysis.?.zir_index });
...@@ -7532,7 +7533,6 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -7532,7 +7533,6 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
7532 const zcu = pt.zcu;7533 const zcu = pt.zcu;
7533 const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;7534 const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;
7534 const maybe_wrapped_indexable_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, bin.lhs) orelse return .generic_poison_type;7535 const maybe_wrapped_indexable_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, bin.lhs) orelse return .generic_poison_type;
7535 try sema.ensureLayoutResolved(maybe_wrapped_indexable_ty);
7536 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(zcu);7536 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(zcu);
7537 assert(indexable_ty.isIndexable(zcu)); // validated by a previous instruction7537 assert(indexable_ty.isIndexable(zcu)); // validated by a previous instruction
7538 const elem_ty = switch (indexable_ty.zigTypeTag(zcu)) {7538 const elem_ty = switch (indexable_ty.zigTypeTag(zcu)) {
...@@ -8040,7 +8040,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8040,7 +8040,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8040 if (dest_ty.zigTypeTag(zcu) != .@"enum") {8040 if (dest_ty.zigTypeTag(zcu) != .@"enum") {
8041 return sema.fail(block, src, "expected enum, found '{f}'", .{dest_ty.fmt(pt)});8041 return sema.fail(block, src, "expected enum, found '{f}'", .{dest_ty.fmt(pt)});
8042 }8042 }
8043 try sema.ensureLayoutResolved(dest_ty);8043 try sema.ensureLayoutResolved(dest_ty, src);
8044 _ = try sema.checkIntType(block, operand_src, operand_ty);8044 _ = try sema.checkIntType(block, operand_src, operand_ty);
80458045
8046 if (sema.resolveValue(operand)) |int_val| {8046 if (sema.resolveValue(operand)) |int_val| {
...@@ -8103,7 +8103,7 @@ fn zirOptionalPayloadPtr(...@@ -8103,7 +8103,7 @@ fn zirOptionalPayloadPtr(
81038103
8104 const ptr_ty = sema.typeOf(optional_ptr);8104 const ptr_ty = sema.typeOf(optional_ptr);
8105 assert(ptr_ty.zigTypeTag(sema.pt.zcu) == .pointer);8105 assert(ptr_ty.zigTypeTag(sema.pt.zcu) == .pointer);
8106 try sema.ensureLayoutResolved(ptr_ty.childType(sema.pt.zcu));8106 try sema.ensureLayoutResolved(ptr_ty.childType(sema.pt.zcu), src);
81078107
8108 return sema.analyzeOptionalPayloadPtr(block, src, optional_ptr, safety_check, false);8108 return sema.analyzeOptionalPayloadPtr(block, src, optional_ptr, safety_check, false);
8109}8109}
...@@ -8313,7 +8313,7 @@ fn zirErrUnionPayloadPtr(...@@ -8313,7 +8313,7 @@ fn zirErrUnionPayloadPtr(
83138313
8314 const ptr_ty = sema.typeOf(operand);8314 const ptr_ty = sema.typeOf(operand);
8315 assert(ptr_ty.zigTypeTag(sema.pt.zcu) == .pointer);8315 assert(ptr_ty.zigTypeTag(sema.pt.zcu) == .pointer);
8316 try sema.ensureLayoutResolved(ptr_ty.childType(sema.pt.zcu));8316 try sema.ensureLayoutResolved(ptr_ty.childType(sema.pt.zcu), src);
83178317
8318 return sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);8318 return sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
8319}8319}
...@@ -9022,6 +9022,7 @@ fn funcCommon(...@@ -9022,6 +9022,7 @@ fn funcCommon(
9022 const io = comp.io;9022 const io = comp.io;
9023 const ip = &zcu.intern_pool;9023 const ip = &zcu.intern_pool;
90249024
9025 const src = block.nodeOffset(src_node_offset);
9025 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });9026 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });
9026 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });9027 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });
90279028
...@@ -9091,7 +9092,7 @@ fn funcCommon(...@@ -9091,7 +9092,7 @@ fn funcCommon(
9091 .lbrace_column = @as(u16, @truncate(src_locs.columns)),9092 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
9092 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),9093 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
9093 }));9094 }));
9094 try sema.ensureLayoutResolved(func_val.typeOf(zcu));9095 try sema.ensureLayoutResolved(func_val.typeOf(zcu), src);
9095 return .fromValue(func_val);9096 return .fromValue(func_val);
9096 }9097 }
90979098
...@@ -9106,7 +9107,7 @@ fn funcCommon(...@@ -9106,7 +9107,7 @@ fn funcCommon(
9106 });9107 });
91079108
9108 if (has_body) {9109 if (has_body) {
9109 try sema.ensureLayoutResolved(.fromInterned(func_ty));9110 try sema.ensureLayoutResolved(.fromInterned(func_ty), src);
9110 return .fromIntern(try ip.getFuncDecl(gpa, io, pt.tid, .{9111 return .fromIntern(try ip.getFuncDecl(gpa, io, pt.tid, .{
9111 .owner_nav = sema.owner.unwrap().nav_val,9112 .owner_nav = sema.owner.unwrap().nav_val,
9112 .ty = func_ty,9113 .ty = func_ty,
...@@ -9762,7 +9763,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9762,7 +9763,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9762 return sema.failWithOwnedErrorMsg(block, msg);9763 return sema.failWithOwnedErrorMsg(block, msg);
9763 }9764 }
9764 try sema.checkIndexable(block, src, indexable_ty);9765 try sema.checkIndexable(block, src, indexable_ty);
9765 try sema.ensureLayoutResolved(indexable_ty.childType(zcu));9766 try sema.ensureLayoutResolved(indexable_ty.childType(zcu), src);
9766 return sema.elemPtrOneLayerOnly(block, src, array_ptr, elem_index, src, false, false);9767 return sema.elemPtrOneLayerOnly(block, src, array_ptr, elem_index, src, false, false);
9767}9768}
97689769
...@@ -9983,7 +9984,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -9983,7 +9984,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
9983 err_union_ty.fmt(pt),9984 err_union_ty.fmt(pt),
9984 });9985 });
9985 }9986 }
9986 try sema.ensureLayoutResolved(err_union_ty);9987 try sema.ensureLayoutResolved(err_union_ty, operand_src);
99879988
9988 const non_err_cond = if (non_err_case.operand_is_ref)9989 const non_err_cond = if (non_err_case.operand_is_ref)
9989 try sema.analyzePtrIsNonErr(block, operand_src, eu_maybe_ptr)9990 try sema.analyzePtrIsNonErr(block, operand_src, eu_maybe_ptr)
...@@ -11287,7 +11288,7 @@ fn validateSwitchBlock(...@@ -11287,7 +11288,7 @@ fn validateSwitchBlock(
11287 }11288 }
11288 break :operand_ty raw_operand_ty;11289 break :operand_ty raw_operand_ty;
11289 };11290 };
11290 try sema.ensureLayoutResolved(operand_ty);11291 try sema.ensureLayoutResolved(operand_ty, operand_src);
1129111292
11292 const item_ty: Type = item_ty: {11293 const item_ty: Type = item_ty: {
11293 switch (operand_ty.zigTypeTag(zcu)) {11294 switch (operand_ty.zigTypeTag(zcu)) {
...@@ -12870,7 +12871,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12870,7 +12871,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12870 const name_src = block.builtinCallArgSrc(inst_data.src_node, 1);12871 const name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
12871 const ty = try sema.resolveType(block, ty_src, extra.lhs);12872 const ty = try sema.resolveType(block, ty_src, extra.lhs);
12872 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{ .simple = .field_name });12873 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{ .simple = .field_name });
12873 try sema.ensureLayoutResolved(ty);12874 try sema.ensureLayoutResolved(ty, ty_src);
12874 const ip = &zcu.intern_pool;12875 const ip = &zcu.intern_pool;
1287512876
12876 const has_field = hf: {12877 const has_field = hf: {
...@@ -15270,7 +15271,7 @@ fn analyzeArithmetic(...@@ -15270,7 +15271,7 @@ fn analyzeArithmetic(
15270 else => return sema.failWithInvalidPtrArithmetic(block, src, "pointer-integer", "addition and subtraction"),15271 else => return sema.failWithInvalidPtrArithmetic(block, src, "pointer-integer", "addition and subtraction"),
15271 };15272 };
1527215273
15273 try sema.ensureLayoutResolved(lhs_ty.childType(zcu));15274 try sema.ensureLayoutResolved(lhs_ty.childType(zcu), src);
15274 return sema.analyzePtrArithmetic(block, src, lhs, rhs, air_tag, lhs_src, rhs_src);15275 return sema.analyzePtrArithmetic(block, src, lhs, rhs, air_tag, lhs_src, rhs_src);
15275 },15276 },
15276 }15277 }
...@@ -15964,7 +15965,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15964,7 +15965,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15964 .@"anyframe",15965 .@"anyframe",
15965 => {},15966 => {},
15966 }15967 }
15967 try sema.ensureLayoutResolved(ty);15968 try sema.ensureLayoutResolved(ty, operand_src);
15968 return .fromValue(try pt.intValue(.comptime_int, ty.abiSize(zcu)));15969 return .fromValue(try pt.intValue(.comptime_int, ty.abiSize(zcu)));
15969}15970}
1597015971
...@@ -16005,7 +16006,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -16005,7 +16006,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
16005 .@"anyframe",16006 .@"anyframe",
16006 => {},16007 => {},
16007 }16008 }
16008 try sema.ensureLayoutResolved(operand_ty);16009 try sema.ensureLayoutResolved(operand_ty, operand_src);
16009 return .fromValue(try pt.intValue(.comptime_int, operand_ty.bitSize(zcu)));16010 return .fromValue(try pt.intValue(.comptime_int, operand_ty.bitSize(zcu)));
16010}16011}
1601116012
...@@ -16251,7 +16252,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16251,7 +16252,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16251 const type_info_ty = try sema.getBuiltinType(src, .Type);16252 const type_info_ty = try sema.getBuiltinType(src, .Type);
16252 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;16253 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;
1625316254
16254 try sema.ensureLayoutResolved(ty);16255 try sema.ensureLayoutResolved(ty, src);
1625516256
16256 if (ty.typeDeclInst(zcu)) |type_decl_inst| {16257 if (ty.typeDeclInst(zcu)) |type_decl_inst| {
16257 try sema.declareDependency(.{ .namespace = type_decl_inst });16258 try sema.declareDependency(.{ .namespace = type_decl_inst });
...@@ -16412,7 +16413,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16412,7 +16413,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16412 if (info.flags.alignment.toByteUnits()) |b| break :bytes b;16413 if (info.flags.alignment.toByteUnits()) |b| break :bytes b;
16413 const elem_ty: Type = .fromInterned(info.child);16414 const elem_ty: Type = .fromInterned(info.child);
16414 // MLUGG TODO: this resolution is sus, but i doubt i'll solve it in this branch16415 // MLUGG TODO: this resolution is sus, but i doubt i'll solve it in this branch
16415 try sema.ensureLayoutResolved(elem_ty);16416 try sema.ensureLayoutResolved(elem_ty, src);
16416 break :bytes elem_ty.abiAlignment(zcu).toByteUnits().?;16417 break :bytes elem_ty.abiAlignment(zcu).toByteUnits().?;
16417 });16418 });
1641816419
...@@ -16873,7 +16874,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16873,7 +16874,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16873 .struct_type => ip.loadStructType(ty.toIntern()),16874 .struct_type => ip.loadStructType(ty.toIntern()),
16874 else => unreachable,16875 else => unreachable,
16875 };16876 };
16876 try sema.ensureStructDefaultsResolved(ty); // can't do this sooner, since it's not allowed on tuples16877 try sema.ensureStructDefaultsResolved(ty, src); // can't do this sooner, since it's not allowed on tuples
16877 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);16878 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);
1687816879
16879 for (struct_field_vals, 0..) |*field_val, field_index| {16880 for (struct_field_vals, 0..) |*field_val, field_index| {
...@@ -18294,7 +18295,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18294,7 +18295,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18294 elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size,18295 elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size,
18295 });18296 });
18296 }18297 }
18297 try sema.ensureLayoutResolved(elem_ty);18298 try sema.ensureLayoutResolved(elem_ty, elem_ty_src);
18298 const elem_bit_size = elem_ty.bitSize(zcu);18299 const elem_bit_size = elem_ty.bitSize(zcu);
18299 if (elem_bit_size > host_size * 8 - bit_offset) {18300 if (elem_bit_size > host_size * 8 - bit_offset) {
18300 return sema.fail(block, bitoffset_src, "packed type '{f}' at bit offset {d} ends {d} bits after the end of a {d} byte host integer", .{18301 return sema.fail(block, bitoffset_src, "packed type '{f}' at bit offset {d} ends {d} bits after the end of a {d} byte host integer", .{
...@@ -18363,7 +18364,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -18363,7 +18364,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
18363 const pt = sema.pt;18364 const pt = sema.pt;
18364 const zcu = pt.zcu;18365 const zcu = pt.zcu;
1836518366
18366 try sema.ensureLayoutResolved(obj_ty);18367 try sema.ensureLayoutResolved(obj_ty, ty_src);
1836718368
18368 switch (obj_ty.zigTypeTag(zcu)) {18369 switch (obj_ty.zigTypeTag(zcu)) {
18369 .@"struct" => return sema.structInitEmpty(block, obj_ty, src, src),18370 .@"struct" => return sema.structInitEmpty(block, obj_ty, src, src),
...@@ -18428,7 +18429,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is...@@ -18428,7 +18429,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
18428 });18429 });
18429 } else ty_operand;18430 } else ty_operand;
1843018431
18431 try sema.ensureLayoutResolved(init_ty);18432 try sema.ensureLayoutResolved(init_ty, src);
1843218433
18433 const obj_ty = init_ty.optEuBaseType(zcu);18434 const obj_ty = init_ty.optEuBaseType(zcu);
1843418435
...@@ -18544,7 +18545,7 @@ fn zirStructInit(...@@ -18544,7 +18545,7 @@ fn zirStructInit(
18544 // The type wasn't actually known, so treat this as an anon struct init.18545 // The type wasn't actually known, so treat this as an anon struct init.
18545 return sema.structInitAnon(block, src, inst, .typed_init, extra.data, extra.end, is_ref);18546 return sema.structInitAnon(block, src, inst, .typed_init, extra.data, extra.end, is_ref);
18546 };18547 };
18547 try sema.ensureLayoutResolved(result_ty);18548 try sema.ensureLayoutResolved(result_ty, src);
18548 const resolved_ty = result_ty.optEuBaseType(zcu);18549 const resolved_ty = result_ty.optEuBaseType(zcu);
1854918550
18550 if (resolved_ty.zigTypeTag(zcu) == .@"struct") {18551 if (resolved_ty.zigTypeTag(zcu) == .@"struct") {
...@@ -18751,7 +18752,7 @@ fn finishStructInit(...@@ -18751,7 +18752,7 @@ fn finishStructInit(
18751 continue;18752 continue;
18752 }18753 }
1875318754
18754 try sema.ensureStructDefaultsResolved(struct_ty);18755 try sema.ensureStructDefaultsResolved(struct_ty, init_src);
1875518756
18756 const field_default: InternPool.Index = d: {18757 const field_default: InternPool.Index = d: {
18757 if (struct_type.field_defaults.len == 0) break :d .none;18758 if (struct_type.field_defaults.len == 0) break :d .none;
...@@ -18979,17 +18980,11 @@ fn structInitAnon(...@@ -18979,17 +18980,11 @@ fn structInitAnon(
18979 });18980 });
18980 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);18981 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
1898118982
18982 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
18983 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
18984 errdefer comptime unreachable; // because we don't remove the `outdated` entries
18985 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), 0);
18986 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), {});
18987
18988 break :ty .fromInterned(wip.finish(ip, new_namespace_index));18983 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
18989 },18984 },
18990 };18985 };
18991 try sema.addTypeReferenceEntry(src, struct_ty);18986 try sema.addTypeReferenceEntry(src, struct_ty);
18992 try sema.ensureLayoutResolved(struct_ty);18987 try sema.ensureLayoutResolved(struct_ty, src);
1899318988
18994 _ = opt_runtime_index orelse {18989 _ = opt_runtime_index orelse {
18995 const struct_val = try pt.aggregateValue(struct_ty, values);18990 const struct_val = try pt.aggregateValue(struct_ty, values);
...@@ -19308,7 +19303,7 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -19308,7 +19303,7 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
19308 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);19303 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);
19309 const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);19304 const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);
19310 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ .simple = .field_name });19305 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ .simple = .field_name });
19311 try sema.ensureLayoutResolved(aggregate_ty);19306 try sema.ensureLayoutResolved(aggregate_ty, ty_src);
19312 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);19307 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);
19313}19308}
1931419309
...@@ -19328,7 +19323,7 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -19328,7 +19323,7 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
19328 const aggregate_ty = wrapped_aggregate_ty.optEuBaseType(zcu);19323 const aggregate_ty = wrapped_aggregate_ty.optEuBaseType(zcu);
19329 const zir_field_name = sema.code.nullTerminatedString(extra.name_start);19324 const zir_field_name = sema.code.nullTerminatedString(extra.name_start);
19330 const field_name = try ip.getOrPutString(gpa, io, pt.tid, zir_field_name, .no_embedded_nulls);19325 const field_name = try ip.getOrPutString(gpa, io, pt.tid, zir_field_name, .no_embedded_nulls);
19331 try sema.ensureLayoutResolved(aggregate_ty);19326 try sema.ensureLayoutResolved(aggregate_ty, ty_src);
19332 return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);19327 return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);
19333}19328}
1933419329
...@@ -19431,7 +19426,7 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19431,7 +19426,7 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19431 if (ty.isNoReturn(zcu)) {19426 if (ty.isNoReturn(zcu)) {
19432 return sema.fail(block, operand_src, "no align available for type '{f}'", .{ty.fmt(sema.pt)});19427 return sema.fail(block, operand_src, "no align available for type '{f}'", .{ty.fmt(sema.pt)});
19433 }19428 }
19434 try sema.ensureLayoutResolved(ty);19429 try sema.ensureLayoutResolved(ty, operand_src);
19435 return .fromValue(try pt.intValue(.comptime_int, ty.abiAlignment(zcu).toByteUnits().?));19430 return .fromValue(try pt.intValue(.comptime_int, ty.abiAlignment(zcu).toByteUnits().?));
19436}19431}
1943719432
...@@ -19912,7 +19907,7 @@ fn zirReifyFn(...@@ -19912,7 +19907,7 @@ fn zirReifyFn(
19912 const param_attrs_arr = try sema.derefSliceAsArray(block, param_attrs_src, param_attrs_slice, .{ .simple = .fn_param_attrs });19907 const param_attrs_arr = try sema.derefSliceAsArray(block, param_attrs_src, param_attrs_slice, .{ .simple = .fn_param_attrs });
1991319908
19914 const ret_ty = try sema.resolveType(block, ret_ty_src, extra.ret_ty);19909 const ret_ty = try sema.resolveType(block, ret_ty_src, extra.ret_ty);
19915 try sema.ensureLayoutResolved(ret_ty);19910 try sema.ensureLayoutResolved(ret_ty, ret_ty_src);
1991619911
19917 const fn_attrs_uncoerced = sema.resolveInst(extra.fn_attrs);19912 const fn_attrs_uncoerced = sema.resolveInst(extra.fn_attrs);
19918 const fn_attrs_coerced = try sema.coerce(block, fn_attrs_ty, fn_attrs_uncoerced, fn_attrs_src);19913 const fn_attrs_coerced = try sema.coerce(block, fn_attrs_ty, fn_attrs_uncoerced, fn_attrs_src);
...@@ -19937,7 +19932,7 @@ fn zirReifyFn(...@@ -19937,7 +19932,7 @@ fn zirReifyFn(
19937 param_types_src,19932 param_types_src,
19938 fn_attrs.@"callconv",19933 fn_attrs.@"callconv",
19939 );19934 );
19940 try sema.ensureLayoutResolved(param_ty);19935 try sema.ensureLayoutResolved(param_ty, param_types_src);
19941 if (param_ty.comptimeOnly(zcu)) {19936 if (param_ty.comptimeOnly(zcu)) {
19942 return sema.fail(block, param_attrs_src, "cannot reify function type with comptime-only parameter type '{f}'", .{param_ty.fmt(pt)});19937 return sema.fail(block, param_attrs_src, "cannot reify function type with comptime-only parameter type '{f}'", .{param_ty.fmt(pt)});
19943 }19938 }
...@@ -20253,14 +20248,6 @@ fn zirReifyStruct(...@@ -20253,14 +20248,6 @@ fn zirReifyStruct(
20253 });20248 });
20254 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));20249 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));
20255 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);20250 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
20256 // MLUGG TODO: we could potentially revert this language change if we wanted? don't mind
20257 try zcu.comp.queueJob(.{ .analyze_unit = .wrap(.{ .type_layout = wip.index }) });
20258
20259 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
20260 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
20261 errdefer comptime unreachable; // because we don't remove the `outdated` entries
20262 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), 0);
20263 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), {});
2026420251
20265 return .fromIntern(wip.finish(ip, new_namespace_index));20252 return .fromIntern(wip.finish(ip, new_namespace_index));
20266 },20253 },
...@@ -20482,15 +20469,6 @@ fn zirReifyUnion(...@@ -20482,15 +20469,6 @@ fn zirReifyUnion(
20482 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);20469 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
20483 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));20470 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));
2048420471
20485 // MLUGG TODO: we could potentially revert this language change if we wanted? don't mind
20486 try zcu.comp.queueJob(.{ .analyze_unit = .wrap(.{ .type_layout = wip.index }) });
20487
20488 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
20489 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
20490 errdefer comptime unreachable; // because we don't remove the `outdated` entry
20491 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), 0);
20492 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), {});
20493
20494 return .fromIntern(wip.finish(ip, new_namespace_index));20472 return .fromIntern(wip.finish(ip, new_namespace_index));
20495 },20473 },
20496 }20474 }
...@@ -20643,15 +20621,6 @@ fn zirReifyEnum(...@@ -20643,15 +20621,6 @@ fn zirReifyEnum(
20643 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));20621 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));
20644 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);20622 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
2064520623
20646 // MLUGG TODO: we could potentially revert this language change if we wanted? don't mind
20647 try zcu.comp.queueJob(.{ .analyze_unit = .wrap(.{ .type_layout = wip.index }) });
20648
20649 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
20650 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
20651 errdefer comptime unreachable; // because we don't remove the `outdated` entry
20652 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), 0);
20653 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), {});
20654
20655 return .fromIntern(wip.finish(ip, new_namespace_index));20624 return .fromIntern(wip.finish(ip, new_namespace_index));
20656 },20625 },
20657 }20626 }
...@@ -20874,7 +20843,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -20874,7 +20843,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
20874 const elem_ty = ptr_ty.nullablePtrElem(zcu);20843 const elem_ty = ptr_ty.nullablePtrElem(zcu);
2087520844
20876 // We'll need to validate the pointer alignment.20845 // We'll need to validate the pointer alignment.
20877 try sema.ensureLayoutResolved(elem_ty);20846 try sema.ensureLayoutResolved(elem_ty, src);
20878 const ptr_align = ptr_ty.ptrAlignment(zcu);20847 const ptr_align = ptr_ty.ptrAlignment(zcu);
2087920848
20880 if (ptr_ty.isSlice(zcu)) {20849 if (ptr_ty.isSlice(zcu)) {
...@@ -21217,8 +21186,8 @@ fn ptrCastFull(...@@ -21217,8 +21186,8 @@ fn ptrCastFull(
21217 const src_info = operand_ty.ptrInfo(zcu);21186 const src_info = operand_ty.ptrInfo(zcu);
21218 const dest_info = dest_ty.ptrInfo(zcu);21187 const dest_info = dest_ty.ptrInfo(zcu);
2121921188
21220 try sema.ensureLayoutResolved(.fromInterned(src_info.child));21189 try sema.ensureLayoutResolved(.fromInterned(src_info.child), operand_src);
21221 try sema.ensureLayoutResolved(.fromInterned(dest_info.child));21190 try sema.ensureLayoutResolved(.fromInterned(dest_info.child), src);
2122221191
21223 const DestSliceLen = union(enum) {21192 const DestSliceLen = union(enum) {
21224 undef,21193 undef,
...@@ -21989,7 +21958,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -21989,7 +21958,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
21989 const ty = try sema.resolveType(block, ty_src, extra.lhs);21958 const ty = try sema.resolveType(block, ty_src, extra.lhs);
21990 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.rhs, .{ .simple = .field_name });21959 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.rhs, .{ .simple = .field_name });
2199121960
21992 try sema.ensureLayoutResolved(ty);21961 try sema.ensureLayoutResolved(ty, ty_src);
2199321962
21994 const pt = sema.pt;21963 const pt = sema.pt;
21995 const zcu = pt.zcu;21964 const zcu = pt.zcu;
...@@ -23072,7 +23041,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -23072,7 +23041,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
23072 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, true);23041 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, true);
23073 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, .{ .simple = .atomic_order });23042 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, .{ .simple = .atomic_order });
2307423043
23075 try sema.ensureLayoutResolved(elem_ty);23044 try sema.ensureLayoutResolved(elem_ty, elem_ty_src);
2307623045
23077 switch (order) {23046 switch (order) {
23078 .release, .acq_rel => {23047 .release, .acq_rel => {
...@@ -23392,7 +23361,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -23392,7 +23361,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
23392 return sema.fail(block, inst_src, "expected single pointer type, found '{f}'", .{parent_ptr_ty.fmt(pt)});23361 return sema.fail(block, inst_src, "expected single pointer type, found '{f}'", .{parent_ptr_ty.fmt(pt)});
23393 }23362 }
23394 const parent_ty: Type = .fromInterned(parent_ptr_info.child);23363 const parent_ty: Type = .fromInterned(parent_ptr_info.child);
23395 try sema.ensureLayoutResolved(parent_ty);23364 try sema.ensureLayoutResolved(parent_ty, inst_src);
23396 switch (parent_ty.zigTypeTag(zcu)) {23365 switch (parent_ty.zigTypeTag(zcu)) {
23397 .@"struct", .@"union" => {},23366 .@"struct", .@"union" => {},
23398 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{f}'", .{parent_ptr_ty.fmt(pt)}),23367 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{f}'", .{parent_ptr_ty.fmt(pt)}),
...@@ -24002,8 +23971,8 @@ fn zirMemcpy(...@@ -24002,8 +23971,8 @@ fn zirMemcpy(
24002 const dest_elem_ty = dest_ty.indexableElem(zcu);23971 const dest_elem_ty = dest_ty.indexableElem(zcu);
24003 const src_elem_ty = src_ty.indexableElem(zcu);23972 const src_elem_ty = src_ty.indexableElem(zcu);
2400423973
24005 try sema.ensureLayoutResolved(dest_elem_ty);23974 try sema.ensureLayoutResolved(dest_elem_ty, dest_src);
24006 try sema.ensureLayoutResolved(src_elem_ty);23975 try sema.ensureLayoutResolved(src_elem_ty, src_src);
2400723976
24008 const imc = try sema.coerceInMemoryAllowed(23977 const imc = try sema.coerceInMemoryAllowed(
24009 block,23978 block,
...@@ -25518,7 +25487,7 @@ fn fieldPtrLoad(...@@ -25518,7 +25487,7 @@ fn fieldPtrLoad(
25518 const zcu = pt.zcu;25487 const zcu = pt.zcu;
25519 const object_ptr_ty = sema.typeOf(object_ptr);25488 const object_ptr_ty = sema.typeOf(object_ptr);
25520 const pointee_ty = object_ptr_ty.childType(zcu);25489 const pointee_ty = object_ptr_ty.childType(zcu);
25521 try sema.ensureLayoutResolved(pointee_ty); // MLUGG TODO25490 try sema.ensureLayoutResolved(pointee_ty, src); // MLUGG TODO
25522 if (try pointee_ty.onePossibleValue(pt)) |opv| {25491 if (try pointee_ty.onePossibleValue(pt)) |opv| {
25523 const object: Air.Inst.Ref = .fromValue(opv);25492 const object: Air.Inst.Ref = .fromValue(opv);
25524 return fieldVal(sema, block, src, object, field_name, field_name_src);25493 return fieldVal(sema, block, src, object, field_name, field_name_src);
...@@ -25654,7 +25623,7 @@ fn fieldVal(...@@ -25654,7 +25623,7 @@ fn fieldVal(
25654 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {25623 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
25655 return inst;25624 return inst;
25656 }25625 }
25657 try sema.ensureLayoutResolved(child_type);25626 try sema.ensureLayoutResolved(child_type, src);
25658 if (child_type.unionTagType(zcu)) |enum_ty| {25627 if (child_type.unionTagType(zcu)) |enum_ty| {
25659 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index_usize| {25628 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index_usize| {
25660 const field_index: u32 = @intCast(field_index_usize);25629 const field_index: u32 = @intCast(field_index_usize);
...@@ -25667,7 +25636,7 @@ fn fieldVal(...@@ -25667,7 +25636,7 @@ fn fieldVal(
25667 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {25636 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
25668 return inst;25637 return inst;
25669 }25638 }
25670 try sema.ensureLayoutResolved(child_type);25639 try sema.ensureLayoutResolved(child_type, src);
25671 const field_index_usize = child_type.enumFieldIndex(field_name, zcu) orelse25640 const field_index_usize = child_type.enumFieldIndex(field_name, zcu) orelse
25672 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);25641 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
25673 const field_index: u32 = @intCast(field_index_usize);25642 const field_index: u32 = @intCast(field_index_usize);
...@@ -25693,7 +25662,7 @@ fn fieldVal(...@@ -25693,7 +25662,7 @@ fn fieldVal(
25693 },25662 },
25694 .@"struct" => if (is_pointer_to) {25663 .@"struct" => if (is_pointer_to) {
25695 // Avoid loading the entire struct by fetching a pointer and loading that25664 // Avoid loading the entire struct by fetching a pointer and loading that
25696 try sema.ensureLayoutResolved(inner_ty);25665 try sema.ensureLayoutResolved(inner_ty, src);
25697 const field_ptr = try sema.structFieldPtr(block, src, object, field_name, field_name_src, inner_ty, false);25666 const field_ptr = try sema.structFieldPtr(block, src, object, field_name, field_name_src, inner_ty, false);
25698 return sema.analyzeLoad(block, src, field_ptr, object_src);25667 return sema.analyzeLoad(block, src, field_ptr, object_src);
25699 } else {25668 } else {
...@@ -25701,7 +25670,7 @@ fn fieldVal(...@@ -25701,7 +25670,7 @@ fn fieldVal(
25701 },25670 },
25702 .@"union" => if (is_pointer_to) {25671 .@"union" => if (is_pointer_to) {
25703 // Avoid loading the entire union by fetching a pointer and loading that25672 // Avoid loading the entire union by fetching a pointer and loading that
25704 try sema.ensureLayoutResolved(inner_ty);25673 try sema.ensureLayoutResolved(inner_ty, src);
25705 const field_ptr = try sema.unionFieldPtr(block, src, object, field_name, field_name_src, inner_ty, false);25674 const field_ptr = try sema.unionFieldPtr(block, src, object, field_name, field_name_src, inner_ty, false);
25706 return sema.analyzeLoad(block, src, field_ptr, object_src);25675 return sema.analyzeLoad(block, src, field_ptr, object_src);
25707 } else {25676 } else {
...@@ -25884,7 +25853,7 @@ fn fieldPtr(...@@ -25884,7 +25853,7 @@ fn fieldPtr(
25884 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {25853 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
25885 return inst;25854 return inst;
25886 }25855 }
25887 try sema.ensureLayoutResolved(child_type);25856 try sema.ensureLayoutResolved(child_type, src);
25888 if (child_type.unionTagType(zcu)) |enum_ty| {25857 if (child_type.unionTagType(zcu)) |enum_ty| {
25889 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index| {25858 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index| {
25890 const field_index_u32: u32 = @intCast(field_index);25859 const field_index_u32: u32 = @intCast(field_index);
...@@ -25898,7 +25867,7 @@ fn fieldPtr(...@@ -25898,7 +25867,7 @@ fn fieldPtr(
25898 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {25867 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
25899 return inst;25868 return inst;
25900 }25869 }
25901 try sema.ensureLayoutResolved(child_type);25870 try sema.ensureLayoutResolved(child_type, src);
25902 const field_index = child_type.enumFieldIndex(field_name, zcu) orelse {25871 const field_index = child_type.enumFieldIndex(field_name, zcu) orelse {
25903 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);25872 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
25904 };25873 };
...@@ -25920,7 +25889,7 @@ fn fieldPtr(...@@ -25920,7 +25889,7 @@ fn fieldPtr(
25920 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)25889 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)
25921 else25890 else
25922 object_ptr;25891 object_ptr;
25923 try sema.ensureLayoutResolved(inner_ty);25892 try sema.ensureLayoutResolved(inner_ty, src);
25924 const field_ptr = try sema.structFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty, initializing);25893 const field_ptr = try sema.structFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty, initializing);
25925 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);25894 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
25926 return field_ptr;25895 return field_ptr;
...@@ -25930,7 +25899,7 @@ fn fieldPtr(...@@ -25930,7 +25899,7 @@ fn fieldPtr(
25930 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)25899 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)
25931 else25900 else
25932 object_ptr;25901 object_ptr;
25933 try sema.ensureLayoutResolved(inner_ty);25902 try sema.ensureLayoutResolved(inner_ty, src);
25934 const field_ptr = try sema.unionFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty, initializing);25903 const field_ptr = try sema.unionFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty, initializing);
25935 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);25904 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
25936 return field_ptr;25905 return field_ptr;
...@@ -25974,7 +25943,7 @@ fn fieldCallBind(...@@ -25974,7 +25943,7 @@ fn fieldCallBind(
25974 // Optionally dereference a second pointer to get the concrete type.25943 // Optionally dereference a second pointer to get the concrete type.
25975 const is_double_ptr = inner_ty.zigTypeTag(zcu) == .pointer and inner_ty.ptrSize(zcu) == .one;25944 const is_double_ptr = inner_ty.zigTypeTag(zcu) == .pointer and inner_ty.ptrSize(zcu) == .one;
25976 const concrete_ty = if (is_double_ptr) inner_ty.childType(zcu) else inner_ty;25945 const concrete_ty = if (is_double_ptr) inner_ty.childType(zcu) else inner_ty;
25977 try sema.ensureLayoutResolved(concrete_ty);25946 try sema.ensureLayoutResolved(concrete_ty, src);
25978 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;25947 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;
25979 const object_ptr = if (is_double_ptr)25948 const object_ptr = if (is_double_ptr)
25980 try sema.analyzeLoad(block, src, raw_ptr, src)25949 try sema.analyzeLoad(block, src, raw_ptr, src)
...@@ -26661,7 +26630,7 @@ fn elemPtr(...@@ -26661,7 +26630,7 @@ fn elemPtr(
26661 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{f}'", .{indexable_ptr_ty.fmt(pt)}),26630 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{f}'", .{indexable_ptr_ty.fmt(pt)}),
26662 };26631 };
26663 try sema.checkIndexable(block, src, indexable_ty);26632 try sema.checkIndexable(block, src, indexable_ty);
26664 try sema.ensureLayoutResolved(indexable_ty);26633 try sema.ensureLayoutResolved(indexable_ty, src);
2666526634
26666 const elem_ptr = switch (indexable_ty.zigTypeTag(zcu)) {26635 const elem_ptr = switch (indexable_ty.zigTypeTag(zcu)) {
26667 .array, .vector => try sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety),26636 .array, .vector => try sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety),
...@@ -26673,7 +26642,7 @@ fn elemPtr(...@@ -26673,7 +26642,7 @@ fn elemPtr(
26673 },26642 },
26674 else => {26643 else => {
26675 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);26644 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);
26676 try sema.ensureLayoutResolved(sema.typeOf(indexable).childType(zcu));26645 try sema.ensureLayoutResolved(sema.typeOf(indexable).childType(zcu), src);
26677 return elemPtrOneLayerOnly(sema, block, src, indexable, elem_index, elem_index_src, init, oob_safety);26646 return elemPtrOneLayerOnly(sema, block, src, indexable, elem_index, elem_index_src, init, oob_safety);
26678 },26647 },
26679 };26648 };
...@@ -26769,7 +26738,7 @@ fn elemVal(...@@ -26769,7 +26738,7 @@ fn elemVal(
26769 switch (indexable_ty.zigTypeTag(zcu)) {26738 switch (indexable_ty.zigTypeTag(zcu)) {
26770 .pointer => {26739 .pointer => {
26771 const child_ty = indexable_ty.childType(zcu);26740 const child_ty = indexable_ty.childType(zcu);
26772 try sema.ensureLayoutResolved(child_ty);26741 try sema.ensureLayoutResolved(child_ty, src);
26773 switch (indexable_ty.ptrSize(zcu)) {26742 switch (indexable_ty.ptrSize(zcu)) {
26774 .slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),26743 .slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
26775 .many, .c => {26744 .many, .c => {
...@@ -27293,7 +27262,7 @@ fn coerceExtra(...@@ -27293,7 +27262,7 @@ fn coerceExtra(
27293 const target = zcu.getTarget();27262 const target = zcu.getTarget();
2729427263
27295 inst_ty.assertHasLayout(zcu);27264 inst_ty.assertHasLayout(zcu);
27296 try sema.ensureLayoutResolved(dest_ty);27265 try sema.ensureLayoutResolved(dest_ty, inst_src);
2729727266
27298 // If the types are the same, we can return the operand.27267 // If the types are the same, we can return the operand.
27299 if (dest_ty.eql(inst_ty, zcu))27268 if (dest_ty.eql(inst_ty, zcu))
...@@ -28657,8 +28626,8 @@ fn coerceInMemoryAllowedFns(...@@ -28657,8 +28626,8 @@ fn coerceInMemoryAllowedFns(
28657 } };28626 } };
28658 }28627 }
2865928628
28660 try sema.ensureLayoutResolved(src_ty);28629 try sema.ensureLayoutResolved(src_ty, src_src);
28661 try sema.ensureLayoutResolved(dest_ty);28630 try sema.ensureLayoutResolved(dest_ty, dest_src);
28662 const src_is_runtime = src_ty.fnHasRuntimeBits(zcu);28631 const src_is_runtime = src_ty.fnHasRuntimeBits(zcu);
28663 const dest_is_runtime = dest_ty.fnHasRuntimeBits(zcu);28632 const dest_is_runtime = dest_ty.fnHasRuntimeBits(zcu);
28664 if (src_is_runtime != dest_is_runtime) return .{ .fn_generic = !dest_is_runtime };28633 if (src_is_runtime != dest_is_runtime) return .{ .fn_generic = !dest_is_runtime };
...@@ -28712,7 +28681,7 @@ fn coerceInMemoryAllowedFns(...@@ -28712,7 +28681,7 @@ fn coerceInMemoryAllowedFns(
28712 const src_is_comptime = src_info.paramIsComptime(@intCast(param_i));28681 const src_is_comptime = src_info.paramIsComptime(@intCast(param_i));
28713 const dest_is_comptime = dest_info.paramIsComptime(@intCast(param_i));28682 const dest_is_comptime = dest_info.paramIsComptime(@intCast(param_i));
28714 if (src_is_comptime == dest_is_comptime) break :comptime_param;28683 if (src_is_comptime == dest_is_comptime) break :comptime_param;
28715 try sema.ensureLayoutResolved(dest_param_ty);28684 try sema.ensureLayoutResolved(dest_param_ty, dest_src);
28716 if (!dest_is_mut and src_is_comptime and !dest_is_comptime and dest_param_ty.comptimeOnly(zcu)) {28685 if (!dest_is_mut and src_is_comptime and !dest_is_comptime and dest_param_ty.comptimeOnly(zcu)) {
28717 // A parameter which is marked `comptime` can drop that annotation if the type is comptime-only.28686 // A parameter which is marked `comptime` can drop that annotation if the type is comptime-only.
28718 // The function remains generic, and the parameter is going to be comptime-resolved either way,28687 // The function remains generic, and the parameter is going to be comptime-resolved either way,
...@@ -28940,11 +28909,11 @@ fn coerceInMemoryAllowedPtrs(...@@ -28940,11 +28909,11 @@ fn coerceInMemoryAllowedPtrs(
28940 dest_info.child != src_info.child)28909 dest_info.child != src_info.child)
28941 {28910 {
28942 const src_align = if (src_info.flags.alignment == .none) a: {28911 const src_align = if (src_info.flags.alignment == .none) a: {
28943 try sema.ensureLayoutResolved(src_child);28912 try sema.ensureLayoutResolved(src_child, src_src);
28944 break :a src_child.abiAlignment(zcu);28913 break :a src_child.abiAlignment(zcu);
28945 } else src_info.flags.alignment;28914 } else src_info.flags.alignment;
28946 const dest_align = if (dest_info.flags.alignment == .none) a: {28915 const dest_align = if (dest_info.flags.alignment == .none) a: {
28947 try sema.ensureLayoutResolved(dest_child);28916 try sema.ensureLayoutResolved(dest_child, dest_src);
28948 break :a dest_child.abiAlignment(zcu);28917 break :a dest_child.abiAlignment(zcu);
28949 } else dest_info.flags.alignment;28918 } else dest_info.flags.alignment;
28950 if (dest_align.compare(if (dest_is_mut) .neq else .gt, src_align)) {28919 if (dest_align.compare(if (dest_is_mut) .neq else .gt, src_align)) {
...@@ -29294,7 +29263,7 @@ fn bitCast(...@@ -29294,7 +29263,7 @@ fn bitCast(
29294 const old_ty = sema.typeOf(inst);29263 const old_ty = sema.typeOf(inst);
2929529264
29296 old_ty.assertHasLayout(zcu);29265 old_ty.assertHasLayout(zcu);
29297 try sema.ensureLayoutResolved(dest_ty);29266 try sema.ensureLayoutResolved(dest_ty, inst_src);
2929829267
29299 const dest_bits = dest_ty.bitSize(zcu);29268 const dest_bits = dest_ty.bitSize(zcu);
29300 const old_bits = old_ty.bitSize(zcu);29269 const old_bits = old_ty.bitSize(zcu);
...@@ -29908,7 +29877,7 @@ fn analyzeNavVal(...@@ -29908,7 +29877,7 @@ fn analyzeNavVal(
29908 return sema.analyzeLoad(block, src, ref, src);29877 return sema.analyzeLoad(block, src, ref, src);
29909}29878}
2991029879
29911fn addReferenceEntry(29880pub fn addReferenceEntry(
29912 sema: *Sema,29881 sema: *Sema,
29913 opt_block: ?*Block,29882 opt_block: ?*Block,
29914 src: LazySrcLoc,29883 src: LazySrcLoc,
...@@ -30176,7 +30145,7 @@ fn analyzeLoad(...@@ -30176,7 +30145,7 @@ fn analyzeLoad(
30176 return sema.fail(block, ptr_src, "cannot load opaque type '{f}'", .{elem_ty.fmt(pt)});30145 return sema.fail(block, ptr_src, "cannot load opaque type '{f}'", .{elem_ty.fmt(pt)});
30177 }30146 }
3017830147
30179 try sema.ensureLayoutResolved(elem_ty);30148 try sema.ensureLayoutResolved(elem_ty, src);
30180 if (try elem_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);30149 if (try elem_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
3018130150
30182 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {30151 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
...@@ -30561,7 +30530,7 @@ fn analyzeSlice(...@@ -30561,7 +30530,7 @@ fn analyzeSlice(
30561 else => return sema.fail(block, src, "slice of non-array type '{f}'", .{ptr_ptr_child_ty.fmt(pt)}),30530 else => return sema.fail(block, src, "slice of non-array type '{f}'", .{ptr_ptr_child_ty.fmt(pt)}),
30562 }30531 }
3056330532
30564 try sema.ensureLayoutResolved(elem_ty);30533 try sema.ensureLayoutResolved(elem_ty, src);
3056530534
30566 const ptr = if (slice_ty.isSlice(zcu))30535 const ptr = if (slice_ty.isSlice(zcu))
30567 try sema.analyzeSlicePtr(block, ptr_src, ptr_or_slice, slice_ty)30536 try sema.analyzeSlicePtr(block, ptr_src, ptr_or_slice, slice_ty)
...@@ -34024,7 +33993,7 @@ pub fn analyzeMemoizedState(sema: *Sema, block: *Block, simple_src: LazySrcLoc,...@@ -34024,7 +33993,7 @@ pub fn analyzeMemoizedState(sema: *Sema, block: *Block, simple_src: LazySrcLoc,
34024 .type => if (uncoerced_val.typeOf(zcu).zigTypeTag(zcu) != .type) {33993 .type => if (uncoerced_val.typeOf(zcu).zigTypeTag(zcu) != .type) {
34025 return sema.fail(block, src, "{s}.{s} is not a type", .{ parent_name, name });33994 return sema.fail(block, src, "{s}.{s} is not a type", .{ parent_name, name });
34026 } else val: {33995 } else val: {
34027 try sema.ensureLayoutResolved(uncoerced_val.toType());33996 try sema.ensureLayoutResolved(uncoerced_val.toType(), src);
34028 break :val uncoerced_val;33997 break :val uncoerced_val;
34029 },33998 },
34030 .func => val: {33999 .func => val: {
...@@ -34271,20 +34240,9 @@ fn zirStructDecl(...@@ -34271,20 +34240,9 @@ fn zirStructDecl(
34271 });34240 });
34272 errdefer pt.destroyNamespace(new_namespace_index);34241 errdefer pt.destroyNamespace(new_namespace_index);
34273 try pt.scanNamespace(new_namespace_index, struct_decl.decls);34242 try pt.scanNamespace(new_namespace_index, struct_decl.decls);
34274 // MLUGG TODO: we could potentially revert this language change if we wanted? don't mind
34275 try zcu.comp.queueJob(.{ .analyze_unit = .wrap(.{ .type_layout = wip.index }) });
34276 try zcu.comp.queueJob(.{ .analyze_unit = .wrap(.{ .struct_defaults = wip.index }) });
3427734243
34278 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);34244 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
3427934245
34280 try zcu.outdated.ensureUnusedCapacity(gpa, 2);
34281 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 2);
34282 errdefer comptime unreachable; // because we don't remove the `outdated` entries
34283 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), 0);
34284 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .struct_defaults = wip.index }), 0);
34285 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), {});
34286 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .struct_defaults = wip.index }), {});
34287
34288 break :ty .fromInterned(wip.finish(ip, new_namespace_index));34246 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
34289 },34247 },
34290 };34248 };
...@@ -34364,17 +34322,8 @@ fn zirUnionDecl(...@@ -34364,17 +34322,8 @@ fn zirUnionDecl(
3436434322
34365 try pt.scanNamespace(new_namespace_index, union_decl.decls);34323 try pt.scanNamespace(new_namespace_index, union_decl.decls);
3436634324
34367 // MLUGG TODO: we could potentially revert this language change if we wanted? don't mind
34368 try zcu.comp.queueJob(.{ .analyze_unit = .wrap(.{ .type_layout = wip.index }) });
34369
34370 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);34325 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
3437134326
34372 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
34373 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
34374 errdefer comptime unreachable; // because we don't remove the `outdated` entry
34375 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), 0);
34376 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), {});
34377
34378 break :ty .fromInterned(wip.finish(ip, new_namespace_index));34327 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
34379 },34328 },
34380 };34329 };
...@@ -34434,17 +34383,8 @@ fn zirEnumDecl(...@@ -34434,17 +34383,8 @@ fn zirEnumDecl(
3443434383
34435 try pt.scanNamespace(new_namespace_index, enum_decl.decls);34384 try pt.scanNamespace(new_namespace_index, enum_decl.decls);
3443634385
34437 // MLUGG TODO: we could potentially revert this language change if we wanted? don't mind
34438 try zcu.comp.queueJob(.{ .analyze_unit = .wrap(.{ .type_layout = wip.index }) });
34439
34440 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);34386 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
3444134387
34442 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
34443 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
34444 errdefer comptime unreachable; // because we don't remove the `outdated` entry
34445 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), 0);
34446 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), {});
34447
34448 break :ty .fromInterned(wip.finish(ip, new_namespace_index));34388 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
34449 },34389 },
34450 };34390 };
src/Sema/LowerZon.zig+6-5
...@@ -300,7 +300,7 @@ fn checkTypeInner(...@@ -300,7 +300,7 @@ fn checkTypeInner(
300 } else {300 } else {
301 const gop = try visited.getOrPut(sema.arena, ty.toIntern());301 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
302 if (gop.found_existing) return;302 if (gop.found_existing) return;
303 try sema.ensureLayoutResolved(ty);303 try sema.ensureLayoutResolved(ty, self.import_loc);
304 const struct_info = zcu.typeToStruct(ty).?;304 const struct_info = zcu.typeToStruct(ty).?;
305 for (struct_info.field_types.get(ip)) |field_type| {305 for (struct_info.field_types.get(ip)) |field_type| {
306 try self.checkTypeInner(.fromInterned(field_type), null, visited);306 try self.checkTypeInner(.fromInterned(field_type), null, visited);
...@@ -309,7 +309,7 @@ fn checkTypeInner(...@@ -309,7 +309,7 @@ fn checkTypeInner(
309 .@"union" => {309 .@"union" => {
310 const gop = try visited.getOrPut(sema.arena, ty.toIntern());310 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
311 if (gop.found_existing) return;311 if (gop.found_existing) return;
312 try sema.ensureLayoutResolved(ty);312 try sema.ensureLayoutResolved(ty, self.import_loc);
313 const union_info = zcu.typeToUnion(ty).?;313 const union_info = zcu.typeToUnion(ty).?;
314 for (union_info.field_types.get(ip)) |field_type| {314 for (union_info.field_types.get(ip)) |field_type| {
315 if (field_type != .void_type) {315 if (field_type != .void_type) {
...@@ -646,6 +646,7 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I...@@ -646,6 +646,7 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I
646 const gpa = comp.gpa;646 const gpa = comp.gpa;
647 const io = comp.io;647 const io = comp.io;
648 const ip = &pt.zcu.intern_pool;648 const ip = &pt.zcu.intern_pool;
649 try self.sema.ensureLayoutResolved(res_ty, self.import_loc);
649 switch (node.get(self.file.zoir.?)) {650 switch (node.get(self.file.zoir.?)) {
650 .enum_literal => |field_name| {651 .enum_literal => |field_name| {
651 const field_name_interned = try ip.getOrPutString(652 const field_name_interned = try ip.getOrPutString(
...@@ -768,8 +769,8 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool...@@ -768,8 +769,8 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
768 const io = comp.io;769 const io = comp.io;
769 const ip = &pt.zcu.intern_pool;770 const ip = &pt.zcu.intern_pool;
770771
771 try self.sema.ensureLayoutResolved(res_ty);772 try self.sema.ensureLayoutResolved(res_ty, self.import_loc);
772 try self.sema.ensureStructDefaultsResolved(res_ty);773 try self.sema.ensureStructDefaultsResolved(res_ty, self.import_loc);
773 const struct_info = self.sema.pt.zcu.typeToStruct(res_ty).?;774 const struct_info = self.sema.pt.zcu.typeToStruct(res_ty).?;
774775
775 const fields: @FieldType(Zoir.Node, "struct_literal") = switch (node.get(self.file.zoir.?)) {776 const fields: @FieldType(Zoir.Node, "struct_literal") = switch (node.get(self.file.zoir.?)) {
...@@ -919,7 +920,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool....@@ -919,7 +920,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
919 const gpa = comp.gpa;920 const gpa = comp.gpa;
920 const io = comp.io;921 const io = comp.io;
921 const ip = &pt.zcu.intern_pool;922 const ip = &pt.zcu.intern_pool;
922 try self.sema.ensureLayoutResolved(res_ty);923 try self.sema.ensureLayoutResolved(res_ty, self.import_loc);
923 const union_info = pt.zcu.typeToUnion(res_ty).?;924 const union_info = pt.zcu.typeToUnion(res_ty).?;
924 const enum_tag_info = ip.loadEnumType(union_info.enum_tag_type);925 const enum_tag_info = ip.loadEnumType(union_info.enum_tag_type);
925926
src/Sema/bitcast.zig+3-3
...@@ -80,7 +80,7 @@ fn bitCastInner(...@@ -80,7 +80,7 @@ fn bitCastInner(
80 const val_ty = val.typeOf(zcu);80 const val_ty = val.typeOf(zcu);
8181
82 val_ty.assertHasLayout(zcu);82 val_ty.assertHasLayout(zcu);
83 try sema.ensureLayoutResolved(dest_ty);83 dest_ty.assertHasLayout(zcu);
8484
85 assert(val_ty.hasWellDefinedLayout(zcu));85 assert(val_ty.hasWellDefinedLayout(zcu));
8686
...@@ -138,8 +138,8 @@ fn bitCastSpliceInner(...@@ -138,8 +138,8 @@ fn bitCastSpliceInner(
138 const val_ty = val.typeOf(zcu);138 const val_ty = val.typeOf(zcu);
139 const splice_val_ty = splice_val.typeOf(zcu);139 const splice_val_ty = splice_val.typeOf(zcu);
140140
141 try sema.ensureLayoutResolved(val_ty);141 val_ty.assertHasLayout(zcu);
142 try sema.ensureLayoutResolved(splice_val_ty);142 splice_val_ty.assertHasLayout(zcu);
143143
144 const splice_bits = splice_val_ty.bitSize(zcu);144 const splice_bits = splice_val_ty.bitSize(zcu);
145145
src/Sema/type_resolution.zig+34-34
...@@ -19,7 +19,7 @@ const arith = @import("arith.zig");...@@ -19,7 +19,7 @@ const arith = @import("arith.zig");
19/// Adds incremental dependencies tracking any required type resolution.19/// Adds incremental dependencies tracking any required type resolution.
20/// MLUGG TODO: to make the langspec non-stupid, we need to call this from WAY fewer places (the conditions need to be less specific).20/// MLUGG TODO: to make the langspec non-stupid, we need to call this from WAY fewer places (the conditions need to be less specific).
21/// MLUGG TODO: to be clear, i should audit EVERY use of this before PRing21/// MLUGG TODO: to be clear, i should audit EVERY use of this before PRing
22pub fn ensureLayoutResolved(sema: *Sema, ty: Type) SemaError!void {22pub fn ensureLayoutResolved(sema: *Sema, ty: Type, src: LazySrcLoc) SemaError!void {
23 const pt = sema.pt;23 const pt = sema.pt;
24 const zcu = pt.zcu;24 const zcu = pt.zcu;
25 const ip = &zcu.intern_pool;25 const ip = &zcu.intern_pool;
...@@ -35,20 +35,21 @@ pub fn ensureLayoutResolved(sema: *Sema, ty: Type) SemaError!void {...@@ -35,20 +35,21 @@ pub fn ensureLayoutResolved(sema: *Sema, ty: Type) SemaError!void {
3535
36 .func_type => |func_type| {36 .func_type => |func_type| {
37 for (func_type.param_types.get(ip)) |param_ty| {37 for (func_type.param_types.get(ip)) |param_ty| {
38 try ensureLayoutResolved(sema, .fromInterned(param_ty));38 try ensureLayoutResolved(sema, .fromInterned(param_ty), src);
39 }39 }
40 try ensureLayoutResolved(sema, .fromInterned(func_type.return_type));40 try ensureLayoutResolved(sema, .fromInterned(func_type.return_type), src);
41 },41 },
4242
43 .array_type => |arr| return ensureLayoutResolved(sema, .fromInterned(arr.child)),43 .array_type => |arr| return ensureLayoutResolved(sema, .fromInterned(arr.child), src),
44 .vector_type => |vec| return ensureLayoutResolved(sema, .fromInterned(vec.child)),44 .vector_type => |vec| return ensureLayoutResolved(sema, .fromInterned(vec.child), src),
45 .opt_type => |child| return ensureLayoutResolved(sema, .fromInterned(child)),45 .opt_type => |child| return ensureLayoutResolved(sema, .fromInterned(child), src),
46 .error_union_type => |eu| return ensureLayoutResolved(sema, .fromInterned(eu.payload_type)),46 .error_union_type => |eu| return ensureLayoutResolved(sema, .fromInterned(eu.payload_type), src),
47 .tuple_type => |tuple| for (tuple.types.get(ip)) |field_ty| {47 .tuple_type => |tuple| for (tuple.types.get(ip)) |field_ty| {
48 try ensureLayoutResolved(sema, .fromInterned(field_ty));48 try ensureLayoutResolved(sema, .fromInterned(field_ty), src);
49 },49 },
50 .struct_type, .union_type, .enum_type => {50 .struct_type, .union_type, .enum_type => {
51 try sema.declareDependency(.{ .type_layout = ty.toIntern() });51 try sema.declareDependency(.{ .type_layout = ty.toIntern() });
52 try sema.addReferenceEntry(null, src, .wrap(.{ .type_layout = ty.toIntern() }));
52 if (zcu.analysis_in_progress.contains(.wrap(.{ .type_layout = ty.toIntern() }))) {53 if (zcu.analysis_in_progress.contains(.wrap(.{ .type_layout = ty.toIntern() }))) {
53 // TODO: better error message54 // TODO: better error message
54 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(55 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(
...@@ -89,13 +90,14 @@ pub fn ensureLayoutResolved(sema: *Sema, ty: Type) SemaError!void {...@@ -89,13 +90,14 @@ pub fn ensureLayoutResolved(sema: *Sema, ty: Type) SemaError!void {
89///90///
90/// It is not necessary to call this function to query the values of comptime fields: those values91/// It is not necessary to call this function to query the values of comptime fields: those values
91/// are available from type *layout* resolution, see `ensureLayoutResolved`.92/// are available from type *layout* resolution, see `ensureLayoutResolved`.
92pub fn ensureStructDefaultsResolved(sema: *Sema, ty: Type) SemaError!void {93pub fn ensureStructDefaultsResolved(sema: *Sema, ty: Type, src: LazySrcLoc) SemaError!void {
93 const pt = sema.pt;94 const pt = sema.pt;
94 const zcu = pt.zcu;95 const zcu = pt.zcu;
95 const ip = &zcu.intern_pool;96 const ip = &zcu.intern_pool;
96 assert(ip.indexToKey(ty.toIntern()) == .struct_type);97 assert(ip.indexToKey(ty.toIntern()) == .struct_type);
9798
98 try sema.declareDependency(.{ .struct_defaults = ty.toIntern() });99 try sema.declareDependency(.{ .struct_defaults = ty.toIntern() });
100 try sema.addReferenceEntry(null, src, .wrap(.{ .struct_defaults = ty.toIntern() }));
99 if (zcu.analysis_in_progress.contains(.wrap(.{ .struct_defaults = ty.toIntern() }))) {101 if (zcu.analysis_in_progress.contains(.wrap(.{ .struct_defaults = ty.toIntern() }))) {
100 // TODO: better error message102 // TODO: better error message
101 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(103 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(
...@@ -120,7 +122,8 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {...@@ -120,7 +122,8 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
120 assert(sema.owner.unwrap().type_layout == struct_ty.toIntern());122 assert(sema.owner.unwrap().type_layout == struct_ty.toIntern());
121123
122 const struct_obj = ip.loadStructType(struct_ty.toIntern());124 const struct_obj = ip.loadStructType(struct_ty.toIntern());
123 const zir_index = struct_obj.zir_index.resolve(ip).?;125 assert(struct_obj.want_layout);
126 const zir_index = struct_obj.zir_index.resolve(ip) orelse return error.AnalysisFail;
124127
125 var block: Block = .{128 var block: Block = .{
126 .parent = null,129 .parent = null,
...@@ -219,7 +222,7 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {...@@ -219,7 +222,7 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
219 const field_ty: Type = .fromInterned(field_ty_ip);222 const field_ty: Type = .fromInterned(field_ty_ip);
220 assert(!field_ty.isGenericPoison());223 assert(!field_ty.isGenericPoison());
221 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });224 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });
222 try sema.ensureLayoutResolved(field_ty);225 try sema.ensureLayoutResolved(field_ty, field_ty_src);
223226
224 if (field_ty.zigTypeTag(zcu) == .@"opaque") {227 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
225 return sema.failWithOwnedErrorMsg(&block, msg: {228 return sema.failWithOwnedErrorMsg(&block, msg: {
...@@ -368,7 +371,7 @@ fn resolvePackedStructLayout(...@@ -368,7 +371,7 @@ fn resolvePackedStructLayout(
368 const field_ty: Type = .fromInterned(field_ty_ip);371 const field_ty: Type = .fromInterned(field_ty_ip);
369 assert(!field_ty.isGenericPoison());372 assert(!field_ty.isGenericPoison());
370 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });373 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });
371 try sema.ensureLayoutResolved(field_ty);374 try sema.ensureLayoutResolved(field_ty, field_ty_src);
372 if (field_ty.zigTypeTag(zcu) == .@"opaque") {375 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
373 return sema.failWithOwnedErrorMsg(block, msg: {376 return sema.failWithOwnedErrorMsg(block, msg: {
374 const msg = try sema.errMsg(field_ty_src, "cannot directly embed opaque type '{f}' in struct", .{field_ty.fmt(pt)});377 const msg = try sema.errMsg(field_ty_src, "cannot directly embed opaque type '{f}' in struct", .{field_ty.fmt(pt)});
...@@ -458,16 +461,19 @@ pub fn resolveStructDefaults(sema: *Sema, struct_ty: Type) CompileError!void {...@@ -458,16 +461,19 @@ pub fn resolveStructDefaults(sema: *Sema, struct_ty: Type) CompileError!void {
458461
459 assert(sema.owner.unwrap().struct_defaults == struct_ty.toIntern());462 assert(sema.owner.unwrap().struct_defaults == struct_ty.toIntern());
460463
461 try sema.ensureLayoutResolved(struct_ty);464 try sema.ensureLayoutResolved(struct_ty, struct_ty.srcLoc(zcu));
462465
463 const struct_obj = ip.loadStructType(struct_ty.toIntern());466 const struct_obj = ip.loadStructType(struct_ty.toIntern());
467 assert(struct_obj.want_defaults);
464468
465 try sema.declareDependency(.{ .src_hash = struct_obj.zir_index });469 if (struct_obj.is_reified) {
470 // `Sema.zirReifyStruct` has already populated the default field values *and* (by loading
471 // the default values from pointers) validated their types, so we have nothing to do. We
472 // don't even need to mark any dependencies.
473 return;
474 }
466475
467 // This logic isn't used for reified structs, because the signature of `@Struct` requires that476 try sema.declareDependency(.{ .src_hash = struct_obj.zir_index });
468 // default values are populated and correctly typed from the moment the struct type is interned
469 // (because `Sema.zirReifyStruct` had to dereference the default value from a pointer).
470 assert(!struct_obj.is_reified);
471477
472 if (struct_obj.field_defaults.len == 0) {478 if (struct_obj.field_defaults.len == 0) {
473 // The struct has no default field values, so the slice has been omitted.479 // The struct has no default field values, so the slice has been omitted.
...@@ -509,7 +515,7 @@ fn resolveStructDefaultsInner(...@@ -509,7 +515,7 @@ fn resolveStructDefaultsInner(
509 const ip = &zcu.intern_pool;515 const ip = &zcu.intern_pool;
510516
511 // We'll need to map the struct decl instruction to provide result types517 // We'll need to map the struct decl instruction to provide result types
512 const zir_index = struct_obj.zir_index.resolve(ip).?;518 const zir_index = struct_obj.zir_index.resolve(ip) orelse return error.AnalysisFail;
513 try sema.inst_map.ensureSpaceForInstructions(gpa, &.{zir_index});519 try sema.inst_map.ensureSpaceForInstructions(gpa, &.{zir_index});
514520
515 const field_types = struct_obj.field_types.get(ip);521 const field_types = struct_obj.field_types.get(ip);
...@@ -555,7 +561,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {...@@ -555,7 +561,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
555 assert(sema.owner.unwrap().type_layout == union_ty.toIntern());561 assert(sema.owner.unwrap().type_layout == union_ty.toIntern());
556562
557 const union_obj = ip.loadUnionType(union_ty.toIntern());563 const union_obj = ip.loadUnionType(union_ty.toIntern());
558 const zir_index = union_obj.zir_index.resolve(ip).?;564 assert(union_obj.want_layout);
565 const zir_index = union_obj.zir_index.resolve(ip) orelse return error.AnalysisFail;
559566
560 var block: Block = .{567 var block: Block = .{
561 .parent = null,568 .parent = null,
...@@ -627,16 +634,11 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {...@@ -627,16 +634,11 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
627 .generation = zcu.generation,634 .generation = zcu.generation,
628 });635 });
629 if (comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);636 if (comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
630 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
631 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
632 errdefer comptime unreachable; // because we don't remove the `outdated` entry
633 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), 0);
634 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), {});
635 break :tag_ty .fromInterned(wip.finish(ip, new_namespace_index));637 break :tag_ty .fromInterned(wip.finish(ip, new_namespace_index));
636 },638 },
637 };639 };
638640
639 try sema.ensureLayoutResolved(enum_tag_ty);641 try sema.ensureLayoutResolved(enum_tag_ty, block.src(.container_arg));
640 const enum_obj = ip.loadEnumType(enum_tag_ty.toIntern());642 const enum_obj = ip.loadEnumType(enum_tag_ty.toIntern());
641643
642 if (union_obj.is_reified) {644 if (union_obj.is_reified) {
...@@ -731,7 +733,7 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {...@@ -731,7 +733,7 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
731 const field_ty: Type = .fromInterned(field_ty_ip);733 const field_ty: Type = .fromInterned(field_ty_ip);
732 assert(!field_ty.isGenericPoison());734 assert(!field_ty.isGenericPoison());
733 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });735 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });
734 try sema.ensureLayoutResolved(field_ty);736 try sema.ensureLayoutResolved(field_ty, field_ty_src);
735 if (field_ty.zigTypeTag(zcu) == .@"opaque") {737 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
736 return sema.failWithOwnedErrorMsg(&block, msg: {738 return sema.failWithOwnedErrorMsg(&block, msg: {
737 const msg = try sema.errMsg(field_ty_src, "cannot directly embed opaque type '{f}' in union", .{field_ty.fmt(pt)});739 const msg = try sema.errMsg(field_ty_src, "cannot directly embed opaque type '{f}' in union", .{field_ty.fmt(pt)});
...@@ -889,7 +891,7 @@ fn resolvePackedUnionLayout(...@@ -889,7 +891,7 @@ fn resolvePackedUnionLayout(
889 const field_ty: Type = .fromInterned(field_ty_ip);891 const field_ty: Type = .fromInterned(field_ty_ip);
890 assert(!field_ty.isGenericPoison());892 assert(!field_ty.isGenericPoison());
891 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });893 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });
892 try sema.ensureLayoutResolved(field_ty);894 try sema.ensureLayoutResolved(field_ty, field_ty_src);
893 if (field_ty.zigTypeTag(zcu) == .@"opaque") {895 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
894 return sema.failWithOwnedErrorMsg(block, msg: {896 return sema.failWithOwnedErrorMsg(block, msg: {
895 const msg = try sema.errMsg(field_ty_src, "cannot directly embed opaque type '{f}' in union", .{field_ty.fmt(pt)});897 const msg = try sema.errMsg(field_ty_src, "cannot directly embed opaque type '{f}' in union", .{field_ty.fmt(pt)});
...@@ -995,6 +997,7 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -995,6 +997,7 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
995 assert(sema.owner.unwrap().type_layout == enum_ty.toIntern());997 assert(sema.owner.unwrap().type_layout == enum_ty.toIntern());
996998
997 const enum_obj = ip.loadEnumType(enum_ty.toIntern());999 const enum_obj = ip.loadEnumType(enum_ty.toIntern());
1000 assert(enum_obj.want_layout);
9981001
999 const maybe_parent_union_obj: ?InternPool.LoadedUnionType = un: {1002 const maybe_parent_union_obj: ?InternPool.LoadedUnionType = un: {
1000 if (enum_obj.owner_union == .none) break :un null;1003 if (enum_obj.owner_union == .none) break :un null;
...@@ -1002,6 +1005,7 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -1002,6 +1005,7 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1002 };1005 };
10031006
1004 const tracked_inst = enum_obj.zir_index.unwrap() orelse maybe_parent_union_obj.?.zir_index;1007 const tracked_inst = enum_obj.zir_index.unwrap() orelse maybe_parent_union_obj.?.zir_index;
1008 const zir_index = tracked_inst.resolve(ip) orelse return error.AnalysisFail;
10051009
1006 var block: Block = .{1010 var block: Block = .{
1007 .parent = null,1011 .parent = null,
...@@ -1040,7 +1044,7 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -1040,7 +1044,7 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1040 // Generated tag enums for declared unions do not yet have field names populated. It is1044 // Generated tag enums for declared unions do not yet have field names populated. It is
1041 // our job to populate them now.1045 // our job to populate them now.
1042 try sema.declareDependency(.{ .src_hash = union_obj.zir_index });1046 try sema.declareDependency(.{ .src_hash = union_obj.zir_index });
1043 const zir_union = sema.code.getUnionDecl(union_obj.zir_index.resolve(ip).?);1047 const zir_union = sema.code.getUnionDecl(zir_index);
1044 for (zir_union.field_names) |zir_field_name| {1048 for (zir_union.field_names) |zir_field_name| {
1045 const name_slice = sema.code.nullTerminatedString(zir_field_name);1049 const name_slice = sema.code.nullTerminatedString(zir_field_name);
1046 const name = try ip.getOrPutString(gpa, io, pt.tid, name_slice, .no_embedded_nulls);1050 const name = try ip.getOrPutString(gpa, io, pt.tid, name_slice, .no_embedded_nulls);
...@@ -1065,7 +1069,7 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -1065,7 +1069,7 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1065 } else {1069 } else {
1066 // Declared enums do not yet have field names populated. It is our job to populate them now.1070 // Declared enums do not yet have field names populated. It is our job to populate them now.
1067 try sema.declareDependency(.{ .src_hash = enum_obj.zir_index.unwrap().? });1071 try sema.declareDependency(.{ .src_hash = enum_obj.zir_index.unwrap().? });
1068 const zir_enum = sema.code.getEnumDecl(enum_obj.zir_index.unwrap().?.resolve(ip).?);1072 const zir_enum = sema.code.getEnumDecl(zir_index);
1069 for (zir_enum.field_names) |zir_field_name| {1073 for (zir_enum.field_names) |zir_field_name| {
1070 const name_slice = sema.code.nullTerminatedString(zir_field_name);1074 const name_slice = sema.code.nullTerminatedString(zir_field_name);
1071 const name = try ip.getOrPutString(gpa, io, pt.tid, name_slice, .no_embedded_nulls);1075 const name = try ip.getOrPutString(gpa, io, pt.tid, name_slice, .no_embedded_nulls);
...@@ -1087,7 +1091,6 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -1087,7 +1091,6 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1087 // Reification has no equivalent of 'union(enum(T))'.1091 // Reification has no equivalent of 'union(enum(T))'.
1088 break :ty null;1092 break :ty null;
1089 }1093 }
1090 const zir_index = union_obj.zir_index.resolve(ip).?;
1091 const zir_union = sema.code.getUnionDecl(zir_index);1094 const zir_union = sema.code.getUnionDecl(zir_index);
1092 if (zir_union.kind != .tagged_enum_explicit) {1095 if (zir_union.kind != .tagged_enum_explicit) {
1093 break :ty null; // int tag type will be inferred1096 break :ty null; // int tag type will be inferred
...@@ -1102,7 +1105,6 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -1102,7 +1105,6 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1102 const type_ref = try sema.resolveInlineBody(&block, tag_type_body, zir_index);1105 const type_ref = try sema.resolveInlineBody(&block, tag_type_body, zir_index);
1103 break :ty try sema.analyzeAsType(&block, tag_type_src, .enum_int_tag_type, type_ref);1106 break :ty try sema.analyzeAsType(&block, tag_type_src, .enum_int_tag_type, type_ref);
1104 } else ty: {1107 } else ty: {
1105 const zir_index = enum_obj.zir_index.unwrap().?.resolve(ip).?;
1106 const zir_enum = sema.code.getEnumDecl(zir_index);1108 const zir_enum = sema.code.getEnumDecl(zir_index);
1107 const tag_type_body = zir_enum.tag_type_body orelse {1109 const tag_type_body = zir_enum.tag_type_body orelse {
1108 break :ty null; // int tag type will be inferred1110 break :ty null; // int tag type will be inferred
...@@ -1147,8 +1149,6 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -1147,8 +1149,6 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1147 // There may be old field values in here from a previous update.1149 // There may be old field values in here from a previous update.
1148 field_value_map.get(ip).clearRetainingCapacity();1150 field_value_map.get(ip).clearRetainingCapacity();
11491151
1150 const zir_index = tracked_inst.resolve(ip).?;
1151
1152 // Map the enum (or union) decl instruction to provide the tag type as the result type1152 // Map the enum (or union) decl instruction to provide the tag type as the result type
1153 try sema.inst_map.ensureSpaceForInstructions(gpa, &.{zir_index});1153 try sema.inst_map.ensureSpaceForInstructions(gpa, &.{zir_index});
1154 sema.inst_map.putAssumeCapacity(zir_index, .fromIntern(int_tag_ty.toIntern()));1154 sema.inst_map.putAssumeCapacity(zir_index, .fromIntern(int_tag_ty.toIntern()));
src/Type.zig+14-1
...@@ -3044,7 +3044,20 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {...@@ -3044,7 +3044,20 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {
3044 .tuple_type => |tuple| for (tuple.types.get(&zcu.intern_pool)) |field_ty| {3044 .tuple_type => |tuple| for (tuple.types.get(&zcu.intern_pool)) |field_ty| {
3045 assertHasLayout(.fromInterned(field_ty), zcu);3045 assertHasLayout(.fromInterned(field_ty), zcu);
3046 },3046 },
3047 .struct_type, .union_type, .enum_type => {3047 .struct_type => {
3048 assert(zcu.intern_pool.loadStructType(ty.toIntern()).want_layout);
3049 const unit: InternPool.AnalUnit = .wrap(.{ .type_layout = ty.toIntern() });
3050 assert(!zcu.outdated.contains(unit));
3051 assert(!zcu.potentially_outdated.contains(unit));
3052 },
3053 .union_type => {
3054 assert(zcu.intern_pool.loadUnionType(ty.toIntern()).want_layout);
3055 const unit: InternPool.AnalUnit = .wrap(.{ .type_layout = ty.toIntern() });
3056 assert(!zcu.outdated.contains(unit));
3057 assert(!zcu.potentially_outdated.contains(unit));
3058 },
3059 .enum_type => {
3060 assert(zcu.intern_pool.loadEnumType(ty.toIntern()).want_layout);
3048 const unit: InternPool.AnalUnit = .wrap(.{ .type_layout = ty.toIntern() });3061 const unit: InternPool.AnalUnit = .wrap(.{ .type_layout = ty.toIntern() });
3049 assert(!zcu.outdated.contains(unit));3062 assert(!zcu.outdated.contains(unit));
3050 assert(!zcu.potentially_outdated.contains(unit));3063 assert(!zcu.potentially_outdated.contains(unit));
src/Value.zig+1-1
...@@ -2149,7 +2149,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh...@@ -2149,7 +2149,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
2149 const base_ptr = Value.fromInterned(field.base);2149 const base_ptr = Value.fromInterned(field.base);
2150 const base_ptr_ty = base_ptr.typeOf(zcu);2150 const base_ptr_ty = base_ptr.typeOf(zcu);
2151 const agg_ty = base_ptr_ty.childType(zcu);2151 const agg_ty = base_ptr_ty.childType(zcu);
2152 if (resolve_types) try opt_sema.?.ensureLayoutResolved(agg_ty);2152 if (resolve_types) try opt_sema.?.ensureLayoutResolved(agg_ty, .unneeded); // MLUGG TODO: unneeded is a hack
2153 const field_ty: Type, const field_align: InternPool.Alignment = switch (agg_ty.zigTypeTag(zcu)) {2153 const field_ty: Type, const field_align: InternPool.Alignment = switch (agg_ty.zigTypeTag(zcu)) {
2154 .@"struct", .@"union" => .{ agg_ty.fieldType(@intCast(field.index), zcu), agg_ty.resolvedFieldAlignment(@intCast(field.index), pt.zcu) },2154 .@"struct", .@"union" => .{ agg_ty.fieldType(@intCast(field.index), zcu), agg_ty.resolvedFieldAlignment(@intCast(field.index), pt.zcu) },
2155 .pointer => switch (field.index) {2155 .pointer => switch (field.index) {
src/Zcu.zig+23-74
...@@ -266,9 +266,6 @@ outdated_ready: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .empty,...@@ -266,9 +266,6 @@ outdated_ready: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .empty,
266/// it as outdated.266/// it as outdated.
267retryable_failures: std.ArrayList(AnalUnit) = .empty,267retryable_failures: std.ArrayList(AnalUnit) = .empty,
268268
269func_body_analysis_queued: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .empty,
270nav_val_analysis_queued: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .empty,
271
272/// These are the modules which we initially queue for analysis in `Compilation.update`.269/// These are the modules which we initially queue for analysis in `Compilation.update`.
273/// `resolveReferences` will use these as the root of its reachability traversal.270/// `resolveReferences` will use these as the root of its reachability traversal.
274analysis_roots_buffer: [5]*Package.Module,271analysis_roots_buffer: [5]*Package.Module,
...@@ -2814,9 +2811,6 @@ pub fn deinit(zcu: *Zcu) void {...@@ -2814,9 +2811,6 @@ pub fn deinit(zcu: *Zcu) void {
2814 zcu.outdated_ready.deinit(gpa);2811 zcu.outdated_ready.deinit(gpa);
2815 zcu.retryable_failures.deinit(gpa);2812 zcu.retryable_failures.deinit(gpa);
28162813
2817 zcu.func_body_analysis_queued.deinit(gpa);
2818 zcu.nav_val_analysis_queued.deinit(gpa);
2819
2820 zcu.test_functions.deinit(gpa);2814 zcu.test_functions.deinit(gpa);
28212815
2822 for (zcu.global_assembly.values()) |s| {2816 for (zcu.global_assembly.values()) |s| {
...@@ -3179,8 +3173,6 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni...@@ -3179,8 +3173,6 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni
3179/// recursive analysis (all of its previously-marked dependencies are already up-to-date), because3173/// recursive analysis (all of its previously-marked dependencies are already up-to-date), because
3180/// recursive analysis can cause over-analysis on incremental updates.3174/// recursive analysis can cause over-analysis on incremental updates.
3181pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {3175pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
3182 if (!zcu.comp.config.incremental) return null;
3183
3184 if (zcu.outdated_ready.count() > 0) {3176 if (zcu.outdated_ready.count() > 0) {
3185 const unit = zcu.outdated_ready.keys()[0];3177 const unit = zcu.outdated_ready.keys()[0];
3186 log.debug("findOutdatedToAnalyze: {f}", .{zcu.fmtAnalUnit(unit)});3178 log.debug("findOutdatedToAnalyze: {f}", .{zcu.fmtAnalUnit(unit)});
...@@ -3458,47 +3450,35 @@ pub fn mapOldZirToNew(...@@ -3458,47 +3450,35 @@ pub fn mapOldZirToNew(
3458/// The caller is responsible for ensuring the function decl itself is already3450/// The caller is responsible for ensuring the function decl itself is already
3459/// analyzed, and for ensuring it can exist at runtime (see3451/// analyzed, and for ensuring it can exist at runtime (see
3460/// `Type.fnHasRuntimeBitsSema`). This function does *not* guarantee that the body3452/// `Type.fnHasRuntimeBitsSema`). This function does *not* guarantee that the body
3461/// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`.3453/// will be analyzed when it returns: for that, see `PerThread.ensureFuncBodyUpToDate`.
3462pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func_index: InternPool.Index) !void {3454pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func: InternPool.Index) !void {
3455 const comp = zcu.comp;
3456 const gpa = comp.gpa;
3457 const io = comp.io;
3463 const ip = &zcu.intern_pool;3458 const ip = &zcu.intern_pool;
34643459 assert(func == ip.unwrapCoercedFunc(func)); // analyze the body of the original function, not a coerced one
3465 const func = zcu.funcInfo(func_index);3460 if (ip.setWantRuntimeFnAnalysis(io, func)) {
34663461 // This is the first reference to this function, so we must ensure it will be analyzed.
3467 assert(func.ty == func.uncoerced_ty); // analyze the body of the original function, not a coerced one3462 const unit: AnalUnit = .wrap(.{ .func = func });
34683463 try zcu.outdated.putNoClobber(gpa, unit, 0);
3469 if (zcu.func_body_analysis_queued.contains(func_index)) return;3464 try zcu.outdated_ready.putNoClobber(gpa, unit, {});
3470
3471 if (func.analysisUnordered(ip).is_analyzed) {
3472 if (!zcu.outdated.contains(.wrap(.{ .func = func_index })) and
3473 !zcu.potentially_outdated.contains(.wrap(.{ .func = func_index })))
3474 {
3475 // This function has been analyzed before and is definitely up-to-date.
3476 return;
3477 }
3478 }3465 }
3479
3480 try zcu.func_body_analysis_queued.ensureUnusedCapacity(zcu.gpa, 1);
3481 try zcu.comp.queueJob(.{ .analyze_unit = .wrap(.{ .func = func_index }) });
3482 zcu.func_body_analysis_queued.putAssumeCapacityNoClobber(func_index, {});
3483}3466}
34843467
3485pub fn ensureNavValAnalysisQueued(zcu: *Zcu, nav_id: InternPool.Nav.Index) !void {3468pub fn ensureNavValAnalysisQueued(zcu: *Zcu, nav: InternPool.Nav.Index) !void {
3469 const comp = zcu.comp;
3470 const gpa = comp.gpa;
3471 const io = comp.io;
3486 const ip = &zcu.intern_pool;3472 const ip = &zcu.intern_pool;
34873473 if (ip.setWantNavAnalysis(io, nav)) {
3488 if (zcu.nav_val_analysis_queued.contains(nav_id)) return;3474 // This is the first reference to this function, so we must ensure it will be analyzed.
34893475 try zcu.outdated.ensureUnusedCapacity(gpa, 2);
3490 if (ip.getNav(nav_id).status == .fully_resolved) {3476 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 2);
3491 if (!zcu.outdated.contains(.wrap(.{ .nav_val = nav_id })) and3477 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .nav_val = nav }), 0);
3492 !zcu.potentially_outdated.contains(.wrap(.{ .nav_val = nav_id })))3478 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .nav_ty = nav }), 0);
3493 {3479 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .nav_val = nav }), {});
3494 // This `Nav` has been analyzed before and is definitely up-to-date.3480 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .nav_ty = nav }), {});
3495 return;
3496 }
3497 }3481 }
3498
3499 try zcu.nav_val_analysis_queued.ensureUnusedCapacity(zcu.gpa, 1);
3500 try zcu.comp.queueJob(.{ .analyze_unit = .wrap(.{ .nav_val = nav_id }) });
3501 zcu.nav_val_analysis_queued.putAssumeCapacityNoClobber(nav_id, {});
3502}3482}
35033483
3504pub const ImportResult = struct {3484pub const ImportResult = struct {
...@@ -4035,37 +4015,6 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R...@@ -4035,37 +4015,6 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
40354015
4036 refs_log.debug("handle type '{f}'", .{Type.fromInterned(ty).containerTypeName(ip).fmt(ip)});4016 refs_log.debug("handle type '{f}'", .{Type.fromInterned(ty).containerTypeName(ip).fmt(ip)});
40374017
4038 // If this type undergoes type resolution, the corresponding `AnalUnit`s are automatically referenced.
4039 const has_layout: bool, const has_inits: bool = switch (ip.indexToKey(ty)) {
4040 .struct_type => .{ true, true },
4041 .union_type => .{ true, false },
4042 .enum_type => .{ false, true },
4043 .opaque_type => .{ false, false },
4044 else => unreachable,
4045 };
4046 if (has_layout) {
4047 // this should only be referenced by the type
4048 const unit: AnalUnit = .wrap(.{ .type_layout = ty });
4049 try units.putNoClobber(gpa, unit, referencer);
4050 }
4051 if (has_inits) {
4052 // this should only be referenced by the type
4053 const unit: AnalUnit = .wrap(.{ .struct_defaults = ty });
4054 try units.putNoClobber(gpa, unit, referencer);
4055 }
4056
4057 // If this is a union with a generated tag, its tag type is automatically referenced.
4058 // We don't add this reference for non-generated tags, as those will already be referenced via the union's type resolution, with a better source location.
4059 implicit_tag: {
4060 const loaded_union = zcu.typeToUnion(.fromInterned(ty)) orelse break :implicit_tag;
4061 const tag_ty = loaded_union.enum_tag_type;
4062 if (tag_ty == .none) break :implicit_tag;
4063 if (ip.indexToKey(tag_ty).enum_type != .generated_union_tag) break :implicit_tag;
4064 const gop = try types.getOrPut(gpa, tag_ty);
4065 if (gop.found_existing) break :implicit_tag;
4066 gop.value_ptr.* = referencer;
4067 }
4068
4069 // Queue any decls within this type which would be automatically analyzed.4018 // Queue any decls within this type which would be automatically analyzed.
4070 // Keep in sync with analysis queueing logic in `Zcu.PerThread.ScanDeclIter.scanDecl`.4019 // Keep in sync with analysis queueing logic in `Zcu.PerThread.ScanDeclIter.scanDecl`.
4071 const ns = Type.fromInterned(ty).getNamespace(zcu).unwrap().?;4020 const ns = Type.fromInterned(ty).getNamespace(zcu).unwrap().?;
src/Zcu/PerThread.zig+23-44
...@@ -719,20 +719,9 @@ pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) (Alloca...@@ -719,20 +719,9 @@ pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) (Alloca
719 });719 });
720 errdefer pt.destroyNamespace(new_namespace_index);720 errdefer pt.destroyNamespace(new_namespace_index);
721 try pt.scanNamespace(new_namespace_index, struct_decl.decls);721 try pt.scanNamespace(new_namespace_index, struct_decl.decls);
722 // MLUGG TODO: we could potentially revert this language change if we wanted? don't mind
723 try zcu.comp.queueJob(.{ .analyze_unit = .wrap(.{ .type_layout = wip.index }) });
724 try zcu.comp.queueJob(.{ .analyze_unit = .wrap(.{ .struct_defaults = wip.index }) });
725722
726 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);723 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
727724
728 try zcu.outdated.ensureUnusedCapacity(gpa, 2);
729 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 2);
730 errdefer comptime unreachable; // because we don't remove the `outdated` entries
731 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), 0);
732 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .struct_defaults = wip.index }), 0);
733 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .type_layout = wip.index }), {});
734 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .struct_defaults = wip.index }), {});
735
736 const file_root_type: Type = .fromInterned(wip.finish(ip, new_namespace_index));725 const file_root_type: Type = .fromInterned(wip.finish(ip, new_namespace_index));
737726
738 zcu.setFileRootType(file_index, file_root_type.toIntern());727 zcu.setFileRootType(file_index, file_root_type.toIntern());
...@@ -1075,11 +1064,12 @@ pub fn ensureTypeLayoutUpToDate(pt: Zcu.PerThread, ty: Type) Zcu.SemaError!void...@@ -1075,11 +1064,12 @@ pub fn ensureTypeLayoutUpToDate(pt: Zcu.PerThread, ty: Type) Zcu.SemaError!void
1075 assert(!zcu.analysis_in_progress.contains(anal_unit));1064 assert(!zcu.analysis_in_progress.contains(anal_unit));
10761065
1077 const was_outdated = zcu.outdated.swapRemove(anal_unit) or1066 const was_outdated = zcu.outdated.swapRemove(anal_unit) or
1078 zcu.potentially_outdated.swapRemove(anal_unit);1067 zcu.potentially_outdated.swapRemove(anal_unit) or
1068 zcu.intern_pool.setWantTypeLayout(zcu.comp.io, ty.toIntern());
10791069
1080 if (was_outdated) {1070 if (was_outdated) {
1081 _ = zcu.outdated_ready.swapRemove(anal_unit);1071 _ = zcu.outdated_ready.swapRemove(anal_unit);
1082 // `was_outdated` can be true in the initial update for comptime units, so this isn't a `dev.check`.1072 // `was_outdated` is true in the initial update, so this isn't a `dev.check`.
1083 if (dev.env.supports(.incremental)) {1073 if (dev.env.supports(.incremental)) {
1084 zcu.deleteUnitExports(anal_unit);1074 zcu.deleteUnitExports(anal_unit);
1085 zcu.deleteUnitReferences(anal_unit);1075 zcu.deleteUnitReferences(anal_unit);
...@@ -1182,16 +1172,13 @@ pub fn ensureStructDefaultsUpToDate(pt: Zcu.PerThread, ty: Type) Zcu.SemaError!v...@@ -1182,16 +1172,13 @@ pub fn ensureStructDefaultsUpToDate(pt: Zcu.PerThread, ty: Type) Zcu.SemaError!v
11821172
1183 assert(!zcu.analysis_in_progress.contains(anal_unit));1173 assert(!zcu.analysis_in_progress.contains(anal_unit));
11841174
1185 // Determine whether or not this type is outdated. For this kind of `AnalUnit`, that's
1186 // the only indicator as to whether or not analysis is required; when a struct/enum is
1187 // first created, it's marked as outdated.
1188
1189 const was_outdated = zcu.outdated.swapRemove(anal_unit) or1175 const was_outdated = zcu.outdated.swapRemove(anal_unit) or
1190 zcu.potentially_outdated.swapRemove(anal_unit);1176 zcu.potentially_outdated.swapRemove(anal_unit) or
1177 zcu.intern_pool.setWantStructDefaults(zcu.comp.io, ty.toIntern());
11911178
1192 if (was_outdated) {1179 if (was_outdated) {
1193 _ = zcu.outdated_ready.swapRemove(anal_unit);1180 _ = zcu.outdated_ready.swapRemove(anal_unit);
1194 // `was_outdated` can be true in the initial update for comptime units, so this isn't a `dev.check`.1181 // `was_outdated` is true in the initial update, so this isn't a `dev.check`.
1195 if (dev.env.supports(.incremental)) {1182 if (dev.env.supports(.incremental)) {
1196 zcu.deleteUnitExports(anal_unit);1183 zcu.deleteUnitExports(anal_unit);
1197 zcu.deleteUnitReferences(anal_unit);1184 zcu.deleteUnitReferences(anal_unit);
...@@ -1279,8 +1266,6 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu...@@ -1279,8 +1266,6 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
1279 const gpa = zcu.gpa;1266 const gpa = zcu.gpa;
1280 const ip = &zcu.intern_pool;1267 const ip = &zcu.intern_pool;
12811268
1282 _ = zcu.nav_val_analysis_queued.swapRemove(nav_id);
1283
1284 const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id });1269 const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id });
1285 const nav = ip.getNav(nav_id);1270 const nav = ip.getNav(nav_id);
12861271
...@@ -1288,6 +1273,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu...@@ -1288,6 +1273,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
12881273
1289 assert(!zcu.analysis_in_progress.contains(anal_unit));1274 assert(!zcu.analysis_in_progress.contains(anal_unit));
12901275
1276 try zcu.ensureNavValAnalysisQueued(nav_id);
1277
1291 // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the1278 // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the
1292 // status is `.unresolved`, which indicates that the value is outdated because it has *never*1279 // status is `.unresolved`, which indicates that the value is outdated because it has *never*
1293 // been analyzed so far.1280 // been analyzed so far.
...@@ -1317,10 +1304,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu...@@ -1317,10 +1304,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
1317 } else {1304 } else {
1318 // We can trust the current information about this unit.1305 // We can trust the current information about this unit.
1319 if (prev_failed) return error.AnalysisFail;1306 if (prev_failed) return error.AnalysisFail;
1320 switch (nav.status) {1307 assert(nav.status == .fully_resolved);
1321 .unresolved, .type_resolved => {},1308 return;
1322 .fully_resolved => return,
1323 }
1324 }1309 }
13251310
1326 if (zcu.comp.debugIncremental()) {1311 if (zcu.comp.debugIncremental()) {
...@@ -1488,9 +1473,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1488,9 +1473,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
14881473
1489 const maybe_ty: ?Type = if (zir_decl.type_body != null) ty: {1474 const maybe_ty: ?Type = if (zir_decl.type_body != null) ty: {
1490 // Since we have a type body, the type is resolved separately!1475 // Since we have a type body, the type is resolved separately!
1491 // Of course, we need to make sure we depend on it properly.1476 try sema.ensureNavResolved(&block, init_src, nav_id, .type);
1492 try sema.declareDependency(.{ .nav_ty = nav_id });
1493 try pt.ensureNavTypeUpToDate(nav_id);
1494 break :ty .fromInterned(ip.getNav(nav_id).typeOf(ip));1477 break :ty .fromInterned(ip.getNav(nav_id).typeOf(ip));
1495 } else null;1478 } else null;
14961479
...@@ -1602,7 +1585,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1602,7 +1585,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
16021585
1603 // This resolves the type of the resolved value, not that value itself. If `nav_val` is a struct type,1586 // This resolves the type of the resolved value, not that value itself. If `nav_val` is a struct type,
1604 // this resolves the type `type` (which needs no resolution), not the struct itself.1587 // this resolves the type `type` (which needs no resolution), not the struct itself.
1605 try sema.ensureLayoutResolved(nav_ty);1588 try sema.ensureLayoutResolved(nav_ty, init_src);
16061589
1607 const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(nav_val.toIntern())) {1590 const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(nav_val.toIntern())) {
1608 .func => |f| .{ true, f.owner_nav == nav_id }, // note that this lets function aliases reach codegen1591 .func => |f| .{ true, f.owner_nav == nav_id }, // note that this lets function aliases reach codegen
...@@ -1692,6 +1675,8 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc...@@ -1692,6 +1675,8 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
16921675
1693 assert(!zcu.analysis_in_progress.contains(anal_unit));1676 assert(!zcu.analysis_in_progress.contains(anal_unit));
16941677
1678 try zcu.ensureNavValAnalysisQueued(nav_id);
1679
1695 const type_resolved_by_value: bool = from_val: {1680 const type_resolved_by_value: bool = from_val: {
1696 const analysis = nav.analysis orelse break :from_val false;1681 const analysis = nav.analysis orelse break :from_val false;
1697 const inst_resolved = analysis.zir_index.resolveFull(ip) orelse break :from_val false;1682 const inst_resolved = analysis.zir_index.resolveFull(ip) orelse break :from_val false;
...@@ -1733,10 +1718,8 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc...@@ -1733,10 +1718,8 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
1733 } else {1718 } else {
1734 // We can trust the current information about this unit.1719 // We can trust the current information about this unit.
1735 if (prev_failed) return error.AnalysisFail;1720 if (prev_failed) return error.AnalysisFail;
1736 switch (nav.status) {1721 assert(nav.status != .unresolved);
1737 .unresolved => {},1722 return;
1738 .type_resolved, .fully_resolved => return,
1739 }
1740 }1723 }
17411724
1742 if (zcu.comp.debugIncremental()) {1725 if (zcu.comp.debugIncremental()) {
...@@ -1869,7 +1852,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr...@@ -1869,7 +1852,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
1869 break :ty .fromInterned(type_ref.toInterned().?);1852 break :ty .fromInterned(type_ref.toInterned().?);
1870 };1853 };
18711854
1872 try sema.ensureLayoutResolved(resolved_ty);1855 try sema.ensureLayoutResolved(resolved_ty, ty_src);
18731856
1874 // In the case where the type is specified, this function is also responsible for resolving1857 // In the case where the type is specified, this function is also responsible for resolving
1875 // the pointer modifiers, i.e. alignment, linksection, addrspace.1858 // the pointer modifiers, i.e. alignment, linksection, addrspace.
...@@ -1929,8 +1912,6 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z...@@ -1929,8 +1912,6 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
1929 const gpa = zcu.gpa;1912 const gpa = zcu.gpa;
1930 const ip = &zcu.intern_pool;1913 const ip = &zcu.intern_pool;
19311914
1932 _ = zcu.func_body_analysis_queued.swapRemove(func_index);
1933
1934 const anal_unit: AnalUnit = .wrap(.{ .func = func_index });1915 const anal_unit: AnalUnit = .wrap(.{ .func = func_index });
19351916
1936 log.debug("ensureFuncBodyUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});1917 log.debug("ensureFuncBodyUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
...@@ -1942,7 +1923,8 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z...@@ -1942,7 +1923,8 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
1942 assert(func.ty == func.uncoerced_ty); // analyze the body of the original function, not a coerced one1923 assert(func.ty == func.uncoerced_ty); // analyze the body of the original function, not a coerced one
19431924
1944 const was_outdated = zcu.outdated.swapRemove(anal_unit) or1925 const was_outdated = zcu.outdated.swapRemove(anal_unit) or
1945 zcu.potentially_outdated.swapRemove(anal_unit);1926 zcu.potentially_outdated.swapRemove(anal_unit) or
1927 ip.setWantRuntimeFnAnalysis(zcu.comp.io, func_index);
19461928
1947 const prev_failed = zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit);1929 const prev_failed = zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit);
19481930
...@@ -1958,10 +1940,8 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z...@@ -1958,10 +1940,8 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
1958 _ = zcu.transitive_failed_analysis.swapRemove(anal_unit);1940 _ = zcu.transitive_failed_analysis.swapRemove(anal_unit);
1959 } else {1941 } else {
1960 // We can trust the current information about this function.1942 // We can trust the current information about this function.
1961 if (prev_failed) {1943 if (prev_failed) return error.AnalysisFail;
1962 return error.AnalysisFail;1944 return;
1963 }
1964 if (func.analysisUnordered(ip).is_analyzed) return;
1965 }1945 }
19661946
1967 if (zcu.comp.debugIncremental()) {1947 if (zcu.comp.debugIncremental()) {
...@@ -3026,7 +3006,6 @@ fn analyzeFuncBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.Sem...@@ -3026,7 +3006,6 @@ fn analyzeFuncBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.Sem
3026 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});3006 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});
3027 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));3007 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
30283008
3029 func.setAnalyzed(ip, io);
3030 if (func.analysisUnordered(ip).inferred_error_set) {3009 if (func.analysisUnordered(ip).inferred_error_set) {
3031 func.setResolvedErrorSet(ip, io, .none);3010 func.setResolvedErrorSet(ip, io, .none);
3032 }3011 }
...@@ -3144,7 +3123,7 @@ fn analyzeFuncBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.Sem...@@ -3144,7 +3123,7 @@ fn analyzeFuncBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.Sem
3144 const param_ty: Type = .fromInterned(fn_ty_info.param_types.get(ip)[runtime_param_index]);3123 const param_ty: Type = .fromInterned(fn_ty_info.param_types.get(ip)[runtime_param_index]);
3145 runtime_param_index += 1;3124 runtime_param_index += 1;
31463125
3147 try sema.ensureLayoutResolved(param_ty);3126 try sema.ensureLayoutResolved(param_ty, inner_block.src(.{ .func_decl_param_ty = @intCast(zir_param_index) }));
3148 if (try param_ty.onePossibleValue(pt)) |opv| {3127 if (try param_ty.onePossibleValue(pt)) |opv| {
3149 gop.value_ptr.* = .fromValue(opv);3128 gop.value_ptr.* = .fromValue(opv);
3150 continue;3129 continue;
...@@ -3161,7 +3140,7 @@ fn analyzeFuncBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.Sem...@@ -3161,7 +3140,7 @@ fn analyzeFuncBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.Sem
3161 });3140 });
3162 }3141 }
31633142
3164 try sema.ensureLayoutResolved(sema.fn_ret_ty);3143 try sema.ensureLayoutResolved(sema.fn_ret_ty, inner_block.src(.{ .node_offset_fn_type_ret_ty = .zero }));
31653144
3166 const last_arg_index = inner_block.instructions.items.len;3145 const last_arg_index = inner_block.instructions.items.len;
31673146