diff --git a/src/Sema.zig b/src/Sema.zig index a937687761..513fcb9df4 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -27612,13 +27612,8 @@ fn explainWhyTypeIsNotPacked( fn preparePanicId(sema: *Sema, src: LazySrcLoc, panic_id: Zcu.PanicId) !InternPool.Index { const zcu = sema.pt.zcu; try sema.ensureMemoizedStateResolved(src, .panic); - try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.@"Panic.call"); - switch (panic_id) { - inline else => |ct_panic_id| { - const name = "Panic.messages." ++ @tagName(ct_panic_id); - return @field(zcu.builtin_decl_values, name); - }, - } + try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.get(.@"Panic.call")); + return zcu.builtin_decl_values.get(panic_id.toBuiltin()); } fn addSafetyCheck( @@ -27723,9 +27718,9 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst. } try sema.ensureMemoizedStateResolved(src, .panic); - try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.@"Panic.call"); + try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.get(.@"Panic.call")); - const panic_fn = Air.internedToRef(zcu.builtin_decl_values.@"Panic.call"); + const panic_fn = Air.internedToRef(zcu.builtin_decl_values.get(.@"Panic.call")); const null_stack_trace = Air.internedToRef(zcu.null_stack_trace); const opt_usize_ty = try pt.optionalType(.usize_type); @@ -38720,15 +38715,15 @@ const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadR const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr; const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult; -pub fn getBuiltinType(sema: *Sema, src: LazySrcLoc, comptime decl: Zcu.BuiltinDecl) SemaError!Type { - comptime assert(decl.kind() == .type); +pub fn getBuiltinType(sema: *Sema, src: LazySrcLoc, decl: Zcu.BuiltinDecl) SemaError!Type { + assert(decl.kind() == .type); try sema.ensureMemoizedStateResolved(src, decl.stage()); - return .fromInterned(@field(sema.pt.zcu.builtin_decl_values, @tagName(decl))); + return .fromInterned(sema.pt.zcu.builtin_decl_values.get(decl)); } -pub fn getBuiltin(sema: *Sema, src: LazySrcLoc, comptime decl: Zcu.BuiltinDecl) SemaError!InternPool.Index { - comptime assert(decl.kind() != .type); +pub fn getBuiltin(sema: *Sema, src: LazySrcLoc, decl: Zcu.BuiltinDecl) SemaError!InternPool.Index { + assert(decl.kind() != .type); try sema.ensureMemoizedStateResolved(src, decl.stage()); - return @field(sema.pt.zcu.builtin_decl_values, @tagName(decl)); + return sema.pt.zcu.builtin_decl_values.get(decl); } pub const NavPtrModifiers = struct { @@ -38810,7 +38805,7 @@ pub fn analyzeMemoizedState(sema: *Sema, block: *Block, src: LazySrcLoc, builtin const parent_ns: Zcu.Namespace.Index, const parent_name: []const u8, const name: []const u8 = switch (comptime builtin_decl.access()) { .direct => |name| .{ builtin_namespace, "std.builtin", name }, .nested => |nested| access: { - const parent_ty: Type = .fromInterned(@field(zcu.builtin_decl_values, @tagName(nested[0]))); + const parent_ty: Type = .fromInterned(zcu.builtin_decl_values.get(nested[0])); const parent_ns = parent_ty.getNamespace(zcu).unwrap() orelse { return sema.fail(block, src, "std.builtin.{s} is not a container type", .{@tagName(nested[0])}); }; @@ -38845,9 +38840,9 @@ pub fn analyzeMemoizedState(sema: *Sema, block: *Block, src: LazySrcLoc, builtin }, } - const prev = @field(zcu.builtin_decl_values, @tagName(builtin_decl)); + const prev = zcu.builtin_decl_values.get(builtin_decl); if (val.toIntern() != prev) { - @field(zcu.builtin_decl_values, @tagName(builtin_decl)) = val.toIntern(); + zcu.builtin_decl_values.set(builtin_decl, val.toIntern()); any_changed = true; } } diff --git a/src/Zcu.zig b/src/Zcu.zig index fcd519e2ed..60aeffdf44 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -217,8 +217,8 @@ all_type_references: std.ArrayListUnmanaged(TypeReference) = .empty, /// Freelist of indices in `all_type_references`. free_type_references: std.ArrayListUnmanaged(u32) = .empty, -/// Populated by analysis of `AnalUnit.wrap(.{ .memoized_state = s })`, where `s` depends on the field. -builtin_decl_values: BuiltinDecl.Memoized = .{}, +/// Populated by analysis of `AnalUnit.wrap(.{ .memoized_state = s })`, where `s` depends on the element. +builtin_decl_values: BuiltinDecl.Memoized = .initFill(.none), /// Populated by analysis of `AnalUnit.wrap(.{ .memoized_state = .panic })`. null_stack_trace: InternPool.Index = .none, @@ -420,7 +420,7 @@ pub const BuiltinDecl = enum { }; } - const Memoized = std.enums.EnumFieldStruct(BuiltinDecl, InternPool.Index, .none); + const Memoized = std.enums.EnumArray(BuiltinDecl, InternPool.Index); }; pub const PanicId = enum { @@ -444,6 +444,21 @@ pub const PanicId = enum { memcpy_len_mismatch, memcpy_alias, noreturn_returned, + + pub fn toBuiltin(id: PanicId) BuiltinDecl { + const first_msg: PanicId = @enumFromInt(0); + const first_decl = @field(BuiltinDecl, "Panic.messages." ++ @tagName(first_msg)); + comptime { + // Ensure that the messages are ordered the same in `BuiltinDecl` as they are here. + for (@typeInfo(PanicId).@"enum".fields) |panic_field| { + const expect_name = "Panic.messages." ++ panic_field.name; + const expect_idx = @intFromEnum(first_decl) + panic_field.value; + const actual_idx = @intFromEnum(@field(BuiltinDecl, expect_name)); + assert(expect_idx == actual_idx); + } + } + return @enumFromInt(@intFromEnum(first_decl) + @intFromEnum(id)); + } }; pub const GlobalErrorSet = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void); diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 854e27ae9b..ee926d5f11 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -590,13 +590,13 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized _ = zcu.transitive_failed_analysis.swapRemove(unit); } else { if (prev_failed) return error.AnalysisFail; - // We use an arbitrary field to check if the state has been resolved yet. - const val = switch (stage) { - .main => zcu.builtin_decl_values.Type, - .panic => zcu.builtin_decl_values.Panic, - .va_list => zcu.builtin_decl_values.VaList, + // We use an arbitrary element to check if the state has been resolved yet. + const to_check: Zcu.BuiltinDecl = switch (stage) { + .main => .Type, + .panic => .Panic, + .va_list => .VaList, }; - if (val != .none) return; + if (zcu.builtin_decl_values.get(to_check) != .none) return; } const any_changed: bool, const new_failed: bool = if (pt.analyzeMemoizedState(stage)) |any_changed| diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 63fc7b7dcc..f14d58459f 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -5754,9 +5754,7 @@ pub const FuncGen = struct { const o = fg.ng.object; const zcu = o.pt.zcu; const ip = &zcu.intern_pool; - const panic_msg_val: InternPool.Index = switch (panic_id) { - inline else => |ct_panic_id| @field(zcu.builtin_decl_values, "Panic.messages." ++ @tagName(ct_panic_id)), - }; + const panic_msg_val = zcu.builtin_decl_values.get(panic_id.toBuiltin()); assert(panic_msg_val != .none); const msg_len = Value.fromInterned(panic_msg_val).typeOf(zcu).childType(zcu).arrayLen(zcu); const msg_ptr = try o.lowerValue(panic_msg_val); @@ -5770,7 +5768,7 @@ pub const FuncGen = struct { // ptr null, ; stack trace // ptr @2, ; addr (null ?usize) // ) - const panic_func = zcu.funcInfo(zcu.builtin_decl_values.@"Panic.call"); + const panic_func = zcu.funcInfo(zcu.builtin_decl_values.get(.@"Panic.call")); const panic_nav = ip.getNav(panic_func.owner_nav); const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?; const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav);