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 {
546546 analysis: ?struct {
547547 namespace: NamespaceIndex,
548548 zir_index: TrackedInst.Index,
549 /// Initially `false`. Set to `true` by `setWantNavAnalysis`.
550 wanted: bool,
549551 },
550552 status: union(enum) {
551553 /// This `Nav` is pending semantic analysis.
......@@ -743,7 +745,7 @@ pub const Nav = struct {
743745 const Repr = struct {
744746 name: NullTerminatedString,
745747 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`.
747749 analysis_namespace: OptionalNamespaceIndex,
748750 analysis_zir_index: TrackedInst.Index.Optional,
749751 /// Populated only if `bits.status != .unresolved`.
......@@ -762,7 +764,7 @@ pub const Nav = struct {
762764 @"addrspace": std.builtin.AddressSpace,
763765 /// Populated only if `bits.status == .type_resolved`.
764766 is_threadlocal: bool,
765 _: u1 = 0,
767 want_analysis: bool,
766768 };
767769
768770 fn unpack(repr: Repr) Nav {
......@@ -772,6 +774,7 @@ pub const Nav = struct {
772774 .analysis = if (repr.analysis_namespace.unwrap()) |namespace| .{
773775 .namespace = namespace,
774776 .zir_index = repr.analysis_zir_index.unwrap().?,
777 .wanted = repr.bits.want_analysis,
775778 } else a: {
776779 assert(repr.analysis_zir_index == .none);
777780 break :a null;
......@@ -824,6 +827,7 @@ pub const Nav = struct {
824827 .alignment = .none,
825828 .@"addrspace" = .generic,
826829 .is_threadlocal = false,
830 .want_analysis = if (nav.analysis) |a| a.wanted else false,
827831 },
828832 .type_resolved => |r| .{
829833 .status = if (r.is_extern_decl) .type_resolved_extern_decl else .type_resolved,
......@@ -831,6 +835,7 @@ pub const Nav = struct {
831835 .alignment = r.alignment,
832836 .@"addrspace" = r.@"addrspace",
833837 .is_threadlocal = r.is_threadlocal,
838 .want_analysis = if (nav.analysis) |a| a.wanted else false,
834839 },
835840 .fully_resolved => |r| .{
836841 .status = .fully_resolved,
......@@ -838,6 +843,7 @@ pub const Nav = struct {
838843 .alignment = r.alignment,
839844 .@"addrspace" = r.@"addrspace",
840845 .is_threadlocal = false,
846 .want_analysis = if (nav.analysis) |a| a.wanted else false,
841847 },
842848 },
843849 };
......@@ -2412,17 +2418,6 @@ pub const Key = union(enum) {
24122418 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
24132419 }
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
24262421 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
24272422 fn zirBodyInstPtr(func: Func, ip: *const InternPool) *TrackedInst.Index {
24282423 const extra = ip.getLocalShared(func.tid).extra.acquire();
......@@ -3314,6 +3309,25 @@ pub const LoadedStructType = struct {
33143309 /// May be `undefined` if `layout != .@"packed"`.
33153310 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
33173331 // The remaining fields are only valid once the struct's layout is resolved.
33183332 field_name_map: MapIndex,
33193333 field_names: NullTerminatedString.Slice,
......@@ -3490,6 +3504,16 @@ pub const LoadedUnionType = struct {
34903504 /// or populate `enum_tag_type`.
34913505 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
34933517 // The remaining fields are only valid once the union's layout is resolved.
34943518 field_types: Index.Slice,
34953519 field_aligns: Alignment.Slice,
......@@ -3532,6 +3556,16 @@ pub const LoadedEnumType = struct {
35323556 int_tag_mode: BackingTypeMode,
35333557 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
35353569 // The remaining fields are only valid once the enum's layout is resolved.
35363570 int_tag_type: Index,
35373571 field_name_map: MapIndex,
......@@ -3669,6 +3703,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
36693703 },
36703704 .packed_backing_mode = undefined,
36713705
3706 .want_layout = extra.data.flags.want_layout,
3707 .want_defaults = extra.data.flags.want_defaults,
3708
36723709 .field_name_map = extra.data.field_name_map,
36733710 .field_names = field_names,
36743711 .field_types = field_types,
......@@ -3690,15 +3727,15 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
36903727 };
36913728 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, item.data);
36923729 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) {
36943731 .reified => captures: {
36953732 extra_index += 2; // type_hash: PackedU64
36963733 break :captures .empty;
36973734 },
3698 _ => .{
3735 _ => |n| .{
36993736 .tid = unwrapped_index.tid,
37003737 .start = extra_index,
3701 .len = @intFromEnum(extra.data.captures_len),
3738 .len = @intFromEnum(n),
37023739 },
37033740 };
37043741 extra_index += captures.len;
......@@ -3723,13 +3760,16 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
37233760 return .{
37243761 .zir_index = extra.data.zir_index,
37253762 .captures = captures,
3726 .is_reified = extra.data.captures_len == .reified,
3763 .is_reified = extra.data.bits.captures_len == .reified,
37273764 .name = extra.data.name,
37283765 .name_nav = extra.data.name_nav,
37293766 .namespace = extra.data.namespace,
37303767 .layout = .@"packed",
37313768 .packed_backing_mode = backing_mode,
37323769
3770 .want_layout = extra.data.bits.want_layout,
3771 .want_defaults = extra.data.bits.want_defaults,
3772
37333773 .field_name_map = extra.data.field_name_map,
37343774 .field_names = field_names,
37353775 .field_types = field_types,
......@@ -3813,6 +3853,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
38133853 .packed_backing_mode = undefined,
38143854 .packed_backing_int_type = undefined,
38153855 .reified_field_names = reified_field_names,
3856 .want_layout = extra.data.flags.want_layout,
38163857 .field_types = field_types,
38173858 .field_aligns = field_aligns,
38183859 .has_no_possible_value = extra.data.flags.has_no_possible_value,
......@@ -3828,19 +3869,19 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
38283869 };
38293870 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, item.data);
38303871 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) {
38323873 .reified => captures: {
38333874 extra_index += 2; // type_hash: PackedU64
38343875 break :captures .empty;
38353876 },
3836 _ => .{
3877 _ => |n| .{
38373878 .tid = unwrapped_index.tid,
38383879 .start = extra_index,
3839 .len = @intFromEnum(extra.data.captures_len),
3880 .len = @intFromEnum(n),
38403881 },
38413882 };
38423883 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) .{
38443885 .tid = unwrapped_index.tid,
38453886 .start = extra_index,
38463887 .len = extra.data.fields_len,
......@@ -3855,7 +3896,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
38553896 return .{
38563897 .zir_index = extra.data.zir_index,
38573898 .captures = captures,
3858 .is_reified = extra.data.captures_len == .reified,
3899 .is_reified = extra.data.bits.captures_len == .reified,
38593900 .name = extra.data.name,
38603901 .name_nav = extra.data.name_nav,
38613902 .namespace = extra.data.namespace,
......@@ -3866,6 +3907,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
38663907 .packed_backing_mode = backing_mode,
38673908 .packed_backing_int_type = extra.data.backing_int_type,
38683909 .reified_field_names = reified_field_names,
3910 .want_layout = extra.data.bits.want_layout,
38693911 .field_types = field_types,
38703912 .field_aligns = .empty,
38713913 .has_no_possible_value = undefined,
......@@ -3891,7 +3933,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
38913933 };
38923934 const extra = extraDataTrail(extra_list, Tag.TypeEnum, item.data);
38933935 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) {
38953937 .reified => info: {
38963938 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[extra_index]);
38973939 extra_index += 1;
......@@ -3903,13 +3945,13 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
39033945 extra_index += 1;
39043946 break :info .{ .none, .empty, owner_union };
39053947 },
3906 _ => info: {
3948 _ => |n| info: {
39073949 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[extra_index]);
39083950 extra_index += 1;
39093951 const captures: CaptureValue.Slice = .{
39103952 .tid = unwrapped_index.tid,
39113953 .start = extra_index,
3912 .len = @intFromEnum(extra.data.captures_len),
3954 .len = @intFromEnum(n),
39133955 };
39143956 extra_index += captures.len;
39153957 break :info .{ zir_index.toOptional(), captures, .none };
......@@ -3935,7 +3977,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
39353977 return .{
39363978 .zir_index = zir_index,
39373979 .captures = captures,
3938 .is_reified = extra.data.captures_len == .reified,
3980 .is_reified = extra.data.bits.captures_len == .reified,
39393981 .owner_union = owner_union,
39403982 .name = extra.data.name,
39413983 .name_nav = extra.data.name_nav,
......@@ -3943,6 +3985,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
39433985 .int_tag_type = extra.data.int_tag_type,
39443986 .int_tag_mode = if (explicit_int_tag) .explicit else .auto,
39453987 .nonexhaustive = nonexhaustive,
3988 .want_layout = extra.data.bits.want_layout,
39463989 .field_name_map = extra.data.field_name_map,
39473990 .field_value_map = field_value_map,
39483991 .field_names = field_names,
......@@ -5629,7 +5672,10 @@ pub const Tag = enum(u8) {
56295672 /// Alignment of the whole struct. Always `.none` until layout resolved.
56305673 alignment: Alignment,
56315674
5632 _: u16 = 0,
5675 want_layout: bool,
5676 want_defaults: bool,
5677
5678 _: u14 = 0,
56335679 };
56345680 };
56355681
......@@ -5641,10 +5687,7 @@ pub const Tag = enum(u8) {
56415687 /// 4. field_default: Index // if item tag implies field defaults; for each `fields_len`
56425688 pub const TypeStructPacked = struct {
56435689 zir_index: TrackedInst.Index,
5644 captures_len: enum(u32) {
5645 reified = std.math.maxInt(u32),
5646 _,
5647 },
5690 bits: Bits,
56485691
56495692 name: NullTerminatedString,
56505693 name_nav: Nav.Index.Optional,
......@@ -5655,6 +5698,15 @@ pub const Tag = enum(u8) {
56555698
56565699 fields_len: u32,
56575700 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 };
56585710 };
56595711
56605712 /// For declared unions, field names are intentionally omitted because they are available in
......@@ -5718,7 +5770,9 @@ pub const Tag = enum(u8) {
57185770 /// Alignment of the whole union. Always `.none` until layout resolved.
57195771 alignment: Alignment,
57205772
5721 _: u15 = 0,
5773 want_layout: bool,
5774
5775 _: u14 = 0,
57225776 };
57235777 };
57245778
......@@ -5734,10 +5788,7 @@ pub const Tag = enum(u8) {
57345788 /// 3. field_type: Index // for each `fields_len`
57355789 pub const TypeUnionPacked = struct {
57365790 zir_index: TrackedInst.Index,
5737 captures_len: enum(u32) {
5738 reified = std.math.maxInt(u32),
5739 _,
5740 },
5791 bits: Bits,
57415792
57425793 name: NullTerminatedString,
57435794 name_nav: Nav.Index.Optional,
......@@ -5753,6 +5804,14 @@ pub const Tag = enum(u8) {
57535804 /// to store it directly. This is also necessary for `dumpStatsFallible` to
57545805 /// work on unresolved types.
57555806 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 };
57565815 };
57575816
57585817 /// Trailing:
......@@ -5764,11 +5823,7 @@ pub const Tag = enum(u8) {
57645823 /// 5. field_name: NullTerminatedString // for each `fields_len`
57655824 /// 6. field_value: Index // if tag is not `.type_enum_auto`; for each `fields_len`
57665825 pub const TypeEnum = struct {
5767 captures_len: enum(u32) {
5768 reified = std.math.maxInt(u32),
5769 generated_union_tag = std.math.maxInt(u32) - 1,
5770 _,
5771 },
5826 bits: Bits,
57725827
57735828 name: NullTerminatedString,
57745829 name_nav: Nav.Index.Optional,
......@@ -5780,6 +5835,15 @@ pub const Tag = enum(u8) {
57805835
57815836 fields_len: u32,
57825837 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 };
57835847 };
57845848
57855849 /// Trailing:
......@@ -5812,7 +5876,7 @@ pub const BackingTypeMode = enum(u1) {
58125876/// equality or hashing, except for `inferred_error_set` which is considered
58135877/// to be part of the type of the function.
58145878pub const FuncAnalysis = packed struct(u32) {
5815 is_analyzed: bool,
5879 want_runtime_analysis: bool,
58165880 branch_hint: std.builtin.BranchHint,
58175881 is_noinline: bool,
58185882 has_error_trace: bool,
......@@ -6597,17 +6661,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
65976661 => .{ .struct_type = ns: {
65986662 const extra_list = unwrapped_index.getExtra(ip);
65996663 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) {
66016665 .reified => .{ .reified = .{
66026666 .zir_index = extra.data.zir_index,
66036667 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
66046668 } },
6605 _ => .{ .declared = .{
6669 _ => |len| .{ .declared = .{
66066670 .zir_index = extra.data.zir_index,
66076671 .captures = .{ .owned = .{
66086672 .tid = unwrapped_index.tid,
66096673 .start = extra.end,
6610 .len = @intFromEnum(extra.data.captures_len),
6674 .len = @intFromEnum(len),
66116675 } },
66126676 } },
66136677 };
......@@ -6637,17 +6701,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
66376701 .type_union_packed_auto, .type_union_packed_explicit => .{ .union_type = ns: {
66386702 const extra_list = unwrapped_index.getExtra(ip);
66396703 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) {
66416705 .reified => .{ .reified = .{
66426706 .zir_index = extra.data.zir_index,
66436707 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
66446708 } },
6645 _ => .{ .declared = .{
6709 _ => |len| .{ .declared = .{
66466710 .zir_index = extra.data.zir_index,
66476711 .captures = .{ .owned = .{
66486712 .tid = unwrapped_index.tid,
66496713 .start = extra.end,
6650 .len = @intFromEnum(extra.data.captures_len),
6714 .len = @intFromEnum(len),
66516715 } },
66526716 } },
66536717 };
......@@ -6655,7 +6719,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
66556719 .type_enum_auto, .type_enum_explicit, .type_enum_nonexhaustive => .{ .enum_type = ns: {
66566720 const extra_list = unwrapped_index.getExtra(ip);
66576721 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) {
66596723 .reified => .{ .reified = .{
66606724 .zir_index = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
66616725 .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(),
......@@ -6663,12 +6727,12 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
66636727 .generated_union_tag => .{ .generated_union_tag = owner_union: {
66646728 break :owner_union @enumFromInt(extra_list.view().items(.@"0")[extra.end]);
66656729 } },
6666 _ => .{ .declared = .{
6730 _ => |len| .{ .declared = .{
66676731 .zir_index = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
66686732 .captures = .{ .owned = .{
66696733 .tid = unwrapped_index.tid,
66706734 .start = extra.end + 1,
6671 .len = @intFromEnum(extra.data.captures_len),
6735 .len = @intFromEnum(len),
66726736 } },
66736737 } },
66746738 };
......@@ -8138,7 +8202,11 @@ pub fn getDeclaredStructType(
81388202
81398203 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
81408204 .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 },
81428210 .name = undefined, // set by `finish`
81438211 .name_nav = undefined, // set by `finish`
81448212 .namespace = undefined, // set by `finish`
......@@ -8204,6 +8272,8 @@ pub fn getDeclaredStructType(
82048272 .comptime_only = false,
82058273 .has_runtime_bits = false,
82068274 .alignment = .none,
8275 .want_layout = false,
8276 .want_defaults = false,
82078277 },
82088278 });
82098279 if (ini.captures.len != 0) {
......@@ -8281,7 +8351,11 @@ pub fn getReifiedStructType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Pe
82818351
82828352 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
82838353 .zir_index = ini.zir_index,
8284 .captures_len = .reified,
8354 .bits = .{
8355 .captures_len = .reified,
8356 .want_layout = false,
8357 .want_defaults = false,
8358 },
82858359 .name = undefined, // set by `finish`
82868360 .name_nav = undefined, // set by `finish`
82878361 .namespace = undefined, // set by `finish`
......@@ -8352,6 +8426,8 @@ pub fn getReifiedStructType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Pe
83528426 .comptime_only = false,
83538427 .has_runtime_bits = false,
83548428 .alignment = .none,
8429 .want_layout = false,
8430 .want_defaults = false,
83558431 },
83568432 });
83578433 _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash)); // type_hash
......@@ -8451,7 +8527,10 @@ pub fn getDeclaredUnionType(
84518527
84528528 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnionPacked{
84538529 .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 },
84558534 .name = undefined, // set by `finish`
84568535 .name_nav = undefined, // set by `finish`
84578536 .namespace = undefined, // set by `finish`
......@@ -8509,6 +8588,7 @@ pub fn getDeclaredUnionType(
85098588 .comptime_only = false,
85108589 .has_runtime_bits = false,
85118590 .alignment = .none,
8591 .want_layout = false,
85128592 },
85138593 });
85148594 if (ini.captures.len > 0) {
......@@ -8572,7 +8652,10 @@ pub fn getReifiedUnionType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Per
85728652
85738653 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnionPacked{
85748654 .zir_index = ini.zir_index,
8575 .captures_len = .reified,
8655 .bits = .{
8656 .captures_len = .reified,
8657 .want_layout = false,
8658 },
85768659 .name = undefined, // set by `finish`
85778660 .name_nav = undefined, // set by `finish`
85788661 .namespace = undefined, // set by `finish`
......@@ -8633,6 +8716,7 @@ pub fn getReifiedUnionType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Per
86338716 .comptime_only = false,
86348717 .has_runtime_bits = false,
86358718 .alignment = .none,
8719 .want_layout = false,
86368720 },
86378721 });
86388722 _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash));
......@@ -8723,7 +8807,10 @@ pub fn getDeclaredEnumType(
87238807 (if (have_values) ini.fields_len else 0)); // field_value
87248808
87258809 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 },
87278814 .name = undefined, // set by `finish`
87288815 .name_nav = undefined, // set by `finish`
87298816 .namespace = undefined, // set by `finish`
......@@ -8795,7 +8882,10 @@ pub fn getReifiedEnumType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerT
87958882 (if (have_values) ini.fields_len else 0)); // field_value
87968883
87978884 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeEnum{
8798 .captures_len = .reified,
8885 .bits = .{
8886 .captures_len = .reified,
8887 .want_layout = false,
8888 },
87998889 .name = undefined, // set by `finish`
88008890 .name_nav = undefined, // set by `finish`
88018891 .namespace = undefined, // set by `finish`
......@@ -8865,7 +8955,10 @@ pub fn getGeneratedEnumTagType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu
88658955 (if (have_values) ini.fields_len else 0)); // field_value
88668956
88678957 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 },
88698962 .name = undefined, // set by `finish`
88708963 .name_nav = undefined, // set by `finish`
88718964 .namespace = undefined, // set by `finish`
......@@ -9249,7 +9342,7 @@ pub fn getFuncDecl(
92499342
92509343 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
92519344 .analysis = .{
9252 .is_analyzed = false,
9345 .want_runtime_analysis = false,
92539346 .branch_hint = .none,
92549347 .is_noinline = key.is_noinline,
92559348 .has_error_trace = false,
......@@ -9359,7 +9452,7 @@ pub fn getFuncDeclIes(
93599452
93609453 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
93619454 .analysis = .{
9362 .is_analyzed = false,
9455 .want_runtime_analysis = false,
93639456 .branch_hint = .none,
93649457 .is_noinline = key.is_noinline,
93659458 .has_error_trace = false,
......@@ -9557,7 +9650,7 @@ pub fn getFuncInstance(
95579650
95589651 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
95599652 .analysis = .{
9560 .is_analyzed = false,
9653 .want_runtime_analysis = false,
95619654 .branch_hint = .none,
95629655 .is_noinline = arg.is_noinline,
95639656 .has_error_trace = false,
......@@ -9658,7 +9751,7 @@ fn getFuncInstanceIes(
96589751
96599752 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
96609753 .analysis = .{
9661 .is_analyzed = false,
9754 .want_runtime_analysis = false,
96629755 .branch_hint = .none,
96639756 .is_noinline = arg.is_noinline,
96649757 .has_error_trace = false,
......@@ -9902,9 +9995,6 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
99029995 TrackedInst.Index,
99039996 TrackedInst.Index.Optional,
99049997 ComptimeAllocIndex,
9905 @FieldType(Tag.TypeStructPacked, "captures_len"),
9906 @FieldType(Tag.TypeUnionPacked, "captures_len"),
9907 @FieldType(Tag.TypeEnum, "captures_len"),
99089998 => @intFromEnum(@field(item, field.name)),
99099999
991010000 u32,
......@@ -9916,6 +10006,9 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
991610006 Tag.TypePointer.PackedOffset,
991710007 Tag.TypeUnion.Flags,
991810008 Tag.TypeStruct.Flags,
10009 Tag.TypeStructPacked.Bits,
10010 Tag.TypeUnionPacked.Bits,
10011 Tag.TypeEnum.Bits,
991910012 => @bitCast(@field(item, field.name)),
992010013
992110014 else => @compileError("bad field type: " ++ @typeName(field.type)),
......@@ -9967,9 +10060,6 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
996710060 TrackedInst.Index,
996810061 TrackedInst.Index.Optional,
996910062 ComptimeAllocIndex,
9970 @FieldType(Tag.TypeStructPacked, "captures_len"),
9971 @FieldType(Tag.TypeUnionPacked, "captures_len"),
9972 @FieldType(Tag.TypeEnum, "captures_len"),
997310063 => @enumFromInt(extra_item),
997410064
997510065 u32,
......@@ -9981,6 +10071,9 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
998110071 Tag.TypeUnion.Flags,
998210072 Tag.TypeStruct.Flags,
998310073 FuncAnalysis,
10074 Tag.TypeStructPacked.Bits,
10075 Tag.TypeUnionPacked.Bits,
10076 Tag.TypeEnum.Bits,
998410077 => @bitCast(extra_item),
998510078
998610079 else => @compileError("bad field type: " ++ @typeName(field.type)),
......@@ -10750,7 +10843,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1075010843 .type_struct_packed_auto, .type_struct_packed_explicit => b: {
1075110844 var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".fields.len;
1075210845 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
10753 switch (extra.data.captures_len) {
10846 switch (extra.data.bits.captures_len) {
1075410847 .reified => n += 2, // type_hash: PackedU64
1075510848 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
1075610849 }
......@@ -10761,7 +10854,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1076110854 .type_struct_packed_auto_defaults, .type_struct_packed_explicit_defaults => b: {
1076210855 var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".fields.len;
1076310856 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
10764 switch (extra.data.captures_len) {
10857 switch (extra.data.bits.captures_len) {
1076510858 .reified => n += 2, // type_hash: PackedU64
1076610859 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
1076710860 }
......@@ -10790,7 +10883,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1079010883 .type_union_packed_auto, .type_union_packed_explicit => b: {
1079110884 var n: usize = @typeInfo(Tag.TypeUnionPacked).@"struct".fields.len;
1079210885 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, data);
10793 switch (extra.data.captures_len) {
10886 switch (extra.data.bits.captures_len) {
1079410887 .reified => n += 2, // type_hash: PackedU64
1079510888 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
1079610889 }
......@@ -10800,7 +10893,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1080010893 .type_enum_auto => b: {
1080110894 var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len;
1080210895 const extra = extraData(extra_list, Tag.TypeEnum, data);
10803 switch (extra.captures_len) {
10896 switch (extra.bits.captures_len) {
1080410897 .generated_union_tag => n += 1, // owner_union: Index
1080510898 .reified => {
1080610899 n += 1; // zir_index: TrackedInst.Index,
......@@ -10817,7 +10910,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1081710910 .type_enum_explicit, .type_enum_nonexhaustive => b: {
1081810911 var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len;
1081910912 const extra = extraData(extra_list, Tag.TypeEnum, data);
10820 switch (extra.captures_len) {
10913 switch (extra.bits.captures_len) {
1082110914 .generated_union_tag => n += 1, // owner_union: Index
1082210915 .reified => {
1082310916 n += 1; // zir_index: TrackedInst.Index,
......@@ -11204,6 +11297,7 @@ pub fn createDeclNav(
1120411297 .analysis = .{
1120511298 .namespace = namespace,
1120611299 .zir_index = zir_index,
11300 .wanted = false,
1120711301 },
1120811302 .status = .unresolved,
1120911303 }));
......@@ -12829,3 +12923,175 @@ pub fn resolveEnumLayout(
1282912923
1283012924 extra_items[item.data + std.meta.fieldIndex(Tag.TypeEnum, "int_tag_type").?] = @intFromEnum(int_tag_type);
1283112925}
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(
32583258 } else .none;
32593259
32603260 if (small.has_type) {
3261 try sema.ensureLayoutResolved(var_ty);
3261 try sema.ensureLayoutResolved(var_ty, ty_src);
32623262 if (block.isComptime() or small.is_comptime or var_ty.comptimeOnly(zcu)) {
32633263 return sema.analyzeComptimeAlloc(block, var_src, var_ty, alignment);
32643264 }
......@@ -3322,7 +3322,7 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
33223322 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
33233323 const var_src = block.nodeOffset(inst_data.src_node);
33243324 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);
33263326 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
33273327}
33283328
......@@ -3743,7 +3743,7 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
37433743 const var_src = block.nodeOffset(inst_data.src_node);
37443744
37453745 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);
37473747 if (block.isComptime() or var_ty.comptimeOnly(zcu)) {
37483748 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
37493749 }
......@@ -3775,7 +3775,7 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
37753775 const var_src = block.nodeOffset(inst_data.src_node);
37763776
37773777 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);
37793779 if (block.isComptime()) {
37803780 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
37813781 }
......@@ -4132,8 +4132,9 @@ fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcL
41324132fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
41334133 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
41344134 const ptr = sema.resolveInst(un_node.operand);
4135 try sema.ensureLayoutResolved(sema.typeOf(ptr).childType(sema.pt.zcu));
4136 return sema.optEuBasePtrInit(block, ptr, block.nodeOffset(un_node.src_node));
4135 const src = 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);
41374138}
41384139
41394140fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -4518,7 +4519,7 @@ fn validateStructInit(
45184519 if (struct_ty.structFieldIsComptime(i, zcu)) continue;
45194520
45204521 if (!struct_ty.isTuple(zcu)) {
4521 try sema.ensureStructDefaultsResolved(struct_ty);
4522 try sema.ensureStructDefaultsResolved(struct_ty, init_src);
45224523 }
45234524
45244525 const default_val = struct_ty.structFieldDefaultValue(i, zcu) orelse {
......@@ -4642,7 +4643,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
46424643 }
46434644
46444645 const elem_ty = operand_ty.childType(zcu);
4645 try sema.ensureLayoutResolved(elem_ty);
4646 try sema.ensureLayoutResolved(elem_ty, src);
46464647
46474648 if (try elem_ty.onePossibleValue(pt) != null) {
46484649 // No need to validate the actual pointer value, we don't need it!
......@@ -7025,7 +7026,7 @@ fn analyzeCall(
70257026
70267027 break :ret_ty full_ty;
70277028 };
7028 try sema.ensureLayoutResolved(resolved_ret_ty);
7029 try sema.ensureLayoutResolved(resolved_ret_ty, func_ret_ty_src);
70297030
70307031 // If we've discovered after evaluating arguments that a generic function instantiation is
70317032 // comptime-only, then we can mark the block as comptime *now*.
......@@ -7122,7 +7123,7 @@ fn analyzeCall(
71227123 .generic_owner = func_val.?.toIntern(),
71237124 .comptime_args = comptime_args,
71247125 });
7125 try sema.ensureLayoutResolved(.fromInterned(ip.typeOf(func_instance)));
7126 try sema.ensureLayoutResolved(.fromInterned(ip.typeOf(func_instance)), call_src);
71267127 if (zcu.comp.debugIncremental()) {
71277128 const nav = ip.indexToKey(func_instance).func.owner_nav;
71287129 const gop = try zcu.incremental_debug_state.navs.getOrPut(gpa, nav);
......@@ -7196,7 +7197,7 @@ fn analyzeCall(
71967197 return .unreachable_value;
71977198 }
71987199
7199 try sema.ensureLayoutResolved(sema.typeOf(maybe_opv));
7200 try sema.ensureLayoutResolved(sema.typeOf(maybe_opv), func_ret_ty_src);
72007201 if (try sema.typeOf(maybe_opv).onePossibleValue(pt)) |opv| {
72017202 return .fromValue(opv);
72027203 } else {
......@@ -7270,7 +7271,7 @@ fn analyzeCall(
72707271 // We're about to do an inline call; if the return type expression was generic, the return type
72717272 // may not be resolved yet. It's correct to resolve it because the function is going to return a
72727273 // value of this type.
7273 try sema.ensureLayoutResolved(resolved_ret_ty);
7274 try sema.ensureLayoutResolved(resolved_ret_ty, func_ret_ty_src);
72747275
72757276 // For an inline call, we depend on the source code of the whole function definition.
72767277 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
75327533 const zcu = pt.zcu;
75337534 const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;
75347535 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);
75367536 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(zcu);
75377537 assert(indexable_ty.isIndexable(zcu)); // validated by a previous instruction
75387538 const elem_ty = switch (indexable_ty.zigTypeTag(zcu)) {
......@@ -8040,7 +8040,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
80408040 if (dest_ty.zigTypeTag(zcu) != .@"enum") {
80418041 return sema.fail(block, src, "expected enum, found '{f}'", .{dest_ty.fmt(pt)});
80428042 }
8043 try sema.ensureLayoutResolved(dest_ty);
8043 try sema.ensureLayoutResolved(dest_ty, src);
80448044 _ = try sema.checkIntType(block, operand_src, operand_ty);
80458045
80468046 if (sema.resolveValue(operand)) |int_val| {
......@@ -8103,7 +8103,7 @@ fn zirOptionalPayloadPtr(
81038103
81048104 const ptr_ty = sema.typeOf(optional_ptr);
81058105 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
81088108 return sema.analyzeOptionalPayloadPtr(block, src, optional_ptr, safety_check, false);
81098109}
......@@ -8313,7 +8313,7 @@ fn zirErrUnionPayloadPtr(
83138313
83148314 const ptr_ty = sema.typeOf(operand);
83158315 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
83188318 return sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
83198319}
......@@ -9022,6 +9022,7 @@ fn funcCommon(
90229022 const io = comp.io;
90239023 const ip = &zcu.intern_pool;
90249024
9025 const src = block.nodeOffset(src_node_offset);
90259026 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });
90269027 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });
90279028
......@@ -9091,7 +9092,7 @@ fn funcCommon(
90919092 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
90929093 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
90939094 }));
9094 try sema.ensureLayoutResolved(func_val.typeOf(zcu));
9095 try sema.ensureLayoutResolved(func_val.typeOf(zcu), src);
90959096 return .fromValue(func_val);
90969097 }
90979098
......@@ -9106,7 +9107,7 @@ fn funcCommon(
91069107 });
91079108
91089109 if (has_body) {
9109 try sema.ensureLayoutResolved(.fromInterned(func_ty));
9110 try sema.ensureLayoutResolved(.fromInterned(func_ty), src);
91109111 return .fromIntern(try ip.getFuncDecl(gpa, io, pt.tid, .{
91119112 .owner_nav = sema.owner.unwrap().nav_val,
91129113 .ty = func_ty,
......@@ -9762,7 +9763,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
97629763 return sema.failWithOwnedErrorMsg(block, msg);
97639764 }
97649765 try sema.checkIndexable(block, src, indexable_ty);
9765 try sema.ensureLayoutResolved(indexable_ty.childType(zcu));
9766 try sema.ensureLayoutResolved(indexable_ty.childType(zcu), src);
97669767 return sema.elemPtrOneLayerOnly(block, src, array_ptr, elem_index, src, false, false);
97679768}
97689769
......@@ -9983,7 +9984,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
99839984 err_union_ty.fmt(pt),
99849985 });
99859986 }
9986 try sema.ensureLayoutResolved(err_union_ty);
9987 try sema.ensureLayoutResolved(err_union_ty, operand_src);
99879988
99889989 const non_err_cond = if (non_err_case.operand_is_ref)
99899990 try sema.analyzePtrIsNonErr(block, operand_src, eu_maybe_ptr)
......@@ -11287,7 +11288,7 @@ fn validateSwitchBlock(
1128711288 }
1128811289 break :operand_ty raw_operand_ty;
1128911290 };
11290 try sema.ensureLayoutResolved(operand_ty);
11291 try sema.ensureLayoutResolved(operand_ty, operand_src);
1129111292
1129211293 const item_ty: Type = item_ty: {
1129311294 switch (operand_ty.zigTypeTag(zcu)) {
......@@ -12870,7 +12871,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1287012871 const name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
1287112872 const ty = try sema.resolveType(block, ty_src, extra.lhs);
1287212873 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);
1287412875 const ip = &zcu.intern_pool;
1287512876
1287612877 const has_field = hf: {
......@@ -15270,7 +15271,7 @@ fn analyzeArithmetic(
1527015271 else => return sema.failWithInvalidPtrArithmetic(block, src, "pointer-integer", "addition and subtraction"),
1527115272 };
1527215273
15273 try sema.ensureLayoutResolved(lhs_ty.childType(zcu));
15274 try sema.ensureLayoutResolved(lhs_ty.childType(zcu), src);
1527415275 return sema.analyzePtrArithmetic(block, src, lhs, rhs, air_tag, lhs_src, rhs_src);
1527515276 },
1527615277 }
......@@ -15964,7 +15965,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1596415965 .@"anyframe",
1596515966 => {},
1596615967 }
15967 try sema.ensureLayoutResolved(ty);
15968 try sema.ensureLayoutResolved(ty, operand_src);
1596815969 return .fromValue(try pt.intValue(.comptime_int, ty.abiSize(zcu)));
1596915970}
1597015971
......@@ -16005,7 +16006,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1600516006 .@"anyframe",
1600616007 => {},
1600716008 }
16008 try sema.ensureLayoutResolved(operand_ty);
16009 try sema.ensureLayoutResolved(operand_ty, operand_src);
1600916010 return .fromValue(try pt.intValue(.comptime_int, operand_ty.bitSize(zcu)));
1601016011}
1601116012
......@@ -16251,7 +16252,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1625116252 const type_info_ty = try sema.getBuiltinType(src, .Type);
1625216253 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;
1625316254
16254 try sema.ensureLayoutResolved(ty);
16255 try sema.ensureLayoutResolved(ty, src);
1625516256
1625616257 if (ty.typeDeclInst(zcu)) |type_decl_inst| {
1625716258 try sema.declareDependency(.{ .namespace = type_decl_inst });
......@@ -16412,7 +16413,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1641216413 if (info.flags.alignment.toByteUnits()) |b| break :bytes b;
1641316414 const elem_ty: Type = .fromInterned(info.child);
1641416415 // 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);
1641616417 break :bytes elem_ty.abiAlignment(zcu).toByteUnits().?;
1641716418 });
1641816419
......@@ -16873,7 +16874,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1687316874 .struct_type => ip.loadStructType(ty.toIntern()),
1687416875 else => unreachable,
1687516876 };
16876 try sema.ensureStructDefaultsResolved(ty); // can't do this sooner, since it's not allowed on tuples
16877 try sema.ensureStructDefaultsResolved(ty, src); // can't do this sooner, since it's not allowed on tuples
1687716878 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);
1687816879
1687916880 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
1829418295 elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size,
1829518296 });
1829618297 }
18297 try sema.ensureLayoutResolved(elem_ty);
18298 try sema.ensureLayoutResolved(elem_ty, elem_ty_src);
1829818299 const elem_bit_size = elem_ty.bitSize(zcu);
1829918300 if (elem_bit_size > host_size * 8 - bit_offset) {
1830018301 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
1836318364 const pt = sema.pt;
1836418365 const zcu = pt.zcu;
1836518366
18366 try sema.ensureLayoutResolved(obj_ty);
18367 try sema.ensureLayoutResolved(obj_ty, ty_src);
1836718368
1836818369 switch (obj_ty.zigTypeTag(zcu)) {
1836918370 .@"struct" => return sema.structInitEmpty(block, obj_ty, src, src),
......@@ -18428,7 +18429,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
1842818429 });
1842918430 } else ty_operand;
1843018431
18431 try sema.ensureLayoutResolved(init_ty);
18432 try sema.ensureLayoutResolved(init_ty, src);
1843218433
1843318434 const obj_ty = init_ty.optEuBaseType(zcu);
1843418435
......@@ -18544,7 +18545,7 @@ fn zirStructInit(
1854418545 // The type wasn't actually known, so treat this as an anon struct init.
1854518546 return sema.structInitAnon(block, src, inst, .typed_init, extra.data, extra.end, is_ref);
1854618547 };
18547 try sema.ensureLayoutResolved(result_ty);
18548 try sema.ensureLayoutResolved(result_ty, src);
1854818549 const resolved_ty = result_ty.optEuBaseType(zcu);
1854918550
1855018551 if (resolved_ty.zigTypeTag(zcu) == .@"struct") {
......@@ -18751,7 +18752,7 @@ fn finishStructInit(
1875118752 continue;
1875218753 }
1875318754
18754 try sema.ensureStructDefaultsResolved(struct_ty);
18755 try sema.ensureStructDefaultsResolved(struct_ty, init_src);
1875518756
1875618757 const field_default: InternPool.Index = d: {
1875718758 if (struct_type.field_defaults.len == 0) break :d .none;
......@@ -18979,17 +18980,11 @@ fn structInitAnon(
1897918980 });
1898018981 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
1898818983 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
1898918984 },
1899018985 };
1899118986 try sema.addTypeReferenceEntry(src, struct_ty);
18992 try sema.ensureLayoutResolved(struct_ty);
18987 try sema.ensureLayoutResolved(struct_ty, src);
1899318988
1899418989 _ = opt_runtime_index orelse {
1899518990 const struct_val = try pt.aggregateValue(struct_ty, values);
......@@ -19308,7 +19303,7 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
1930819303 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);
1930919304 const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);
1931019305 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);
1931219307 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);
1931319308}
1931419309
......@@ -19328,7 +19323,7 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
1932819323 const aggregate_ty = wrapped_aggregate_ty.optEuBaseType(zcu);
1932919324 const zir_field_name = sema.code.nullTerminatedString(extra.name_start);
1933019325 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);
1933219327 return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);
1933319328}
1933419329
......@@ -19431,7 +19426,7 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1943119426 if (ty.isNoReturn(zcu)) {
1943219427 return sema.fail(block, operand_src, "no align available for type '{f}'", .{ty.fmt(sema.pt)});
1943319428 }
19434 try sema.ensureLayoutResolved(ty);
19429 try sema.ensureLayoutResolved(ty, operand_src);
1943519430 return .fromValue(try pt.intValue(.comptime_int, ty.abiAlignment(zcu).toByteUnits().?));
1943619431}
1943719432
......@@ -19912,7 +19907,7 @@ fn zirReifyFn(
1991219907 const param_attrs_arr = try sema.derefSliceAsArray(block, param_attrs_src, param_attrs_slice, .{ .simple = .fn_param_attrs });
1991319908
1991419909 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
1991719912 const fn_attrs_uncoerced = sema.resolveInst(extra.fn_attrs);
1991819913 const fn_attrs_coerced = try sema.coerce(block, fn_attrs_ty, fn_attrs_uncoerced, fn_attrs_src);
......@@ -19937,7 +19932,7 @@ fn zirReifyFn(
1993719932 param_types_src,
1993819933 fn_attrs.@"callconv",
1993919934 );
19940 try sema.ensureLayoutResolved(param_ty);
19935 try sema.ensureLayoutResolved(param_ty, param_types_src);
1994119936 if (param_ty.comptimeOnly(zcu)) {
1994219937 return sema.fail(block, param_attrs_src, "cannot reify function type with comptime-only parameter type '{f}'", .{param_ty.fmt(pt)});
1994319938 }
......@@ -20253,14 +20248,6 @@ fn zirReifyStruct(
2025320248 });
2025420249 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));
2025520250 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
2026520252 return .fromIntern(wip.finish(ip, new_namespace_index));
2026620253 },
......@@ -20482,15 +20469,6 @@ fn zirReifyUnion(
2048220469 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
2048320470 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
2049420472 return .fromIntern(wip.finish(ip, new_namespace_index));
2049520473 },
2049620474 }
......@@ -20643,15 +20621,6 @@ fn zirReifyEnum(
2064320621 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));
2064420622 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
2065520624 return .fromIntern(wip.finish(ip, new_namespace_index));
2065620625 },
2065720626 }
......@@ -20874,7 +20843,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2087420843 const elem_ty = ptr_ty.nullablePtrElem(zcu);
2087520844
2087620845 // We'll need to validate the pointer alignment.
20877 try sema.ensureLayoutResolved(elem_ty);
20846 try sema.ensureLayoutResolved(elem_ty, src);
2087820847 const ptr_align = ptr_ty.ptrAlignment(zcu);
2087920848
2088020849 if (ptr_ty.isSlice(zcu)) {
......@@ -21217,8 +21186,8 @@ fn ptrCastFull(
2121721186 const src_info = operand_ty.ptrInfo(zcu);
2121821187 const dest_info = dest_ty.ptrInfo(zcu);
2121921188
21220 try sema.ensureLayoutResolved(.fromInterned(src_info.child));
21221 try sema.ensureLayoutResolved(.fromInterned(dest_info.child));
21189 try sema.ensureLayoutResolved(.fromInterned(src_info.child), operand_src);
21190 try sema.ensureLayoutResolved(.fromInterned(dest_info.child), src);
2122221191
2122321192 const DestSliceLen = union(enum) {
2122421193 undef,
......@@ -21989,7 +21958,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
2198921958 const ty = try sema.resolveType(block, ty_src, extra.lhs);
2199021959 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
2199421963 const pt = sema.pt;
2199521964 const zcu = pt.zcu;
......@@ -23072,7 +23041,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2307223041 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, true);
2307323042 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
2307723046 switch (order) {
2307823047 .release, .acq_rel => {
......@@ -23392,7 +23361,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2339223361 return sema.fail(block, inst_src, "expected single pointer type, found '{f}'", .{parent_ptr_ty.fmt(pt)});
2339323362 }
2339423363 const parent_ty: Type = .fromInterned(parent_ptr_info.child);
23395 try sema.ensureLayoutResolved(parent_ty);
23364 try sema.ensureLayoutResolved(parent_ty, inst_src);
2339623365 switch (parent_ty.zigTypeTag(zcu)) {
2339723366 .@"struct", .@"union" => {},
2339823367 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(
2400223971 const dest_elem_ty = dest_ty.indexableElem(zcu);
2400323972 const src_elem_ty = src_ty.indexableElem(zcu);
2400423973
24005 try sema.ensureLayoutResolved(dest_elem_ty);
24006 try sema.ensureLayoutResolved(src_elem_ty);
23974 try sema.ensureLayoutResolved(dest_elem_ty, dest_src);
23975 try sema.ensureLayoutResolved(src_elem_ty, src_src);
2400723976
2400823977 const imc = try sema.coerceInMemoryAllowed(
2400923978 block,
......@@ -25518,7 +25487,7 @@ fn fieldPtrLoad(
2551825487 const zcu = pt.zcu;
2551925488 const object_ptr_ty = sema.typeOf(object_ptr);
2552025489 const pointee_ty = object_ptr_ty.childType(zcu);
25521 try sema.ensureLayoutResolved(pointee_ty); // MLUGG TODO
25490 try sema.ensureLayoutResolved(pointee_ty, src); // MLUGG TODO
2552225491 if (try pointee_ty.onePossibleValue(pt)) |opv| {
2552325492 const object: Air.Inst.Ref = .fromValue(opv);
2552425493 return fieldVal(sema, block, src, object, field_name, field_name_src);
......@@ -25654,7 +25623,7 @@ fn fieldVal(
2565425623 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
2565525624 return inst;
2565625625 }
25657 try sema.ensureLayoutResolved(child_type);
25626 try sema.ensureLayoutResolved(child_type, src);
2565825627 if (child_type.unionTagType(zcu)) |enum_ty| {
2565925628 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index_usize| {
2566025629 const field_index: u32 = @intCast(field_index_usize);
......@@ -25667,7 +25636,7 @@ fn fieldVal(
2566725636 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
2566825637 return inst;
2566925638 }
25670 try sema.ensureLayoutResolved(child_type);
25639 try sema.ensureLayoutResolved(child_type, src);
2567125640 const field_index_usize = child_type.enumFieldIndex(field_name, zcu) orelse
2567225641 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
2567325642 const field_index: u32 = @intCast(field_index_usize);
......@@ -25693,7 +25662,7 @@ fn fieldVal(
2569325662 },
2569425663 .@"struct" => if (is_pointer_to) {
2569525664 // 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);
2569725666 const field_ptr = try sema.structFieldPtr(block, src, object, field_name, field_name_src, inner_ty, false);
2569825667 return sema.analyzeLoad(block, src, field_ptr, object_src);
2569925668 } else {
......@@ -25701,7 +25670,7 @@ fn fieldVal(
2570125670 },
2570225671 .@"union" => if (is_pointer_to) {
2570325672 // 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);
2570525674 const field_ptr = try sema.unionFieldPtr(block, src, object, field_name, field_name_src, inner_ty, false);
2570625675 return sema.analyzeLoad(block, src, field_ptr, object_src);
2570725676 } else {
......@@ -25884,7 +25853,7 @@ fn fieldPtr(
2588425853 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
2588525854 return inst;
2588625855 }
25887 try sema.ensureLayoutResolved(child_type);
25856 try sema.ensureLayoutResolved(child_type, src);
2588825857 if (child_type.unionTagType(zcu)) |enum_ty| {
2588925858 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index| {
2589025859 const field_index_u32: u32 = @intCast(field_index);
......@@ -25898,7 +25867,7 @@ fn fieldPtr(
2589825867 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
2589925868 return inst;
2590025869 }
25901 try sema.ensureLayoutResolved(child_type);
25870 try sema.ensureLayoutResolved(child_type, src);
2590225871 const field_index = child_type.enumFieldIndex(field_name, zcu) orelse {
2590325872 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
2590425873 };
......@@ -25920,7 +25889,7 @@ fn fieldPtr(
2592025889 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)
2592125890 else
2592225891 object_ptr;
25923 try sema.ensureLayoutResolved(inner_ty);
25892 try sema.ensureLayoutResolved(inner_ty, src);
2592425893 const field_ptr = try sema.structFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty, initializing);
2592525894 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
2592625895 return field_ptr;
......@@ -25930,7 +25899,7 @@ fn fieldPtr(
2593025899 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)
2593125900 else
2593225901 object_ptr;
25933 try sema.ensureLayoutResolved(inner_ty);
25902 try sema.ensureLayoutResolved(inner_ty, src);
2593425903 const field_ptr = try sema.unionFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty, initializing);
2593525904 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
2593625905 return field_ptr;
......@@ -25974,7 +25943,7 @@ fn fieldCallBind(
2597425943 // Optionally dereference a second pointer to get the concrete type.
2597525944 const is_double_ptr = inner_ty.zigTypeTag(zcu) == .pointer and inner_ty.ptrSize(zcu) == .one;
2597625945 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);
2597825947 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;
2597925948 const object_ptr = if (is_double_ptr)
2598025949 try sema.analyzeLoad(block, src, raw_ptr, src)
......@@ -26661,7 +26630,7 @@ fn elemPtr(
2666126630 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{f}'", .{indexable_ptr_ty.fmt(pt)}),
2666226631 };
2666326632 try sema.checkIndexable(block, src, indexable_ty);
26664 try sema.ensureLayoutResolved(indexable_ty);
26633 try sema.ensureLayoutResolved(indexable_ty, src);
2666526634
2666626635 const elem_ptr = switch (indexable_ty.zigTypeTag(zcu)) {
2666726636 .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(
2667326642 },
2667426643 else => {
2667526644 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);
2667726646 return elemPtrOneLayerOnly(sema, block, src, indexable, elem_index, elem_index_src, init, oob_safety);
2667826647 },
2667926648 };
......@@ -26769,7 +26738,7 @@ fn elemVal(
2676926738 switch (indexable_ty.zigTypeTag(zcu)) {
2677026739 .pointer => {
2677126740 const child_ty = indexable_ty.childType(zcu);
26772 try sema.ensureLayoutResolved(child_ty);
26741 try sema.ensureLayoutResolved(child_ty, src);
2677326742 switch (indexable_ty.ptrSize(zcu)) {
2677426743 .slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
2677526744 .many, .c => {
......@@ -27293,7 +27262,7 @@ fn coerceExtra(
2729327262 const target = zcu.getTarget();
2729427263
2729527264 inst_ty.assertHasLayout(zcu);
27296 try sema.ensureLayoutResolved(dest_ty);
27265 try sema.ensureLayoutResolved(dest_ty, inst_src);
2729727266
2729827267 // If the types are the same, we can return the operand.
2729927268 if (dest_ty.eql(inst_ty, zcu))
......@@ -28657,8 +28626,8 @@ fn coerceInMemoryAllowedFns(
2865728626 } };
2865828627 }
2865928628
28660 try sema.ensureLayoutResolved(src_ty);
28661 try sema.ensureLayoutResolved(dest_ty);
28629 try sema.ensureLayoutResolved(src_ty, src_src);
28630 try sema.ensureLayoutResolved(dest_ty, dest_src);
2866228631 const src_is_runtime = src_ty.fnHasRuntimeBits(zcu);
2866328632 const dest_is_runtime = dest_ty.fnHasRuntimeBits(zcu);
2866428633 if (src_is_runtime != dest_is_runtime) return .{ .fn_generic = !dest_is_runtime };
......@@ -28712,7 +28681,7 @@ fn coerceInMemoryAllowedFns(
2871228681 const src_is_comptime = src_info.paramIsComptime(@intCast(param_i));
2871328682 const dest_is_comptime = dest_info.paramIsComptime(@intCast(param_i));
2871428683 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);
2871628685 if (!dest_is_mut and src_is_comptime and !dest_is_comptime and dest_param_ty.comptimeOnly(zcu)) {
2871728686 // A parameter which is marked `comptime` can drop that annotation if the type is comptime-only.
2871828687 // The function remains generic, and the parameter is going to be comptime-resolved either way,
......@@ -28940,11 +28909,11 @@ fn coerceInMemoryAllowedPtrs(
2894028909 dest_info.child != src_info.child)
2894128910 {
2894228911 const src_align = if (src_info.flags.alignment == .none) a: {
28943 try sema.ensureLayoutResolved(src_child);
28912 try sema.ensureLayoutResolved(src_child, src_src);
2894428913 break :a src_child.abiAlignment(zcu);
2894528914 } else src_info.flags.alignment;
2894628915 const dest_align = if (dest_info.flags.alignment == .none) a: {
28947 try sema.ensureLayoutResolved(dest_child);
28916 try sema.ensureLayoutResolved(dest_child, dest_src);
2894828917 break :a dest_child.abiAlignment(zcu);
2894928918 } else dest_info.flags.alignment;
2895028919 if (dest_align.compare(if (dest_is_mut) .neq else .gt, src_align)) {
......@@ -29294,7 +29263,7 @@ fn bitCast(
2929429263 const old_ty = sema.typeOf(inst);
2929529264
2929629265 old_ty.assertHasLayout(zcu);
29297 try sema.ensureLayoutResolved(dest_ty);
29266 try sema.ensureLayoutResolved(dest_ty, inst_src);
2929829267
2929929268 const dest_bits = dest_ty.bitSize(zcu);
2930029269 const old_bits = old_ty.bitSize(zcu);
......@@ -29908,7 +29877,7 @@ fn analyzeNavVal(
2990829877 return sema.analyzeLoad(block, src, ref, src);
2990929878}
2991029879
29911fn addReferenceEntry(
29880pub fn addReferenceEntry(
2991229881 sema: *Sema,
2991329882 opt_block: ?*Block,
2991429883 src: LazySrcLoc,
......@@ -30176,7 +30145,7 @@ fn analyzeLoad(
3017630145 return sema.fail(block, ptr_src, "cannot load opaque type '{f}'", .{elem_ty.fmt(pt)});
3017730146 }
3017830147
30179 try sema.ensureLayoutResolved(elem_ty);
30148 try sema.ensureLayoutResolved(elem_ty, src);
3018030149 if (try elem_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
3018130150
3018230151 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
......@@ -30561,7 +30530,7 @@ fn analyzeSlice(
3056130530 else => return sema.fail(block, src, "slice of non-array type '{f}'", .{ptr_ptr_child_ty.fmt(pt)}),
3056230531 }
3056330532
30564 try sema.ensureLayoutResolved(elem_ty);
30533 try sema.ensureLayoutResolved(elem_ty, src);
3056530534
3056630535 const ptr = if (slice_ty.isSlice(zcu))
3056730536 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,
3402433993 .type => if (uncoerced_val.typeOf(zcu).zigTypeTag(zcu) != .type) {
3402533994 return sema.fail(block, src, "{s}.{s} is not a type", .{ parent_name, name });
3402633995 } else val: {
34027 try sema.ensureLayoutResolved(uncoerced_val.toType());
33996 try sema.ensureLayoutResolved(uncoerced_val.toType(), src);
3402833997 break :val uncoerced_val;
3402933998 },
3403033999 .func => val: {
......@@ -34271,20 +34240,9 @@ fn zirStructDecl(
3427134240 });
3427234241 errdefer pt.destroyNamespace(new_namespace_index);
3427334242 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
3427834244 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
3428834246 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
3428934247 },
3429034248 };
......@@ -34364,17 +34322,8 @@ fn zirUnionDecl(
3436434322
3436534323 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
3437034325 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
3437834327 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
3437934328 },
3438034329 };
......@@ -34434,17 +34383,8 @@ fn zirEnumDecl(
3443434383
3443534384 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
3444034386 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
3444834388 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
3444934389 },
3445034390 };
src/Sema/LowerZon.zig+6-5
......@@ -300,7 +300,7 @@ fn checkTypeInner(
300300 } else {
301301 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
302302 if (gop.found_existing) return;
303 try sema.ensureLayoutResolved(ty);
303 try sema.ensureLayoutResolved(ty, self.import_loc);
304304 const struct_info = zcu.typeToStruct(ty).?;
305305 for (struct_info.field_types.get(ip)) |field_type| {
306306 try self.checkTypeInner(.fromInterned(field_type), null, visited);
......@@ -309,7 +309,7 @@ fn checkTypeInner(
309309 .@"union" => {
310310 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
311311 if (gop.found_existing) return;
312 try sema.ensureLayoutResolved(ty);
312 try sema.ensureLayoutResolved(ty, self.import_loc);
313313 const union_info = zcu.typeToUnion(ty).?;
314314 for (union_info.field_types.get(ip)) |field_type| {
315315 if (field_type != .void_type) {
......@@ -646,6 +646,7 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I
646646 const gpa = comp.gpa;
647647 const io = comp.io;
648648 const ip = &pt.zcu.intern_pool;
649 try self.sema.ensureLayoutResolved(res_ty, self.import_loc);
649650 switch (node.get(self.file.zoir.?)) {
650651 .enum_literal => |field_name| {
651652 const field_name_interned = try ip.getOrPutString(
......@@ -768,8 +769,8 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
768769 const io = comp.io;
769770 const ip = &pt.zcu.intern_pool;
770771
771 try self.sema.ensureLayoutResolved(res_ty);
772 try self.sema.ensureStructDefaultsResolved(res_ty);
772 try self.sema.ensureLayoutResolved(res_ty, self.import_loc);
773 try self.sema.ensureStructDefaultsResolved(res_ty, self.import_loc);
773774 const struct_info = self.sema.pt.zcu.typeToStruct(res_ty).?;
774775
775776 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.
919920 const gpa = comp.gpa;
920921 const io = comp.io;
921922 const ip = &pt.zcu.intern_pool;
922 try self.sema.ensureLayoutResolved(res_ty);
923 try self.sema.ensureLayoutResolved(res_ty, self.import_loc);
923924 const union_info = pt.zcu.typeToUnion(res_ty).?;
924925 const enum_tag_info = ip.loadEnumType(union_info.enum_tag_type);
925926
src/Sema/bitcast.zig+3-3
......@@ -80,7 +80,7 @@ fn bitCastInner(
8080 const val_ty = val.typeOf(zcu);
8181
8282 val_ty.assertHasLayout(zcu);
83 try sema.ensureLayoutResolved(dest_ty);
83 dest_ty.assertHasLayout(zcu);
8484
8585 assert(val_ty.hasWellDefinedLayout(zcu));
8686
......@@ -138,8 +138,8 @@ fn bitCastSpliceInner(
138138 const val_ty = val.typeOf(zcu);
139139 const splice_val_ty = splice_val.typeOf(zcu);
140140
141 try sema.ensureLayoutResolved(val_ty);
142 try sema.ensureLayoutResolved(splice_val_ty);
141 val_ty.assertHasLayout(zcu);
142 splice_val_ty.assertHasLayout(zcu);
143143
144144 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");
1919/// Adds incremental dependencies tracking any required type resolution.
2020/// MLUGG TODO: to make the langspec non-stupid, we need to call this from WAY fewer places (the conditions need to be less specific).
2121/// 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 {
2323 const pt = sema.pt;
2424 const zcu = pt.zcu;
2525 const ip = &zcu.intern_pool;
......@@ -35,20 +35,21 @@ pub fn ensureLayoutResolved(sema: *Sema, ty: Type) SemaError!void {
3535
3636 .func_type => |func_type| {
3737 for (func_type.param_types.get(ip)) |param_ty| {
38 try ensureLayoutResolved(sema, .fromInterned(param_ty));
38 try ensureLayoutResolved(sema, .fromInterned(param_ty), src);
3939 }
40 try ensureLayoutResolved(sema, .fromInterned(func_type.return_type));
40 try ensureLayoutResolved(sema, .fromInterned(func_type.return_type), src);
4141 },
4242
43 .array_type => |arr| return ensureLayoutResolved(sema, .fromInterned(arr.child)),
44 .vector_type => |vec| return ensureLayoutResolved(sema, .fromInterned(vec.child)),
45 .opt_type => |child| return ensureLayoutResolved(sema, .fromInterned(child)),
46 .error_union_type => |eu| return ensureLayoutResolved(sema, .fromInterned(eu.payload_type)),
43 .array_type => |arr| return ensureLayoutResolved(sema, .fromInterned(arr.child), src),
44 .vector_type => |vec| return ensureLayoutResolved(sema, .fromInterned(vec.child), src),
45 .opt_type => |child| return ensureLayoutResolved(sema, .fromInterned(child), src),
46 .error_union_type => |eu| return ensureLayoutResolved(sema, .fromInterned(eu.payload_type), src),
4747 .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);
4949 },
5050 .struct_type, .union_type, .enum_type => {
5151 try sema.declareDependency(.{ .type_layout = ty.toIntern() });
52 try sema.addReferenceEntry(null, src, .wrap(.{ .type_layout = ty.toIntern() }));
5253 if (zcu.analysis_in_progress.contains(.wrap(.{ .type_layout = ty.toIntern() }))) {
5354 // TODO: better error message
5455 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(
......@@ -89,13 +90,14 @@ pub fn ensureLayoutResolved(sema: *Sema, ty: Type) SemaError!void {
8990///
9091/// It is not necessary to call this function to query the values of comptime fields: those values
9192/// 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 {
9394 const pt = sema.pt;
9495 const zcu = pt.zcu;
9596 const ip = &zcu.intern_pool;
9697 assert(ip.indexToKey(ty.toIntern()) == .struct_type);
9798
9899 try sema.declareDependency(.{ .struct_defaults = ty.toIntern() });
100 try sema.addReferenceEntry(null, src, .wrap(.{ .struct_defaults = ty.toIntern() }));
99101 if (zcu.analysis_in_progress.contains(.wrap(.{ .struct_defaults = ty.toIntern() }))) {
100102 // TODO: better error message
101103 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(
......@@ -120,7 +122,8 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
120122 assert(sema.owner.unwrap().type_layout == struct_ty.toIntern());
121123
122124 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
125128 var block: Block = .{
126129 .parent = null,
......@@ -219,7 +222,7 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
219222 const field_ty: Type = .fromInterned(field_ty_ip);
220223 assert(!field_ty.isGenericPoison());
221224 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
224227 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
225228 return sema.failWithOwnedErrorMsg(&block, msg: {
......@@ -368,7 +371,7 @@ fn resolvePackedStructLayout(
368371 const field_ty: Type = .fromInterned(field_ty_ip);
369372 assert(!field_ty.isGenericPoison());
370373 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);
372375 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
373376 return sema.failWithOwnedErrorMsg(block, msg: {
374377 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 {
458461
459462 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
463466 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 that
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);
476 try sema.declareDependency(.{ .src_hash = struct_obj.zir_index });
471477
472478 if (struct_obj.field_defaults.len == 0) {
473479 // The struct has no default field values, so the slice has been omitted.
......@@ -509,7 +515,7 @@ fn resolveStructDefaultsInner(
509515 const ip = &zcu.intern_pool;
510516
511517 // 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;
513519 try sema.inst_map.ensureSpaceForInstructions(gpa, &.{zir_index});
514520
515521 const field_types = struct_obj.field_types.get(ip);
......@@ -555,7 +561,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
555561 assert(sema.owner.unwrap().type_layout == union_ty.toIntern());
556562
557563 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
560567 var block: Block = .{
561568 .parent = null,
......@@ -627,16 +634,11 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
627634 .generation = zcu.generation,
628635 });
629636 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 }), {});
635637 break :tag_ty .fromInterned(wip.finish(ip, new_namespace_index));
636638 },
637639 };
638640
639 try sema.ensureLayoutResolved(enum_tag_ty);
641 try sema.ensureLayoutResolved(enum_tag_ty, block.src(.container_arg));
640642 const enum_obj = ip.loadEnumType(enum_tag_ty.toIntern());
641643
642644 if (union_obj.is_reified) {
......@@ -731,7 +733,7 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
731733 const field_ty: Type = .fromInterned(field_ty_ip);
732734 assert(!field_ty.isGenericPoison());
733735 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);
735737 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
736738 return sema.failWithOwnedErrorMsg(&block, msg: {
737739 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(
889891 const field_ty: Type = .fromInterned(field_ty_ip);
890892 assert(!field_ty.isGenericPoison());
891893 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);
893895 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
894896 return sema.failWithOwnedErrorMsg(block, msg: {
895897 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 {
995997 assert(sema.owner.unwrap().type_layout == enum_ty.toIntern());
996998
997999 const enum_obj = ip.loadEnumType(enum_ty.toIntern());
1000 assert(enum_obj.want_layout);
9981001
9991002 const maybe_parent_union_obj: ?InternPool.LoadedUnionType = un: {
10001003 if (enum_obj.owner_union == .none) break :un null;
......@@ -1002,6 +1005,7 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
10021005 };
10031006
10041007 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
10061010 var block: Block = .{
10071011 .parent = null,
......@@ -1040,7 +1044,7 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
10401044 // Generated tag enums for declared unions do not yet have field names populated. It is
10411045 // our job to populate them now.
10421046 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);
10441048 for (zir_union.field_names) |zir_field_name| {
10451049 const name_slice = sema.code.nullTerminatedString(zir_field_name);
10461050 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 {
10651069 } else {
10661070 // Declared enums do not yet have field names populated. It is our job to populate them now.
10671071 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);
10691073 for (zir_enum.field_names) |zir_field_name| {
10701074 const name_slice = sema.code.nullTerminatedString(zir_field_name);
10711075 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 {
10871091 // Reification has no equivalent of 'union(enum(T))'.
10881092 break :ty null;
10891093 }
1090 const zir_index = union_obj.zir_index.resolve(ip).?;
10911094 const zir_union = sema.code.getUnionDecl(zir_index);
10921095 if (zir_union.kind != .tagged_enum_explicit) {
10931096 break :ty null; // int tag type will be inferred
......@@ -1102,7 +1105,6 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
11021105 const type_ref = try sema.resolveInlineBody(&block, tag_type_body, zir_index);
11031106 break :ty try sema.analyzeAsType(&block, tag_type_src, .enum_int_tag_type, type_ref);
11041107 } else ty: {
1105 const zir_index = enum_obj.zir_index.unwrap().?.resolve(ip).?;
11061108 const zir_enum = sema.code.getEnumDecl(zir_index);
11071109 const tag_type_body = zir_enum.tag_type_body orelse {
11081110 break :ty null; // int tag type will be inferred
......@@ -1147,8 +1149,6 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
11471149 // There may be old field values in here from a previous update.
11481150 field_value_map.get(ip).clearRetainingCapacity();
11491151
1150 const zir_index = tracked_inst.resolve(ip).?;
1151
11521152 // Map the enum (or union) decl instruction to provide the tag type as the result type
11531153 try sema.inst_map.ensureSpaceForInstructions(gpa, &.{zir_index});
11541154 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 {
30443044 .tuple_type => |tuple| for (tuple.types.get(&zcu.intern_pool)) |field_ty| {
30453045 assertHasLayout(.fromInterned(field_ty), zcu);
30463046 },
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);
30483061 const unit: InternPool.AnalUnit = .wrap(.{ .type_layout = ty.toIntern() });
30493062 assert(!zcu.outdated.contains(unit));
30503063 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
21492149 const base_ptr = Value.fromInterned(field.base);
21502150 const base_ptr_ty = base_ptr.typeOf(zcu);
21512151 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
21532153 const field_ty: Type, const field_align: InternPool.Alignment = switch (agg_ty.zigTypeTag(zcu)) {
21542154 .@"struct", .@"union" => .{ agg_ty.fieldType(@intCast(field.index), zcu), agg_ty.resolvedFieldAlignment(@intCast(field.index), pt.zcu) },
21552155 .pointer => switch (field.index) {
src/Zcu.zig+23-74
......@@ -266,9 +266,6 @@ outdated_ready: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .empty,
266266/// it as outdated.
267267retryable_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
272269/// These are the modules which we initially queue for analysis in `Compilation.update`.
273270/// `resolveReferences` will use these as the root of its reachability traversal.
274271analysis_roots_buffer: [5]*Package.Module,
......@@ -2814,9 +2811,6 @@ pub fn deinit(zcu: *Zcu) void {
28142811 zcu.outdated_ready.deinit(gpa);
28152812 zcu.retryable_failures.deinit(gpa);
28162813
2817 zcu.func_body_analysis_queued.deinit(gpa);
2818 zcu.nav_val_analysis_queued.deinit(gpa);
2819
28202814 zcu.test_functions.deinit(gpa);
28212815
28222816 for (zcu.global_assembly.values()) |s| {
......@@ -3179,8 +3173,6 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni
31793173/// recursive analysis (all of its previously-marked dependencies are already up-to-date), because
31803174/// recursive analysis can cause over-analysis on incremental updates.
31813175pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
3182 if (!zcu.comp.config.incremental) return null;
3183
31843176 if (zcu.outdated_ready.count() > 0) {
31853177 const unit = zcu.outdated_ready.keys()[0];
31863178 log.debug("findOutdatedToAnalyze: {f}", .{zcu.fmtAnalUnit(unit)});
......@@ -3458,47 +3450,35 @@ pub fn mapOldZirToNew(
34583450/// The caller is responsible for ensuring the function decl itself is already
34593451/// analyzed, and for ensuring it can exist at runtime (see
34603452/// `Type.fnHasRuntimeBitsSema`). This function does *not* guarantee that the body
3461/// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`.
3462pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func_index: InternPool.Index) !void {
3453/// will be analyzed when it returns: for that, see `PerThread.ensureFuncBodyUpToDate`.
3454pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func: InternPool.Index) !void {
3455 const comp = zcu.comp;
3456 const gpa = comp.gpa;
3457 const io = comp.io;
34633458 const ip = &zcu.intern_pool;
3464
3465 const func = zcu.funcInfo(func_index);
3466
3467 assert(func.ty == func.uncoerced_ty); // analyze the body of the original function, not a coerced one
3468
3469 if (zcu.func_body_analysis_queued.contains(func_index)) return;
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 }
3459 assert(func == ip.unwrapCoercedFunc(func)); // analyze the body of the original function, not a coerced one
3460 if (ip.setWantRuntimeFnAnalysis(io, func)) {
3461 // This is the first reference to this function, so we must ensure it will be analyzed.
3462 const unit: AnalUnit = .wrap(.{ .func = func });
3463 try zcu.outdated.putNoClobber(gpa, unit, 0);
3464 try zcu.outdated_ready.putNoClobber(gpa, unit, {});
34783465 }
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, {});
34833466}
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;
34863472 const ip = &zcu.intern_pool;
3487
3488 if (zcu.nav_val_analysis_queued.contains(nav_id)) return;
3489
3490 if (ip.getNav(nav_id).status == .fully_resolved) {
3491 if (!zcu.outdated.contains(.wrap(.{ .nav_val = nav_id })) and
3492 !zcu.potentially_outdated.contains(.wrap(.{ .nav_val = nav_id })))
3493 {
3494 // This `Nav` has been analyzed before and is definitely up-to-date.
3495 return;
3496 }
3473 if (ip.setWantNavAnalysis(io, nav)) {
3474 // This is the first reference to this function, so we must ensure it will be analyzed.
3475 try zcu.outdated.ensureUnusedCapacity(gpa, 2);
3476 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 2);
3477 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .nav_val = nav }), 0);
3478 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .nav_ty = nav }), 0);
3479 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .nav_val = nav }), {});
3480 zcu.outdated_ready.putAssumeCapacityNoClobber(.wrap(.{ .nav_ty = nav }), {});
34973481 }
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, {});
35023482}
35033483
35043484pub const ImportResult = struct {
......@@ -4035,37 +4015,6 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
40354015
40364016 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
40694018 // Queue any decls within this type which would be automatically analyzed.
40704019 // Keep in sync with analysis queueing logic in `Zcu.PerThread.ScanDeclIter.scanDecl`.
40714020 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
719719 });
720720 errdefer pt.destroyNamespace(new_namespace_index);
721721 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
726723 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
736725 const file_root_type: Type = .fromInterned(wip.finish(ip, new_namespace_index));
737726
738727 zcu.setFileRootType(file_index, file_root_type.toIntern());
......@@ -1075,11 +1064,12 @@ pub fn ensureTypeLayoutUpToDate(pt: Zcu.PerThread, ty: Type) Zcu.SemaError!void
10751064 assert(!zcu.analysis_in_progress.contains(anal_unit));
10761065
10771066 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
10801070 if (was_outdated) {
10811071 _ = 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`.
10831073 if (dev.env.supports(.incremental)) {
10841074 zcu.deleteUnitExports(anal_unit);
10851075 zcu.deleteUnitReferences(anal_unit);
......@@ -1182,16 +1172,13 @@ pub fn ensureStructDefaultsUpToDate(pt: Zcu.PerThread, ty: Type) Zcu.SemaError!v
11821172
11831173 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
11891175 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
11921179 if (was_outdated) {
11931180 _ = 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`.
11951182 if (dev.env.supports(.incremental)) {
11961183 zcu.deleteUnitExports(anal_unit);
11971184 zcu.deleteUnitReferences(anal_unit);
......@@ -1279,8 +1266,6 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
12791266 const gpa = zcu.gpa;
12801267 const ip = &zcu.intern_pool;
12811268
1282 _ = zcu.nav_val_analysis_queued.swapRemove(nav_id);
1283
12841269 const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id });
12851270 const nav = ip.getNav(nav_id);
12861271
......@@ -1288,6 +1273,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
12881273
12891274 assert(!zcu.analysis_in_progress.contains(anal_unit));
12901275
1276 try zcu.ensureNavValAnalysisQueued(nav_id);
1277
12911278 // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the
12921279 // status is `.unresolved`, which indicates that the value is outdated because it has *never*
12931280 // been analyzed so far.
......@@ -1317,10 +1304,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
13171304 } else {
13181305 // We can trust the current information about this unit.
13191306 if (prev_failed) return error.AnalysisFail;
1320 switch (nav.status) {
1321 .unresolved, .type_resolved => {},
1322 .fully_resolved => return,
1323 }
1307 assert(nav.status == .fully_resolved);
1308 return;
13241309 }
13251310
13261311 if (zcu.comp.debugIncremental()) {
......@@ -1488,9 +1473,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
14881473
14891474 const maybe_ty: ?Type = if (zir_decl.type_body != null) ty: {
14901475 // Since we have a type body, the type is resolved separately!
1491 // Of course, we need to make sure we depend on it properly.
1492 try sema.declareDependency(.{ .nav_ty = nav_id });
1493 try pt.ensureNavTypeUpToDate(nav_id);
1476 try sema.ensureNavResolved(&block, init_src, nav_id, .type);
14941477 break :ty .fromInterned(ip.getNav(nav_id).typeOf(ip));
14951478 } else null;
14961479
......@@ -1602,7 +1585,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
16021585
16031586 // This resolves the type of the resolved value, not that value itself. If `nav_val` is a struct type,
16041587 // 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
16071590 const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(nav_val.toIntern())) {
16081591 .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
16921675
16931676 assert(!zcu.analysis_in_progress.contains(anal_unit));
16941677
1678 try zcu.ensureNavValAnalysisQueued(nav_id);
1679
16951680 const type_resolved_by_value: bool = from_val: {
16961681 const analysis = nav.analysis orelse break :from_val false;
16971682 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
17331718 } else {
17341719 // We can trust the current information about this unit.
17351720 if (prev_failed) return error.AnalysisFail;
1736 switch (nav.status) {
1737 .unresolved => {},
1738 .type_resolved, .fully_resolved => return,
1739 }
1721 assert(nav.status != .unresolved);
1722 return;
17401723 }
17411724
17421725 if (zcu.comp.debugIncremental()) {
......@@ -1869,7 +1852,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
18691852 break :ty .fromInterned(type_ref.toInterned().?);
18701853 };
18711854
1872 try sema.ensureLayoutResolved(resolved_ty);
1855 try sema.ensureLayoutResolved(resolved_ty, ty_src);
18731856
18741857 // In the case where the type is specified, this function is also responsible for resolving
18751858 // the pointer modifiers, i.e. alignment, linksection, addrspace.
......@@ -1929,8 +1912,6 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
19291912 const gpa = zcu.gpa;
19301913 const ip = &zcu.intern_pool;
19311914
1932 _ = zcu.func_body_analysis_queued.swapRemove(func_index);
1933
19341915 const anal_unit: AnalUnit = .wrap(.{ .func = func_index });
19351916
19361917 log.debug("ensureFuncBodyUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
......@@ -1942,7 +1923,8 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
19421923 assert(func.ty == func.uncoerced_ty); // analyze the body of the original function, not a coerced one
19431924
19441925 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
19471929 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
19581940 _ = zcu.transitive_failed_analysis.swapRemove(anal_unit);
19591941 } else {
19601942 // We can trust the current information about this function.
1961 if (prev_failed) {
1962 return error.AnalysisFail;
1963 }
1964 if (func.analysisUnordered(ip).is_analyzed) return;
1943 if (prev_failed) return error.AnalysisFail;
1944 return;
19651945 }
19661946
19671947 if (zcu.comp.debugIncremental()) {
......@@ -3026,7 +3006,6 @@ fn analyzeFuncBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.Sem
30263006 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});
30273007 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
30283008
3029 func.setAnalyzed(ip, io);
30303009 if (func.analysisUnordered(ip).inferred_error_set) {
30313010 func.setResolvedErrorSet(ip, io, .none);
30323011 }
......@@ -3144,7 +3123,7 @@ fn analyzeFuncBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.Sem
31443123 const param_ty: Type = .fromInterned(fn_ty_info.param_types.get(ip)[runtime_param_index]);
31453124 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) }));
31483127 if (try param_ty.onePossibleValue(pt)) |opv| {
31493128 gop.value_ptr.* = .fromValue(opv);
31503129 continue;
......@@ -3161,7 +3140,7 @@ fn analyzeFuncBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.Sem
31613140 });
31623141 }
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
31663145 const last_arg_index = inner_block.instructions.items.len;
31673146