authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-04 05:09:02+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-04 07:51:19+00:00
logf01029c4af7d3015c1c3f7d36bb62f7d5afb53a4
tree21fd6696e57bc59fb1c097903e8421562d0862f5
parentfd62912787ee4f26b06ba86560e9aa605095ae04
signaturelock-open Commit is signed but in an unrecognized format.

incremental: new `AnalUnit` to group dependencies on `std.builtin` decls

This commit reworks how values like the panic handler function are memoized during a compiler invocation. Previously, the value was resolved by whichever analysis requested it first, and cached on `Zcu`. This is problematic for incremental compilation, as after the initial resolution, no dependencies are marked by users of this memoized state. This is arguably acceptable for `std.builtin`, but it's definitely not acceptable for the panic handler/messages, because those can be set by the user (`std.builtin.Panic` checks `@import("root").Panic`). So, here we introduce a new kind of `AnalUnit`, called `memoized_state`. There are 3 such units: * `.{ .memoized_state = .va_list }` resolves the type `std.builtin.VaList` * `.{ .memoized_state = .panic }` resolves `std.Panic` * `.{ .memoized_state = .main }` resolves everything else we want These units essentially "bundle" the resolution of their corresponding declarations, storing the results into fields on `Zcu`. This way, when, for instance, a function wants to call the panic handler, it simply runs `ensureMemoizedStateResolved`, registering one dependency, and pulls the values from the `Zcu`. This "bundling" minimizes dependency edges. The 3 units are separated to allow them to act independently: for instance, the panic handler can use `std.builtin.Type` without triggering a dependency loop.

6 files changed, 639 insertions(+), 254 deletions(-)

src/Compilation.zig+16-10
......@@ -3158,16 +3158,19 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
31583158 if (!refs.contains(anal_unit)) continue;
31593159 }
31603160
3161 const file_index = switch (anal_unit.unwrap()) {
3162 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index.resolveFile(ip),
3163 .nav_val, .nav_ty => |nav| ip.getNav(nav).analysis.?.zir_index.resolveFile(ip),
3164 .type => |ty| Type.fromInterned(ty).typeDeclInst(zcu).?.resolveFile(ip),
3165 .func => |ip_index| zcu.funcInfo(ip_index).zir_body_inst.resolveFile(ip),
3166 };
3161 report_ok: {
3162 const file_index = switch (anal_unit.unwrap()) {
3163 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index.resolveFile(ip),
3164 .nav_val, .nav_ty => |nav| ip.getNav(nav).analysis.?.zir_index.resolveFile(ip),
3165 .type => |ty| Type.fromInterned(ty).typeDeclInst(zcu).?.resolveFile(ip),
3166 .func => |ip_index| zcu.funcInfo(ip_index).zir_body_inst.resolveFile(ip),
3167 .memoized_state => break :report_ok, // always report std.builtin errors
3168 };
31673169
3168 // Skip errors for AnalUnits within files that had a parse failure.
3169 // We'll try again once parsing succeeds.
3170 if (!zcu.fileByIndex(file_index).okToReportErrors()) continue;
3170 // Skip errors for AnalUnits within files that had a parse failure.
3171 // We'll try again once parsing succeeds.
3172 if (!zcu.fileByIndex(file_index).okToReportErrors()) continue;
3173 }
31713174
31723175 std.log.scoped(.zcu).debug("analysis error '{s}' reported from unit '{}'", .{
31733176 error_msg.msg,
......@@ -3391,7 +3394,7 @@ pub fn addModuleErrorMsg(
33913394 const ref = maybe_ref orelse break;
33923395 const gop = try seen.getOrPut(gpa, ref.referencer);
33933396 if (gop.found_existing) break;
3394 if (ref_traces.items.len < max_references) {
3397 if (ref_traces.items.len < max_references) skip: {
33953398 const src = ref.src.upgrade(zcu);
33963399 const source = try src.file_scope.getSource(gpa);
33973400 const span = try src.span(gpa);
......@@ -3403,6 +3406,7 @@ pub fn addModuleErrorMsg(
34033406 .nav_val, .nav_ty => |nav| ip.getNav(nav).name.toSlice(ip),
34043407 .type => |ty| Type.fromInterned(ty).containerTypeName(ip).toSlice(ip),
34053408 .func => |f| ip.getNav(zcu.funcInfo(f).owner_nav).name.toSlice(ip),
3409 .memoized_state => break :skip,
34063410 };
34073411 try ref_traces.append(gpa, .{
34083412 .decl_name = try eb.addString(name),
......@@ -3670,6 +3674,7 @@ fn performAllTheWorkInner(
36703674 if (try zcu.findOutdatedToAnalyze()) |outdated| {
36713675 try comp.queueJob(switch (outdated.unwrap()) {
36723676 .func => |f| .{ .analyze_func = f },
3677 .memoized_state,
36733678 .@"comptime",
36743679 .nav_ty,
36753680 .nav_val,
......@@ -3737,6 +3742,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
37373742 .nav_ty => |nav| pt.ensureNavTypeUpToDate(nav),
37383743 .nav_val => |nav| pt.ensureNavValUpToDate(nav),
37393744 .type => |ty| if (pt.ensureTypeUpToDate(ty)) |_| {} else |err| err,
3745 .memoized_state => |stage| pt.ensureMemoizedStateUpToDate(stage),
37403746 .func => unreachable,
37413747 };
37423748 maybe_err catch |err| switch (err) {
src/InternPool.zig+55
......@@ -49,6 +49,11 @@ namespace_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index)
4949/// Dependencies on the (non-)existence of some name in a namespace.
5050/// Value is index into `dep_entries` of the first dependency on this name.
5151namespace_name_deps: std.AutoArrayHashMapUnmanaged(NamespaceNameKey, DepEntry.Index),
52// Dependencies on the value of fields memoized on `Zcu` (`panic_messages` etc).
53// If set, these are indices into `dep_entries` of the first dependency on this state.
54memoized_state_main_deps: DepEntry.Index.Optional,
55memoized_state_panic_deps: DepEntry.Index.Optional,
56memoized_state_va_list_deps: DepEntry.Index.Optional,
5257
5358/// Given a `Depender`, points to an entry in `dep_entries` whose `depender`
5459/// matches. The `next_dependee` field can be used to iterate all such entries
......@@ -87,6 +92,9 @@ pub const empty: InternPool = .{
8792 .interned_deps = .empty,
8893 .namespace_deps = .empty,
8994 .namespace_name_deps = .empty,
95 .memoized_state_main_deps = .none,
96 .memoized_state_panic_deps = .none,
97 .memoized_state_va_list_deps = .none,
9098 .first_dependency = .empty,
9199 .dep_entries = .empty,
92100 .free_dep_entries = .empty,
......@@ -385,6 +393,7 @@ pub const AnalUnit = packed struct(u64) {
385393 nav_ty,
386394 type,
387395 func,
396 memoized_state,
388397 };
389398
390399 pub const Unwrapped = union(Kind) {
......@@ -399,6 +408,8 @@ pub const AnalUnit = packed struct(u64) {
399408 type: InternPool.Index,
400409 /// This `AnalUnit` analyzes the body of the given runtime function.
401410 func: InternPool.Index,
411 /// This `AnalUnit` resolves all state which is memoized in fields on `Zcu`.
412 memoized_state: MemoizedStateStage,
402413 };
403414
404415 pub fn unwrap(au: AnalUnit) Unwrapped {
......@@ -434,6 +445,16 @@ pub const AnalUnit = packed struct(u64) {
434445 };
435446};
436447
448pub const MemoizedStateStage = enum(u32) {
449 /// Everything other than panics and `VaList`.
450 main,
451 /// Everything within `std.builtin.Panic`.
452 /// Since the panic handler is user-provided, this must be able to reference the other memoized state.
453 panic,
454 /// Specifically `std.builtin.VaList`. See `Zcu.BuiltinDecl.stage`.
455 va_list,
456};
457
437458pub const ComptimeUnit = extern struct {
438459 zir_index: TrackedInst.Index,
439460 namespace: NamespaceIndex,
......@@ -769,6 +790,7 @@ pub const Dependee = union(enum) {
769790 interned: Index,
770791 namespace: TrackedInst.Index,
771792 namespace_name: NamespaceNameKey,
793 memoized_state: MemoizedStateStage,
772794};
773795
774796pub fn removeDependenciesForDepender(ip: *InternPool, gpa: Allocator, depender: AnalUnit) void {
......@@ -819,6 +841,11 @@ pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyI
819841 .interned => |x| ip.interned_deps.get(x),
820842 .namespace => |x| ip.namespace_deps.get(x),
821843 .namespace_name => |x| ip.namespace_name_deps.get(x),
844 .memoized_state => |stage| switch (stage) {
845 .main => ip.memoized_state_main_deps.unwrap(),
846 .panic => ip.memoized_state_panic_deps.unwrap(),
847 .va_list => ip.memoized_state_va_list_deps.unwrap(),
848 },
822849 } orelse return .{
823850 .ip = ip,
824851 .next_entry = .none,
......@@ -848,6 +875,33 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend
848875 // This block should allocate an entry and prepend it to the relevant `*_deps` list.
849876 // The `next` field should be correctly initialized; all other fields may be undefined.
850877 const new_index: DepEntry.Index = switch (dependee) {
878 .memoized_state => |stage| new_index: {
879 const deps = switch (stage) {
880 .main => &ip.memoized_state_main_deps,
881 .panic => &ip.memoized_state_panic_deps,
882 .va_list => &ip.memoized_state_va_list_deps,
883 };
884
885 if (deps.unwrap()) |first| {
886 if (ip.dep_entries.items[@intFromEnum(first)].depender == .none) {
887 // Dummy entry, so we can reuse it rather than allocating a new one!
888 break :new_index first;
889 }
890 }
891
892 // Prepend a new dependency.
893 const new_index: DepEntry.Index, const ptr = if (ip.free_dep_entries.popOrNull()) |new_index| new: {
894 break :new .{ new_index, &ip.dep_entries.items[@intFromEnum(new_index)] };
895 } else .{ @enumFromInt(ip.dep_entries.items.len), ip.dep_entries.addOneAssumeCapacity() };
896 if (deps.unwrap()) |old_first| {
897 ptr.next = old_first.toOptional();
898 ip.dep_entries.items[@intFromEnum(old_first)].prev = new_index.toOptional();
899 } else {
900 ptr.next = .none;
901 }
902 deps.* = new_index.toOptional();
903 break :new_index new_index;
904 },
851905 inline else => |dependee_payload, tag| new_index: {
852906 const gop = try switch (tag) {
853907 .file => ip.file_deps,
......@@ -857,6 +911,7 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend
857911 .interned => ip.interned_deps,
858912 .namespace => ip.namespace_deps,
859913 .namespace_name => ip.namespace_name_deps,
914 .memoized_state => comptime unreachable,
860915 }.getOrPut(gpa, dependee_payload);
861916
862917 if (gop.found_existing and ip.dep_entries.items[@intFromEnum(gop.value_ptr.*)].depender == .none) {
src/Sema.zig+208-215
......@@ -428,7 +428,7 @@ pub const Block = struct {
428428 } });
429429 }
430430
431 fn nodeOffset(block: Block, node_offset: i32) LazySrcLoc {
431 pub fn nodeOffset(block: Block, node_offset: i32) LazySrcLoc {
432432 return block.src(LazySrcLoc.Offset.nodeOffset(node_offset));
433433 }
434434
......@@ -2149,7 +2149,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
21492149 const addrs_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(addr_arr_ty));
21502150
21512151 // var st: StackTrace = undefined;
2152 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
2152 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace);
21532153 try stack_trace_ty.resolveFields(pt);
21542154 const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty));
21552155
......@@ -6600,6 +6600,7 @@ fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
66006600 .nav_val,
66016601 .nav_ty,
66026602 .type,
6603 .memoized_state,
66036604 => return, // does nothing outside a function
66046605 };
66056606 ip.funcSetDisableInstrumentation(func);
......@@ -6609,7 +6610,7 @@ fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
66096610fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
66106611 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
66116612 const src = block.builtinCallArgSrc(extra.node, 0);
6612 block.float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode", .{ .simple = .operand_setFloatMode });
6613 block.float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, .FloatMode, .{ .simple = .operand_setFloatMode });
66136614}
66146615
66156616fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
......@@ -6917,7 +6918,7 @@ fn lookupInNamespace(
69176918
69186919 ignore_self: {
69196920 const skip_nav = switch (sema.owner.unwrap()) {
6920 .@"comptime", .type, .func => break :ignore_self,
6921 .@"comptime", .type, .func, .memoized_state => break :ignore_self,
69216922 .nav_ty, .nav_val => |nav| nav,
69226923 };
69236924 var i: usize = 0;
......@@ -6990,7 +6991,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
69906991
69916992 if (!block.ownerModule().error_tracing) return .none;
69926993
6993 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
6994 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace);
69946995 try stack_trace_ty.resolveFields(pt);
69956996 const field_name = try zcu.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);
69966997 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {
......@@ -7032,7 +7033,7 @@ fn popErrorReturnTrace(
70327033 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or
70337034 // the result is comptime-known to be a non-error. Either way, pop unconditionally.
70347035
7035 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
7036 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
70367037 try stack_trace_ty.resolveFields(pt);
70377038 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
70387039 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
......@@ -7058,7 +7059,7 @@ fn popErrorReturnTrace(
70587059 defer then_block.instructions.deinit(gpa);
70597060
70607061 // If non-error, then pop the error return trace by restoring the index.
7061 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
7062 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
70627063 try stack_trace_ty.resolveFields(pt);
70637064 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
70647065 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
......@@ -7178,7 +7179,7 @@ fn zirCall(
71787179 const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
71797180
71807181 switch (sema.owner.unwrap()) {
7181 .@"comptime", .type, .nav_ty, .nav_val => input_is_error = false,
7182 .@"comptime", .type, .memoized_state, .nav_ty, .nav_val => input_is_error = false,
71827183 .func => |owner_func| if (!zcu.intern_pool.funcAnalysisUnordered(owner_func).calls_or_awaits_errorable_fn) {
71837184 // No errorable fn actually called; we have no error return trace
71847185 input_is_error = false;
......@@ -7201,7 +7202,7 @@ fn zirCall(
72017202 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
72027203 // need to clean-up our own trace if we were passed to a non-error-handling expression.
72037204 if (input_is_error or (pop_error_return_trace and return_ty.isError(zcu))) {
7204 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
7205 const stack_trace_ty = try sema.getBuiltinType(call_src, .StackTrace);
72057206 try stack_trace_ty.resolveFields(pt);
72067207 const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "index", .no_embedded_nulls);
72077208 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
......@@ -8091,7 +8092,7 @@ fn analyzeCall(
80918092 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
80928093
80938094 switch (sema.owner.unwrap()) {
8094 .@"comptime", .nav_ty, .nav_val, .type => {},
8095 .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {},
80958096 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) {
80968097 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
80978098 },
......@@ -8557,7 +8558,7 @@ fn instantiateGenericCall(
85578558 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
85588559
85598560 switch (sema.owner.unwrap()) {
8560 .@"comptime", .nav_ty, .nav_val, .type => {},
8561 .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {},
85618562 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) {
85628563 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
85638564 },
......@@ -9537,6 +9538,7 @@ fn zirFunc(
95379538 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);
95389539 const target = zcu.getTarget();
95399540 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });
9541 const src = block.nodeOffset(inst_data.src_node);
95409542
95419543 var extra_index = extra.end;
95429544
......@@ -9588,7 +9590,7 @@ fn zirFunc(
95889590 // error by trying to evaluate `std.builtin.CallingConvention.c`, so for consistency,
95899591 // let's eval that now and just get the transitive error. (It's guaranteed to error
95909592 // because it does the exact `cCallingConvention` call we just did.)
9591 const cc_type = try sema.getBuiltinType("CallingConvention");
9593 const cc_type = try sema.getBuiltinType(src, .CallingConvention);
95929594 _ = try sema.namespaceLookupVal(
95939595 block,
95949596 LazySrcLoc.unneeded,
......@@ -10302,7 +10304,7 @@ fn finishFunc(
1030210304 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {
1030310305 // Make sure that StackTrace's fields are resolved so that the backend can
1030410306 // lower this fn type.
10305 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
10307 const unresolved_stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace);
1030610308 try unresolved_stack_trace_ty.resolveFields(pt);
1030710309 }
1030810310
......@@ -14283,7 +14285,7 @@ fn maybeErrorUnwrap(
1428314285 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1428414286 const msg_inst = try sema.resolveInst(inst_data.operand);
1428514287
14286 const panic_fn = try getPanicInnerFn(sema, block, operand_src, "call");
14288 const panic_fn = try getBuiltin(sema, operand_src, .@"Panic.call");
1428714289 const err_return_trace = try sema.getErrorReturnTrace(block);
1428814290 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };
1428914291 try sema.callBuiltin(block, operand_src, Air.internedToRef(panic_fn), .auto, &args, .@"safety check");
......@@ -17477,7 +17479,7 @@ fn analyzeArithmetic(
1747717479 if (block.wantSafety() and want_safety and scalar_tag == .int) {
1747817480 if (zcu.backendSupportsFeature(.safety_checked_instructions)) {
1747917481 if (air_tag != air_tag_safe) {
17480 _ = try sema.preparePanicId(block, src, .integer_overflow);
17482 _ = try sema.preparePanicId(src, .integer_overflow);
1748117483 }
1748217484 return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs);
1748317485 } else {
......@@ -18381,7 +18383,7 @@ fn zirBuiltinSrc(
1838118383 } });
1838218384 };
1838318385
18384 const src_loc_ty = try sema.getBuiltinType("SourceLocation");
18386 const src_loc_ty = try sema.getBuiltinType(block.nodeOffset(0), .SourceLocation);
1838518387 const fields = .{
1838618388 // module: [:0]const u8,
1838718389 module_name_val,
......@@ -18408,7 +18410,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1840818410 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1840918411 const src = block.nodeOffset(inst_data.src_node);
1841018412 const ty = try sema.resolveType(block, src, inst_data.operand);
18411 const type_info_ty = try sema.getBuiltinType("Type");
18413 const type_info_ty = try sema.getBuiltinType(src, .Type);
1841218414 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;
1841318415
1841418416 if (ty.typeDeclInst(zcu)) |type_decl_inst| {
......@@ -18428,8 +18430,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1842818430 => |type_info_tag| return unionInitFromEnumTag(sema, block, src, type_info_ty, @intFromEnum(type_info_tag), .void_value),
1842918431
1843018432 .@"fn" => {
18431 const fn_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Fn");
18432 const param_info_ty = try getBuiltinInnerType(sema, block, src, fn_info_ty, "Type.Fn", "Param");
18433 const fn_info_ty = try sema.getBuiltinType(src, .@"Type.Fn");
18434 const param_info_ty = try sema.getBuiltinType(src, .@"Type.Fn.Param");
1843318435
1843418436 const func_ty_info = zcu.typeToFunc(ty).?;
1843518437 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
......@@ -18499,7 +18501,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1849918501 func_ty_info.return_type,
1850018502 } });
1850118503
18502 const callconv_ty = try sema.getBuiltinType("CallingConvention");
18504 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
1850318505 const callconv_val = Value.uninterpret(func_ty_info.cc, callconv_ty, pt) catch |err| switch (err) {
1850418506 error.TypeMismatch => @panic("std.builtin is corrupt"),
1850518507 error.OutOfMemory => |e| return e,
......@@ -18527,8 +18529,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1852718529 })));
1852818530 },
1852918531 .int => {
18530 const int_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Int");
18531 const signedness_ty = try sema.getBuiltinType("Signedness");
18532 const int_info_ty = try sema.getBuiltinType(src, .@"Type.Int");
18533 const signedness_ty = try sema.getBuiltinType(src, .Signedness);
1853218534 const info = ty.intInfo(zcu);
1853318535 const field_values = .{
1853418536 // signedness: Signedness,
......@@ -18546,7 +18548,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1854618548 })));
1854718549 },
1854818550 .float => {
18549 const float_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Float");
18551 const float_info_ty = try sema.getBuiltinType(src, .@"Type.Float");
1855018552
1855118553 const field_vals = .{
1855218554 // bits: u16,
......@@ -18568,9 +18570,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1856818570 else
1856918571 try Type.fromInterned(info.child).lazyAbiAlignment(pt);
1857018572
18571 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
18572 const pointer_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Pointer");
18573 const ptr_size_ty = try getBuiltinInnerType(sema, block, src, pointer_ty, "Type.Pointer", "Size");
18573 const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
18574 const pointer_ty = try sema.getBuiltinType(src, .@"Type.Pointer");
18575 const ptr_size_ty = try sema.getBuiltinType(src, .@"Type.Pointer.Size");
1857418576
1857518577 const field_values = .{
1857618578 // size: Size,
......@@ -18603,7 +18605,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1860318605 })));
1860418606 },
1860518607 .array => {
18606 const array_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Array");
18608 const array_field_ty = try sema.getBuiltinType(src, .@"Type.Array");
1860718609
1860818610 const info = ty.arrayInfo(zcu);
1860918611 const field_values = .{
......@@ -18624,7 +18626,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1862418626 })));
1862518627 },
1862618628 .vector => {
18627 const vector_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Vector");
18629 const vector_field_ty = try sema.getBuiltinType(src, .@"Type.Vector");
1862818630
1862918631 const info = ty.arrayInfo(zcu);
1863018632 const field_values = .{
......@@ -18643,7 +18645,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1864318645 })));
1864418646 },
1864518647 .optional => {
18646 const optional_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Optional");
18648 const optional_field_ty = try sema.getBuiltinType(src, .@"Type.Optional");
1864718649
1864818650 const field_values = .{
1864918651 // child: type,
......@@ -18660,7 +18662,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1866018662 },
1866118663 .error_set => {
1866218664 // Get the Error type
18663 const error_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Error");
18665 const error_field_ty = try sema.getBuiltinType(src, .@"Type.Error");
1866418666
1866518667 // Build our list of Error values
1866618668 // Optional value is only null if anyerror
......@@ -18756,7 +18758,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1875618758 })));
1875718759 },
1875818760 .error_union => {
18759 const error_union_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ErrorUnion");
18761 const error_union_field_ty = try sema.getBuiltinType(src, .@"Type.ErrorUnion");
1876018762
1876118763 const field_values = .{
1876218764 // error_set: type,
......@@ -18776,7 +18778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1877618778 .@"enum" => {
1877718779 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);
1877818780
18779 const enum_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "EnumField");
18781 const enum_field_ty = try sema.getBuiltinType(src, .@"Type.EnumField");
1878018782
1878118783 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);
1878218784 for (enum_field_vals, 0..) |*field_val, tag_index| {
......@@ -18861,9 +18863,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1886118863 } });
1886218864 };
1886318865
18864 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace.toOptional());
18866 const decls_val = try sema.typeInfoDecls(block, src, ip.loadEnumType(ty.toIntern()).namespace.toOptional());
1886518867
18866 const type_enum_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Enum");
18868 const type_enum_ty = try sema.getBuiltinType(src, .@"Type.Enum");
1886718869
1886818870 const field_values = .{
1886918871 // tag_type: type,
......@@ -18885,8 +18887,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1888518887 })));
1888618888 },
1888718889 .@"union" => {
18888 const type_union_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Union");
18889 const union_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "UnionField");
18890 const type_union_ty = try sema.getBuiltinType(src, .@"Type.Union");
18891 const union_field_ty = try sema.getBuiltinType(src, .@"Type.UnionField");
1889018892
1889118893 try ty.resolveLayout(pt); // Getting alignment requires type layout
1889218894 const union_obj = zcu.typeToUnion(ty).?;
......@@ -18974,14 +18976,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1897418976 } });
1897518977 };
1897618978
18977 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(zcu).toOptional());
18979 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespaceIndex(zcu).toOptional());
1897818980
1897918981 const enum_tag_ty_val = try pt.intern(.{ .opt = .{
1898018982 .ty = (try pt.optionalType(.type_type)).toIntern(),
1898118983 .val = if (ty.unionTagType(zcu)) |tag_ty| tag_ty.toIntern() else .none,
1898218984 } });
1898318985
18984 const container_layout_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ContainerLayout");
18986 const container_layout_ty = try sema.getBuiltinType(src, .@"Type.ContainerLayout");
1898518987
1898618988 const field_values = .{
1898718989 // layout: ContainerLayout,
......@@ -19004,8 +19006,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1900419006 })));
1900519007 },
1900619008 .@"struct" => {
19007 const type_struct_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Struct");
19008 const struct_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "StructField");
19009 const type_struct_ty = try sema.getBuiltinType(src, .@"Type.Struct");
19010 const struct_field_ty = try sema.getBuiltinType(src, .@"Type.StructField");
1900919011
1901019012 try ty.resolveLayout(pt); // Getting alignment requires type layout
1901119013
......@@ -19169,7 +19171,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1916919171 } });
1917019172 };
1917119173
19172 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(zcu));
19174 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespace(zcu));
1917319175
1917419176 const backing_integer_val = try pt.intern(.{ .opt = .{
1917519177 .ty = (try pt.optionalType(.type_type)).toIntern(),
......@@ -19179,7 +19181,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1917919181 } else .none,
1918019182 } });
1918119183
19182 const container_layout_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ContainerLayout");
19184 const container_layout_ty = try sema.getBuiltinType(src, .@"Type.ContainerLayout");
1918319185
1918419186 const layout = ty.containerLayout(zcu);
1918519187
......@@ -19205,10 +19207,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1920519207 })));
1920619208 },
1920719209 .@"opaque" => {
19208 const type_opaque_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Opaque");
19210 const type_opaque_ty = try sema.getBuiltinType(src, .@"Type.Opaque");
1920919211
1921019212 try ty.resolveFields(pt);
19211 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(zcu));
19213 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespace(zcu));
1921219214
1921319215 const field_values = .{
1921419216 // decls: []const Declaration,
......@@ -19232,14 +19234,13 @@ fn typeInfoDecls(
1923219234 sema: *Sema,
1923319235 block: *Block,
1923419236 src: LazySrcLoc,
19235 type_info_ty: Type,
1923619237 opt_namespace: InternPool.OptionalNamespaceIndex,
1923719238) CompileError!InternPool.Index {
1923819239 const pt = sema.pt;
1923919240 const zcu = pt.zcu;
1924019241 const gpa = sema.gpa;
1924119242
19242 const declaration_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Declaration");
19243 const declaration_ty = try sema.getBuiltinType(src, .@"Type.Declaration");
1924319244
1924419245 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
1924519246 defer decl_vals.deinit();
......@@ -20181,11 +20182,11 @@ fn retWithErrTracing(
2018120182 else => true,
2018220183 };
2018320184 const gpa = sema.gpa;
20184 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
20185 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
2018520186 try stack_trace_ty.resolveFields(pt);
2018620187 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
2018720188 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
20188 const return_err_fn = try sema.getBuiltin("returnError");
20189 const return_err_fn = Air.internedToRef(try sema.getBuiltin(src, .returnError));
2018920190 const args: [1]Air.Inst.Ref = .{err_return_trace};
2019020191
2019120192 if (!need_check) {
......@@ -21607,7 +21608,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
2160721608 const pt = sema.pt;
2160821609 const zcu = pt.zcu;
2160921610 const ip = &zcu.intern_pool;
21610 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
21611 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace);
2161121612 try stack_trace_ty.resolveFields(pt);
2161221613 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
2161321614 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
......@@ -21616,7 +21617,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
2161621617 .func => |func| if (ip.funcAnalysisUnordered(func).calls_or_awaits_errorable_fn and block.ownerModule().error_tracing) {
2161721618 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
2161821619 },
21619 .@"comptime", .nav_ty, .nav_val, .type => {},
21620 .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {},
2162021621 }
2162121622 return Air.internedToRef(try pt.intern(.{ .opt = .{
2162221623 .ty = opt_ptr_stack_trace_ty.toIntern(),
......@@ -21896,7 +21897,7 @@ fn zirReify(
2189621897 },
2189721898 },
2189821899 };
21899 const type_info_ty = try sema.getBuiltinType("Type");
21900 const type_info_ty = try sema.getBuiltinType(src, .Type);
2190021901 const uncasted_operand = try sema.resolveInst(extra.operand);
2190121902 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
2190221903 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{ .simple = .operand_Type });
......@@ -23156,7 +23157,7 @@ fn reifyStruct(
2315623157
2315723158fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
2315823159 const pt = sema.pt;
23159 const va_list_ty = try sema.getBuiltinType("VaList");
23160 const va_list_ty = try sema.getBuiltinType(src, .VaList);
2316023161 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);
2316123162
2316223163 const inst = try sema.resolveInst(zir_ref);
......@@ -23195,7 +23196,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
2319523196 const va_list_src = block.builtinCallArgSrc(extra.node, 0);
2319623197
2319723198 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);
23198 const va_list_ty = try sema.getBuiltinType("VaList");
23199 const va_list_ty = try sema.getBuiltinType(src, .VaList);
2319923200
2320023201 try sema.requireRuntimeBlock(block, src, null);
2320123202 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);
......@@ -23215,7 +23216,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2321523216fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
2321623217 const src = block.nodeOffset(@bitCast(extended.operand));
2321723218
23218 const va_list_ty = try sema.getBuiltinType("VaList");
23219 const va_list_ty = try sema.getBuiltinType(src, .VaList);
2321923220 try sema.requireRuntimeBlock(block, src, null);
2322023221 return block.addInst(.{
2322123222 .tag = .c_va_start,
......@@ -24821,7 +24822,7 @@ fn resolveExportOptions(
2482124822 const zcu = pt.zcu;
2482224823 const gpa = sema.gpa;
2482324824 const ip = &zcu.intern_pool;
24824 const export_options_ty = try sema.getBuiltinType("ExportOptions");
24825 const export_options_ty = try sema.getBuiltinType(src, .ExportOptions);
2482524826 const air_ref = try sema.resolveInst(zir_ref);
2482624827 const options = try sema.coerce(block, export_options_ty, air_ref, src);
2482724828
......@@ -24871,15 +24872,15 @@ fn resolveBuiltinEnum(
2487124872 block: *Block,
2487224873 src: LazySrcLoc,
2487324874 zir_ref: Zir.Inst.Ref,
24874 comptime name: []const u8,
24875 comptime name: Zcu.BuiltinDecl,
2487524876 reason: ComptimeReason,
24876) CompileError!@field(std.builtin, name) {
24877) CompileError!@field(std.builtin, @tagName(name)) {
2487724878 const pt = sema.pt;
24878 const ty = try sema.getBuiltinType(name);
24879 const ty = try sema.getBuiltinType(src, name);
2487924880 const air_ref = try sema.resolveInst(zir_ref);
2488024881 const coerced = try sema.coerce(block, ty, air_ref, src);
2488124882 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
24882 return pt.zcu.toEnum(@field(std.builtin, name), val);
24883 return pt.zcu.toEnum(@field(std.builtin, @tagName(name)), val);
2488324884}
2488424885
2488524886fn resolveAtomicOrder(
......@@ -24889,7 +24890,7 @@ fn resolveAtomicOrder(
2488924890 zir_ref: Zir.Inst.Ref,
2489024891 reason: ComptimeReason,
2489124892) CompileError!std.builtin.AtomicOrder {
24892 return sema.resolveBuiltinEnum(block, src, zir_ref, "AtomicOrder", reason);
24893 return sema.resolveBuiltinEnum(block, src, zir_ref, .AtomicOrder, reason);
2489324894}
2489424895
2489524896fn resolveAtomicRmwOp(
......@@ -24898,7 +24899,7 @@ fn resolveAtomicRmwOp(
2489824899 src: LazySrcLoc,
2489924900 zir_ref: Zir.Inst.Ref,
2490024901) CompileError!std.builtin.AtomicRmwOp {
24901 return sema.resolveBuiltinEnum(block, src, zir_ref, "AtomicRmwOp", .{ .simple = .operand_atomicRmw_operation });
24902 return sema.resolveBuiltinEnum(block, src, zir_ref, .AtomicRmwOp, .{ .simple = .operand_atomicRmw_operation });
2490224903}
2490324904
2490424905fn zirCmpxchg(
......@@ -25078,7 +25079,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2507825079 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2507925080 const op_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2508025081 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 1);
25081 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp", .{ .simple = .operand_reduce_operation });
25082 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, .ReduceOp, .{ .simple = .operand_reduce_operation });
2508225083 const operand = try sema.resolveInst(extra.rhs);
2508325084 const operand_ty = sema.typeOf(operand);
2508425085 const pt = sema.pt;
......@@ -25668,7 +25669,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2566825669 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
2566925670 const func = try sema.resolveInst(extra.callee);
2567025671
25671 const modifier_ty = try sema.getBuiltinType("CallModifier");
25672 const modifier_ty = try sema.getBuiltinType(call_src, .CallModifier);
2567225673 const air_ref = try sema.resolveInst(extra.modifier);
2567325674 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);
2567425675 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{ .simple = .call_modifier });
......@@ -26630,13 +26631,13 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2663026631 const body = sema.code.bodySlice(extra_index, body_len);
2663126632 extra_index += body.len;
2663226633
26633 const cc_ty = try sema.getBuiltinType("CallingConvention");
26634 const cc_ty = try sema.getBuiltinType(cc_src, .CallingConvention);
2663426635 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{ .simple = .@"callconv" });
2663526636 break :blk try sema.analyzeValueAsCallconv(block, cc_src, val);
2663626637 } else if (extra.data.bits.has_cc_ref) blk: {
2663726638 const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
2663826639 extra_index += 1;
26639 const cc_ty = try sema.getBuiltinType("CallingConvention");
26640 const cc_ty = try sema.getBuiltinType(cc_src, .CallingConvention);
2664026641 const uncoerced_cc = try sema.resolveInst(cc_ref);
2664126642 const coerced_cc = try sema.coerce(block, cc_ty, uncoerced_cc, cc_src);
2664226643 const cc_val = try sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{ .simple = .@"callconv" });
......@@ -26656,7 +26657,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2665626657 // error by trying to evaluate `std.builtin.CallingConvention.c`, so for consistency,
2665726658 // let's eval that now and just get the transitive error. (It's guaranteed to error
2665826659 // because it does the exact `cCallingConvention` call we just did.)
26659 const cc_type = try sema.getBuiltinType("CallingConvention");
26660 const cc_type = try sema.getBuiltinType(cc_src, .CallingConvention);
2666026661 _ = try sema.namespaceLookupVal(
2666126662 block,
2666226663 LazySrcLoc.unneeded,
......@@ -26834,7 +26835,7 @@ fn resolvePrefetchOptions(
2683426835 const zcu = pt.zcu;
2683526836 const gpa = sema.gpa;
2683626837 const ip = &zcu.intern_pool;
26837 const options_ty = try sema.getBuiltinType("PrefetchOptions");
26838 const options_ty = try sema.getBuiltinType(src, .PrefetchOptions);
2683826839 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
2683926840
2684026841 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });
......@@ -26902,7 +26903,7 @@ fn resolveExternOptions(
2690226903 const gpa = sema.gpa;
2690326904 const ip = &zcu.intern_pool;
2690426905 const options_inst = try sema.resolveInst(zir_ref);
26905 const extern_options_ty = try sema.getBuiltinType("ExternOptions");
26906 const extern_options_ty = try sema.getBuiltinType(src, .ExternOptions);
2690626907 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
2690726908
2690826909 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
......@@ -27004,6 +27005,7 @@ fn zirBuiltinExtern(
2700427005 .zir_index = switch (sema.owner.unwrap()) {
2700527006 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index,
2700627007 .type => |owner_ty| Type.fromInterned(owner_ty).typeDeclInst(zcu).?,
27008 .memoized_state => unreachable,
2700727009 .nav_ty, .nav_val => |nav| ip.getNav(nav).analysis.?.zir_index,
2700827010 .func => |func| zir_index: {
2700927011 const func_info = zcu.funcInfo(func);
......@@ -27081,23 +27083,25 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2708127083 const src = block.nodeOffset(@bitCast(extended.operand));
2708227084 const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small);
2708327085
27084 const type_name = switch (value) {
27085 .atomic_order => "AtomicOrder",
27086 .atomic_rmw_op => "AtomicRmwOp",
27087 .calling_convention => "CallingConvention",
27088 .address_space => "AddressSpace",
27089 .float_mode => "FloatMode",
27090 .reduce_op => "ReduceOp",
27091 .call_modifier => "CallModifier",
27092 .prefetch_options => "PrefetchOptions",
27093 .export_options => "ExportOptions",
27094 .extern_options => "ExternOptions",
27095 .type_info => "Type",
27096 .branch_hint => "BranchHint",
27086 const ty = switch (value) {
27087 // zig fmt: off
27088 .atomic_order => try sema.getBuiltinType(src, .AtomicOrder),
27089 .atomic_rmw_op => try sema.getBuiltinType(src, .AtomicRmwOp),
27090 .calling_convention => try sema.getBuiltinType(src, .CallingConvention),
27091 .address_space => try sema.getBuiltinType(src, .AddressSpace),
27092 .float_mode => try sema.getBuiltinType(src, .FloatMode),
27093 .reduce_op => try sema.getBuiltinType(src, .ReduceOp),
27094 .call_modifier => try sema.getBuiltinType(src, .CallModifier),
27095 .prefetch_options => try sema.getBuiltinType(src, .PrefetchOptions),
27096 .export_options => try sema.getBuiltinType(src, .ExportOptions),
27097 .extern_options => try sema.getBuiltinType(src, .ExternOptions),
27098 .type_info => try sema.getBuiltinType(src, .Type),
27099 .branch_hint => try sema.getBuiltinType(src, .BranchHint),
27100 // zig fmt: on
2709727101
2709827102 // Values are handled here.
2709927103 .calling_convention_c => {
27100 const callconv_ty = try sema.getBuiltinType("CallingConvention");
27104 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
2710127105 return try sema.namespaceLookupVal(
2710227106 block,
2710327107 src,
......@@ -27107,7 +27111,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2710727111 },
2710827112 .calling_convention_inline => {
2710927113 comptime assert(@typeInfo(std.builtin.CallingConvention.Tag).@"enum".tag_type == u8);
27110 const callconv_ty = try sema.getBuiltinType("CallingConvention");
27114 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
2711127115 const callconv_tag_ty = callconv_ty.unionTagType(zcu) orelse @panic("std.builtin is corrupt");
2711227116 const inline_tag_val = try pt.enumValue(
2711327117 callconv_tag_ty,
......@@ -27119,7 +27123,6 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2711927123 return sema.coerce(block, callconv_ty, Air.internedToRef(inline_tag_val.toIntern()), src);
2712027124 },
2712127125 };
27122 const ty = try sema.getBuiltinType(type_name);
2712327126 return Air.internedToRef(ty.toIntern());
2712427127}
2712527128
......@@ -27158,7 +27161,7 @@ fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
2715827161 const uncoerced_hint = try sema.resolveInst(extra.operand);
2715927162 const operand_src = block.builtinCallArgSrc(extra.node, 0);
2716027163
27161 const hint_ty = try sema.getBuiltinType("BranchHint");
27164 const hint_ty = try sema.getBuiltinType(operand_src, .BranchHint);
2716227165 const coerced_hint = try sema.coerce(block, hint_ty, uncoerced_hint, operand_src);
2716327166 const hint_val = try sema.resolveConstDefinedValue(block, operand_src, coerced_hint, .{ .simple = .operand_branchHint });
2716427167
......@@ -27603,61 +27606,19 @@ fn explainWhyTypeIsNotPacked(
2760327606 }
2760427607}
2760527608
27606fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
27607 const pt = sema.pt;
27608 const zcu = pt.zcu;
27609
27610 if (zcu.panic_func_index == .none) {
27611 zcu.panic_func_index = try sema.getPanicInnerFn(block, src, "call");
27612 // Here, function body analysis must be queued up so that backends can
27613 // make calls to this function.
27614 try zcu.ensureFuncBodyAnalysisQueued(zcu.panic_func_index);
27615 }
27616
27617 if (zcu.null_stack_trace == .none) {
27618 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
27619 try stack_trace_ty.resolveFields(pt);
27620 const target = zcu.getTarget();
27621 const ptr_stack_trace_ty = try pt.ptrTypeSema(.{
27622 .child = stack_trace_ty.toIntern(),
27623 .flags = .{
27624 .address_space = target_util.defaultAddressSpace(target, .global_constant),
27625 },
27626 });
27627 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
27628 zcu.null_stack_trace = try pt.intern(.{ .opt = .{
27629 .ty = opt_ptr_stack_trace_ty.toIntern(),
27630 .val = .none,
27631 } });
27632 }
27633}
27634
2763527609/// Backends depend on panic decls being available when lowering safety-checked
2763627610/// instructions. This function ensures the panic function will be available to
2763727611/// be called during that time.
27638fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Zcu.PanicId) !InternPool.Nav.Index {
27639 const pt = sema.pt;
27640 const zcu = pt.zcu;
27641 const gpa = sema.gpa;
27642 if (zcu.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;
27643
27644 try sema.prepareSimplePanic(block, src);
27645
27646 const panic_ty = try sema.getBuiltinType("Panic");
27647 const panic_messages_ty = try sema.getBuiltinInnerType(block, src, panic_ty, "Panic", "messages");
27648 const msg_nav_index = (sema.namespaceLookup(
27649 block,
27650 LazySrcLoc.unneeded,
27651 panic_messages_ty.getNamespaceIndex(zcu),
27652 try zcu.intern_pool.getOrPutString(gpa, pt.tid, @tagName(panic_id), .no_embedded_nulls),
27653 ) catch |err| switch (err) {
27654 error.AnalysisFail => return error.AnalysisFail,
27655 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
27656 error.OutOfMemory => |e| return e,
27657 }).?;
27658 try sema.ensureNavResolved(src, msg_nav_index, .fully);
27659 zcu.panic_messages[@intFromEnum(panic_id)] = msg_nav_index.toOptional();
27660 return msg_nav_index;
27612fn preparePanicId(sema: *Sema, src: LazySrcLoc, panic_id: Zcu.PanicId) !InternPool.Index {
27613 const zcu = sema.pt.zcu;
27614 try sema.ensureMemoizedStateResolved(src, .panic);
27615 try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.@"Panic.call");
27616 switch (panic_id) {
27617 inline else => |ct_panic_id| {
27618 const name = "Panic.messages." ++ @tagName(ct_panic_id);
27619 return @field(zcu.builtin_decl_values, name);
27620 },
27621 }
2766127622}
2766227623
2766327624fn addSafetyCheck(
......@@ -27761,10 +27722,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
2776127722 return;
2776227723 }
2776327724
27764 try sema.prepareSimplePanic(block, src);
27725 try sema.ensureMemoizedStateResolved(src, .panic);
27726 try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.@"Panic.call");
2776527727
27766 const panic_func = zcu.funcInfo(zcu.panic_func_index);
27767 const panic_fn = try sema.analyzeNavVal(block, src, panic_func.owner_nav);
27728 const panic_fn = Air.internedToRef(zcu.builtin_decl_values.@"Panic.call");
2776827729 const null_stack_trace = Air.internedToRef(zcu.null_stack_trace);
2776927730
2777027731 const opt_usize_ty = try pt.optionalType(.usize_type);
......@@ -27812,7 +27773,7 @@ fn safetyPanicUnwrapError(sema: *Sema, block: *Block, src: LazySrcLoc, err: Air.
2781227773 if (!zcu.backendSupportsFeature(.panic_fn)) {
2781327774 _ = try block.addNoOp(.trap);
2781427775 } else {
27815 const panic_fn = try getPanicInnerFn(sema, block, src, "unwrapError");
27776 const panic_fn = try getBuiltin(sema, src, .@"Panic.unwrapError");
2781627777 const err_return_trace = try sema.getErrorReturnTrace(block);
2781727778 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
2781827779 try sema.callBuiltin(block, src, Air.internedToRef(panic_fn), .auto, &args, .@"safety check");
......@@ -27829,7 +27790,7 @@ fn addSafetyCheckIndexOob(
2782927790) !void {
2783027791 assert(!parent_block.isComptime());
2783127792 const ok = try parent_block.addBinOp(cmp_op, index, len);
27832 return addSafetyCheckCall(sema, parent_block, src, ok, "outOfBounds", &.{ index, len });
27793 return addSafetyCheckCall(sema, parent_block, src, ok, .@"Panic.outOfBounds", &.{ index, len });
2783327794}
2783427795
2783527796fn addSafetyCheckInactiveUnionField(
......@@ -27841,7 +27802,7 @@ fn addSafetyCheckInactiveUnionField(
2784127802) !void {
2784227803 assert(!parent_block.isComptime());
2784327804 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);
27844 return addSafetyCheckCall(sema, parent_block, src, ok, "inactiveUnionField", &.{ active_tag, wanted_tag });
27805 return addSafetyCheckCall(sema, parent_block, src, ok, .@"Panic.inactiveUnionField", &.{ active_tag, wanted_tag });
2784527806}
2784627807
2784727808fn addSafetyCheckSentinelMismatch(
......@@ -27882,7 +27843,7 @@ fn addSafetyCheckSentinelMismatch(
2788227843 break :ok try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel);
2788327844 };
2788427845
27885 return addSafetyCheckCall(sema, parent_block, src, ok, "sentinelMismatch", &.{
27846 return addSafetyCheckCall(sema, parent_block, src, ok, .@"Panic.sentinelMismatch", &.{
2788627847 expected_sentinel, actual_sentinel,
2788727848 });
2788827849}
......@@ -27892,7 +27853,7 @@ fn addSafetyCheckCall(
2789227853 parent_block: *Block,
2789327854 src: LazySrcLoc,
2789427855 ok: Air.Inst.Ref,
27895 func_name: []const u8,
27856 comptime func_decl: Zcu.BuiltinDecl,
2789627857 args: []const Air.Inst.Ref,
2789727858) !void {
2789827859 assert(!parent_block.isComptime());
......@@ -27916,7 +27877,7 @@ fn addSafetyCheckCall(
2791627877 if (!zcu.backendSupportsFeature(.panic_fn)) {
2791727878 _ = try fail_block.addNoOp(.trap);
2791827879 } else {
27919 const panic_fn = try getPanicInnerFn(sema, &fail_block, src, func_name);
27880 const panic_fn = try getBuiltin(sema, src, func_decl);
2792027881 try sema.callBuiltin(&fail_block, src, Air.internedToRef(panic_fn), .auto, args, .@"safety check");
2792127882 }
2792227883
......@@ -27925,9 +27886,8 @@ fn addSafetyCheckCall(
2792527886
2792627887/// This does not set `sema.branch_hint`.
2792727888fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Zcu.PanicId) CompileError!void {
27928 const msg_nav_index = try sema.preparePanicId(block, src, panic_id);
27929 const msg_inst = try sema.analyzeNavVal(block, src, msg_nav_index);
27930 try sema.panicWithMsg(block, src, msg_inst, .@"safety check");
27889 const msg_val = try sema.preparePanicId(src, panic_id);
27890 try sema.panicWithMsg(block, src, Air.internedToRef(msg_val), .@"safety check");
2793127891}
2793227892
2793327893fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
......@@ -32524,6 +32484,19 @@ fn addTypeReferenceEntry(
3252432484 try zcu.addTypeReference(sema.owner, referenced_type, src);
3252532485}
3252632486
32487fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.MemoizedStateStage) SemaError!void {
32488 const pt = sema.pt;
32489
32490 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
32491 try sema.addReferenceEntry(src, unit);
32492 try sema.declareDependency(.{ .memoized_state = stage });
32493
32494 if (pt.zcu.analysis_in_progress.contains(unit)) {
32495 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(src, "dependency loop detected", .{}));
32496 }
32497 try pt.ensureMemoizedStateUpToDate(stage);
32498}
32499
3252732500pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void {
3252832501 const pt = sema.pt;
3252932502 const zcu = pt.zcu;
......@@ -33373,7 +33346,7 @@ fn analyzeSlice(
3337333346 assert(!block.isComptime());
3337433347 try sema.requireRuntimeBlock(block, src, runtime_src.?);
3337533348 const ok = try block.addBinOp(.cmp_lte, start, end);
33376 try sema.addSafetyCheckCall(block, src, ok, "startGreaterThanEnd", &.{ start, end });
33349 try sema.addSafetyCheckCall(block, src, ok, .@"Panic.startGreaterThanEnd", &.{ start, end });
3337733350 }
3337833351 const new_len = if (by_length)
3337933352 try sema.coerce(block, Type.usize, uncasted_end_opt, end_src)
......@@ -35493,7 +35466,7 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void
3549335466 }
3549435467}
3549535468
35496pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
35469pub fn resolveFnTypes(sema: *Sema, fn_ty: Type, src: LazySrcLoc) CompileError!void {
3549735470 const pt = sema.pt;
3549835471 const zcu = pt.zcu;
3549935472 const ip = &zcu.intern_pool;
......@@ -35505,7 +35478,7 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
3550535478 Type.fromInterned(fn_ty_info.return_type).isError(zcu))
3550635479 {
3550735480 // Ensure the type exists so that backends can assume that.
35508 _ = try sema.getBuiltinType("StackTrace");
35481 _ = try sema.getBuiltinType(src, .StackTrace);
3550935482 }
3551035483
3551135484 for (0..fn_ty_info.param_types.len) |i| {
......@@ -37550,7 +37523,7 @@ pub fn analyzeAsAddressSpace(
3755037523) !std.builtin.AddressSpace {
3755137524 const pt = sema.pt;
3755237525 const zcu = pt.zcu;
37553 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
37526 const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
3755437527 const coerced = try sema.coerce(block, addrspace_ty, air_ref, src);
3755537528 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ .simple = .@"addrspace" });
3755637529 const address_space = zcu.toEnum(std.builtin.AddressSpace, addrspace_val);
......@@ -38747,69 +38720,15 @@ const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadR
3874738720const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;
3874838721const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult;
3874938722
38750fn getPanicInnerFn(
38751 sema: *Sema,
38752 block: *Block,
38753 src: LazySrcLoc,
38754 inner_name: []const u8,
38755) !InternPool.Index {
38756 const gpa = sema.gpa;
38757 const pt = sema.pt;
38758 const zcu = pt.zcu;
38759 const ip = &zcu.intern_pool;
38760 const outer_ty = try sema.getBuiltinType("Panic");
38761 const inner_name_ip = try ip.getOrPutString(gpa, pt.tid, inner_name, .no_embedded_nulls);
38762 const opt_fn_ref = try namespaceLookupVal(sema, block, src, outer_ty.getNamespaceIndex(zcu), inner_name_ip);
38763 const fn_ref = opt_fn_ref orelse return sema.fail(block, src, "std.builtin.Panic missing {s}", .{inner_name});
38764 const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{ .simple = .panic_handler });
38765 if (fn_val.typeOf(zcu).zigTypeTag(zcu) != .@"fn") {
38766 return sema.fail(block, src, "std.builtin.Panic.{s} is not a function", .{inner_name});
38767 }
38768 // Better not to queue up function body analysis because the function might be generic, and
38769 // the semantic analysis for the call will already queue if necessary.
38770 return fn_val.toIntern();
38771}
38772
38773fn getBuiltinType(sema: *Sema, name: []const u8) SemaError!Type {
38774 const pt = sema.pt;
38775 const ty_inst = try sema.getBuiltin(name);
38776 const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt"));
38777 try ty.resolveFully(pt);
38778 return ty;
38779}
38780
38781fn getBuiltinInnerType(
38782 sema: *Sema,
38783 block: *Block,
38784 src: LazySrcLoc,
38785 outer_ty: Type,
38786 /// Relative to "std.builtin".
38787 compile_error_parent_name: []const u8,
38788 inner_name: []const u8,
38789) !Type {
38790 const pt = sema.pt;
38791 const zcu = pt.zcu;
38792 const ip = &zcu.intern_pool;
38793 const gpa = sema.gpa;
38794 const inner_name_ip = try ip.getOrPutString(gpa, pt.tid, inner_name, .no_embedded_nulls);
38795 const opt_nav = try sema.namespaceLookup(block, src, outer_ty.getNamespaceIndex(zcu), inner_name_ip);
38796 const nav = opt_nav orelse return sema.fail(block, src, "std.builtin.{s} missing {s}", .{
38797 compile_error_parent_name, inner_name,
38798 });
38799 try sema.ensureNavResolved(src, nav, .fully);
38800 const val = Value.fromInterned(ip.getNav(nav).status.fully_resolved.val);
38801 const ty = val.toType();
38802 try ty.resolveFully(pt);
38803 return ty;
38723pub fn getBuiltinType(sema: *Sema, src: LazySrcLoc, comptime decl: Zcu.BuiltinDecl) SemaError!Type {
38724 comptime assert(decl.kind() == .type);
38725 try sema.ensureMemoizedStateResolved(src, decl.stage());
38726 return .fromInterned(@field(sema.pt.zcu.builtin_decl_values, @tagName(decl)));
3880438727}
38805
38806fn getBuiltin(sema: *Sema, name: []const u8) SemaError!Air.Inst.Ref {
38807 const pt = sema.pt;
38808 const zcu = pt.zcu;
38809 const ip = &zcu.intern_pool;
38810 const nav = try pt.getBuiltinNav(name);
38811 try pt.ensureNavValUpToDate(nav);
38812 return Air.internedToRef(ip.getNav(nav).status.fully_resolved.val);
38728pub fn getBuiltin(sema: *Sema, src: LazySrcLoc, comptime decl: Zcu.BuiltinDecl) SemaError!InternPool.Index {
38729 comptime assert(decl.kind() != .type);
38730 try sema.ensureMemoizedStateResolved(src, decl.stage());
38731 return @field(sema.pt.zcu.builtin_decl_values, @tagName(decl));
3881338732}
3881438733
3881538734pub const NavPtrModifiers = struct {
......@@ -38877,3 +38796,77 @@ pub fn resolveNavPtrModifiers(
3887738796 .@"addrspace" = @"addrspace",
3887838797 };
3887938798}
38799
38800pub fn analyzeMemoizedState(sema: *Sema, block: *Block, src: LazySrcLoc, builtin_namespace: InternPool.NamespaceIndex, stage: InternPool.MemoizedStateStage) CompileError!bool {
38801 const pt = sema.pt;
38802 const zcu = pt.zcu;
38803 const ip = &zcu.intern_pool;
38804 const gpa = zcu.gpa;
38805
38806 var any_changed = false;
38807
38808 inline for (comptime std.enums.values(Zcu.BuiltinDecl)) |builtin_decl| {
38809 if (stage == comptime builtin_decl.stage()) {
38810 const parent_ns: Zcu.Namespace.Index, const parent_name: []const u8, const name: []const u8 = switch (comptime builtin_decl.access()) {
38811 .direct => |name| .{ builtin_namespace, "std.builtin", name },
38812 .nested => |nested| access: {
38813 const parent_ty: Type = .fromInterned(@field(zcu.builtin_decl_values, @tagName(nested[0])));
38814 const parent_ns = parent_ty.getNamespace(zcu).unwrap() orelse {
38815 return sema.fail(block, src, "std.builtin.{s} is not a container type", .{@tagName(nested[0])});
38816 };
38817 break :access .{ parent_ns, "std.builtin." ++ @tagName(nested[0]), nested[1] };
38818 },
38819 };
38820
38821 const name_nts = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
38822 const result = try sema.namespaceLookupVal(block, src, parent_ns, name_nts) orelse
38823 return sema.fail(block, src, "{s} missing {s}", .{ parent_name, name });
38824
38825 const val = try sema.resolveConstDefinedValue(block, src, result, null);
38826
38827 switch (builtin_decl.kind()) {
38828 .type => if (val.typeOf(zcu).zigTypeTag(zcu) != .type) {
38829 return sema.fail(block, src, "{s}.{s} is not a type", .{ parent_name, name });
38830 } else {
38831 try val.toType().resolveFully(pt);
38832 },
38833 .func => if (val.typeOf(zcu).zigTypeTag(zcu) != .@"fn") {
38834 return sema.fail(block, src, "{s}.{s} is not a function", .{ parent_name, name });
38835 },
38836 .string => {
38837 const ty = val.typeOf(zcu);
38838 if (!ty.isSinglePointer(zcu) or
38839 !ty.isConstPtr(zcu) or
38840 ty.childType(zcu).zigTypeTag(zcu) != .array or
38841 ty.childType(zcu).childType(zcu).toIntern() != .u8_type)
38842 {
38843 return sema.fail(block, src, "{s}.{s} is not a valid string", .{ parent_name, name });
38844 }
38845 },
38846 }
38847
38848 const prev = @field(zcu.builtin_decl_values, @tagName(builtin_decl));
38849 if (val.toIntern() != prev) {
38850 @field(zcu.builtin_decl_values, @tagName(builtin_decl)) = val.toIntern();
38851 any_changed = true;
38852 }
38853 }
38854 }
38855
38856 if (stage == .panic) {
38857 // We use `getBuiltinType` because this is from an earlier stage.
38858 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
38859 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
38860 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
38861 const null_stack_trace = try pt.intern(.{ .opt = .{
38862 .ty = opt_ptr_stack_trace_ty.toIntern(),
38863 .val = .none,
38864 } });
38865 if (null_stack_trace != zcu.null_stack_trace) {
38866 zcu.null_stack_trace = null_stack_trace;
38867 any_changed = true;
38868 }
38869 }
38870
38871 return any_changed;
38872}
src/Zcu.zig+211-6
......@@ -217,15 +217,212 @@ all_type_references: std.ArrayListUnmanaged(TypeReference) = .empty,
217217/// Freelist of indices in `all_type_references`.
218218free_type_references: std.ArrayListUnmanaged(u32) = .empty,
219219
220panic_messages: [PanicId.len]InternPool.Nav.Index.Optional = .{.none} ** PanicId.len,
221/// The panic function body.
222panic_func_index: InternPool.Index = .none,
220/// Populated by analysis of `AnalUnit.wrap(.{ .memoized_state = s })`, where `s` depends on the field.
221builtin_decl_values: BuiltinDecl.Memoized = .{},
222/// Populated by analysis of `AnalUnit.wrap(.{ .memoized_state = .panic })`.
223223null_stack_trace: InternPool.Index = .none,
224224
225225generation: u32 = 0,
226226
227227pub const PerThread = @import("Zcu/PerThread.zig");
228228
229/// Names of declarations in `std.builtin` whose values are memoized in a `BuiltinDecl.Memoized`.
230/// The name must exactly match the declaration name, as comptime logic is used to compute the namespace accesses.
231/// Parent namespaces must be before their children in this enum. For instance, `.Type` must be before `.@"Type.Fn"`.
232/// Additionally, parent namespaces must be resolved in the same stage as their children; see `BuiltinDecl.stage`.
233pub const BuiltinDecl = enum {
234 Signedness,
235 AddressSpace,
236 CallingConvention,
237 returnError,
238 StackTrace,
239 SourceLocation,
240 CallModifier,
241 AtomicOrder,
242 AtomicRmwOp,
243 ReduceOp,
244 FloatMode,
245 PrefetchOptions,
246 ExportOptions,
247 ExternOptions,
248 BranchHint,
249
250 Type,
251 @"Type.Fn",
252 @"Type.Fn.Param",
253 @"Type.Int",
254 @"Type.Float",
255 @"Type.Pointer",
256 @"Type.Pointer.Size",
257 @"Type.Array",
258 @"Type.Vector",
259 @"Type.Optional",
260 @"Type.Error",
261 @"Type.ErrorUnion",
262 @"Type.EnumField",
263 @"Type.Enum",
264 @"Type.Union",
265 @"Type.UnionField",
266 @"Type.Struct",
267 @"Type.StructField",
268 @"Type.ContainerLayout",
269 @"Type.Opaque",
270 @"Type.Declaration",
271
272 Panic,
273 @"Panic.call",
274 @"Panic.sentinelMismatch",
275 @"Panic.unwrapError",
276 @"Panic.outOfBounds",
277 @"Panic.startGreaterThanEnd",
278 @"Panic.inactiveUnionField",
279 @"Panic.messages",
280 @"Panic.messages.reached_unreachable",
281 @"Panic.messages.unwrap_null",
282 @"Panic.messages.cast_to_null",
283 @"Panic.messages.incorrect_alignment",
284 @"Panic.messages.invalid_error_code",
285 @"Panic.messages.cast_truncated_data",
286 @"Panic.messages.negative_to_unsigned",
287 @"Panic.messages.integer_overflow",
288 @"Panic.messages.shl_overflow",
289 @"Panic.messages.shr_overflow",
290 @"Panic.messages.divide_by_zero",
291 @"Panic.messages.exact_division_remainder",
292 @"Panic.messages.integer_part_out_of_bounds",
293 @"Panic.messages.corrupt_switch",
294 @"Panic.messages.shift_rhs_too_big",
295 @"Panic.messages.invalid_enum_value",
296 @"Panic.messages.for_len_mismatch",
297 @"Panic.messages.memcpy_len_mismatch",
298 @"Panic.messages.memcpy_alias",
299 @"Panic.messages.noreturn_returned",
300
301 VaList,
302
303 /// Determines what kind of validation will be done to the decl's value.
304 pub fn kind(decl: BuiltinDecl) enum { type, func, string } {
305 return switch (decl) {
306 .returnError => .func,
307
308 .StackTrace,
309 .CallingConvention,
310 .SourceLocation,
311 .Signedness,
312 .AddressSpace,
313 .VaList,
314 .CallModifier,
315 .AtomicOrder,
316 .AtomicRmwOp,
317 .ReduceOp,
318 .FloatMode,
319 .PrefetchOptions,
320 .ExportOptions,
321 .ExternOptions,
322 .BranchHint,
323 => .type,
324
325 .Type,
326 .@"Type.Fn",
327 .@"Type.Fn.Param",
328 .@"Type.Int",
329 .@"Type.Float",
330 .@"Type.Pointer",
331 .@"Type.Pointer.Size",
332 .@"Type.Array",
333 .@"Type.Vector",
334 .@"Type.Optional",
335 .@"Type.Error",
336 .@"Type.ErrorUnion",
337 .@"Type.EnumField",
338 .@"Type.Enum",
339 .@"Type.Union",
340 .@"Type.UnionField",
341 .@"Type.Struct",
342 .@"Type.StructField",
343 .@"Type.ContainerLayout",
344 .@"Type.Opaque",
345 .@"Type.Declaration",
346 => .type,
347
348 .Panic => .type,
349
350 .@"Panic.call",
351 .@"Panic.sentinelMismatch",
352 .@"Panic.unwrapError",
353 .@"Panic.outOfBounds",
354 .@"Panic.startGreaterThanEnd",
355 .@"Panic.inactiveUnionField",
356 => .func,
357
358 .@"Panic.messages" => .type,
359
360 .@"Panic.messages.reached_unreachable",
361 .@"Panic.messages.unwrap_null",
362 .@"Panic.messages.cast_to_null",
363 .@"Panic.messages.incorrect_alignment",
364 .@"Panic.messages.invalid_error_code",
365 .@"Panic.messages.cast_truncated_data",
366 .@"Panic.messages.negative_to_unsigned",
367 .@"Panic.messages.integer_overflow",
368 .@"Panic.messages.shl_overflow",
369 .@"Panic.messages.shr_overflow",
370 .@"Panic.messages.divide_by_zero",
371 .@"Panic.messages.exact_division_remainder",
372 .@"Panic.messages.integer_part_out_of_bounds",
373 .@"Panic.messages.corrupt_switch",
374 .@"Panic.messages.shift_rhs_too_big",
375 .@"Panic.messages.invalid_enum_value",
376 .@"Panic.messages.for_len_mismatch",
377 .@"Panic.messages.memcpy_len_mismatch",
378 .@"Panic.messages.memcpy_alias",
379 .@"Panic.messages.noreturn_returned",
380 => .string,
381 };
382 }
383
384 /// Resolution of these values is done in three distinct stages:
385 /// * Resolution of `std.builtin.Panic` and everything under it
386 /// * Resolution of `VaList`
387 /// * Everything else
388 ///
389 /// Panics are separated because they are provided by the user, so must be able to use
390 /// things like reification.
391 ///
392 /// `VaList` is separate because its value depends on the target, so it needs some reflection
393 /// machinery to work; additionally, it is `@compileError` on some targets, so must be referenced
394 /// by itself.
395 pub fn stage(decl: BuiltinDecl) InternPool.MemoizedStateStage {
396 if (decl == .VaList) return .va_list;
397
398 if (@intFromEnum(decl) <= @intFromEnum(BuiltinDecl.@"Type.Declaration")) {
399 return .main;
400 } else {
401 return .panic;
402 }
403 }
404
405 /// Based on the tag name, determines how to access this decl; either as a direct child of the
406 /// `std.builtin` namespace, or as a child of some preceding `BuiltinDecl` value.
407 pub fn access(decl: BuiltinDecl) union(enum) {
408 direct: []const u8,
409 nested: struct { BuiltinDecl, []const u8 },
410 } {
411 @setEvalBranchQuota(2000);
412 return switch (decl) {
413 inline else => |tag| {
414 const name = @tagName(tag);
415 const split = (comptime std.mem.lastIndexOfScalar(u8, name, '.')) orelse return .{ .direct = name };
416 const parent = @field(BuiltinDecl, name[0..split]);
417 comptime assert(@intFromEnum(parent) < @intFromEnum(tag)); // dependencies ordered correctly
418 return .{ .nested = .{ parent, name[split + 1 ..] } };
419 },
420 };
421 }
422
423 const Memoized = std.enums.EnumFieldStruct(BuiltinDecl, InternPool.Index, .none);
424};
425
229426pub const PanicId = enum {
230427 reached_unreachable,
231428 unwrap_null,
......@@ -247,8 +444,6 @@ pub const PanicId = enum {
247444 memcpy_len_mismatch,
248445 memcpy_alias,
249446 noreturn_returned,
250
251 pub const len = @typeInfo(PanicId).@"enum".fields.len;
252447};
253448
254449pub const GlobalErrorSet = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void);
......@@ -2454,6 +2649,7 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
24542649 .nav_ty => |nav| try zcu.markPoDependeeUpToDate(.{ .nav_ty = nav }),
24552650 .type => |ty| try zcu.markPoDependeeUpToDate(.{ .interned = ty }),
24562651 .func => |func| try zcu.markPoDependeeUpToDate(.{ .interned = func }),
2652 .memoized_state => |stage| try zcu.markPoDependeeUpToDate(.{ .memoized_state = stage }),
24572653 }
24582654 }
24592655}
......@@ -2468,6 +2664,7 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni
24682664 .nav_ty => |nav| .{ .nav_ty = nav },
24692665 .type => |ty| .{ .interned = ty },
24702666 .func => |func_index| .{ .interned = func_index }, // IES
2667 .memoized_state => |stage| .{ .memoized_state = stage },
24712668 };
24722669 log.debug("potentially outdated dependee: {}", .{zcu.fmtDependee(dependee)});
24732670 var it = ip.dependencyIterator(dependee);
......@@ -2553,6 +2750,12 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
25532750 .type => |ty| .{ .interned = ty },
25542751 .nav_val => |nav| .{ .nav_val = nav },
25552752 .nav_ty => |nav| .{ .nav_ty = nav },
2753 .memoized_state => {
2754 // If we've hit a loop and some `.memoized_state` is outdated, we should make that choice eagerly.
2755 // In general, it's good to resolve this early on, since -- for instance -- almost every function
2756 // references the panic handler.
2757 return unit;
2758 },
25562759 });
25572760 while (it.next()) |_| n += 1;
25582761
......@@ -3462,7 +3665,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
34623665 const other: AnalUnit = .wrap(switch (unit.unwrap()) {
34633666 .nav_val => |n| .{ .nav_ty = n },
34643667 .nav_ty => |n| .{ .nav_val = n },
3465 .@"comptime", .type, .func => break :queue_paired,
3668 .@"comptime", .type, .func, .memoized_state => break :queue_paired,
34663669 });
34673670 if (result.contains(other)) break :queue_paired;
34683671 try unit_queue.put(gpa, other, kv.value); // same reference location
......@@ -3597,6 +3800,7 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co
35973800 const nav = zcu.funcInfo(func).owner_nav;
35983801 return writer.print("func('{}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(func) });
35993802 },
3803 .memoized_state => return writer.writeAll("memoized_state"),
36003804 }
36013805}
36023806fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
......@@ -3642,6 +3846,7 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com
36423846 const file_path = zcu.fileByIndex(info.file).sub_file_path;
36433847 return writer.print("namespace('{s}', %{d}, '{}')", .{ file_path, @intFromEnum(info.inst), k.name.fmt(ip) });
36443848 },
3849 .memoized_state => return writer.writeAll("memoized_state"),
36453850 }
36463851}
36473852
src/Zcu/PerThread.zig+142-18
......@@ -560,6 +560,147 @@ pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.Sem
560560 return pt.semaFile(file_index);
561561}
562562
563/// Ensures that all memoized state on `Zcu` is up-to-date, performing re-analysis if necessary.
564/// Returns `error.AnalysisFail` if an analysis error is encountered; the caller is free to ignore
565/// this, since the error is already registered, but it must not use the value of memoized fields.
566pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) Zcu.SemaError!void {
567 const tracy = trace(@src());
568 defer tracy.end();
569
570 const zcu = pt.zcu;
571 const gpa = zcu.gpa;
572
573 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
574
575 log.debug("ensureMemoizedStateUpToDate", .{});
576
577 assert(!zcu.analysis_in_progress.contains(unit));
578
579 const was_outdated = zcu.outdated.swapRemove(unit) or zcu.potentially_outdated.swapRemove(unit);
580 const prev_failed = zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit);
581
582 if (was_outdated) {
583 dev.check(.incremental);
584 _ = zcu.outdated_ready.swapRemove(unit);
585 // No need for `deleteUnitExports` because we never export anything.
586 zcu.deleteUnitReferences(unit);
587 if (zcu.failed_analysis.fetchSwapRemove(unit)) |kv| {
588 kv.value.destroy(gpa);
589 }
590 _ = zcu.transitive_failed_analysis.swapRemove(unit);
591 } else {
592 if (prev_failed) return error.AnalysisFail;
593 // We use an arbitrary field to check if the state has been resolved yet.
594 const val = switch (stage) {
595 .main => zcu.builtin_decl_values.Type,
596 .panic => zcu.builtin_decl_values.Panic,
597 .va_list => zcu.builtin_decl_values.VaList,
598 };
599 if (val != .none) return;
600 }
601
602 const any_changed: bool, const new_failed: bool = if (pt.analyzeMemoizedState(stage)) |any_changed|
603 .{ any_changed or prev_failed, false }
604 else |err| switch (err) {
605 error.AnalysisFail => res: {
606 if (!zcu.failed_analysis.contains(unit)) {
607 // If this unit caused the error, it would have an entry in `failed_analysis`.
608 // Since it does not, this must be a transitive failure.
609 try zcu.transitive_failed_analysis.put(gpa, unit, {});
610 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(unit)});
611 }
612 break :res .{ !prev_failed, true };
613 },
614 error.OutOfMemory => {
615 // TODO: same as for `ensureComptimeUnitUpToDate` etc
616 return error.OutOfMemory;
617 },
618 error.GenericPoison => unreachable,
619 error.ComptimeReturn => unreachable,
620 error.ComptimeBreak => unreachable,
621 };
622
623 if (was_outdated) {
624 const dependee: InternPool.Dependee = .{ .memoized_state = stage };
625 if (any_changed) {
626 try zcu.markDependeeOutdated(.marked_po, dependee);
627 } else {
628 try zcu.markPoDependeeUpToDate(dependee);
629 }
630 }
631
632 if (new_failed) return error.AnalysisFail;
633}
634
635fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) Zcu.CompileError!bool {
636 const zcu = pt.zcu;
637 const ip = &zcu.intern_pool;
638 const gpa = zcu.gpa;
639
640 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
641
642 try zcu.analysis_in_progress.put(gpa, unit, {});
643 defer assert(zcu.analysis_in_progress.swapRemove(unit));
644
645 // Before we begin, collect:
646 // * The type `std`, and its namespace
647 // * The type `std.builtin`, and its namespace
648 // * A semi-reasonable source location
649 const std_file_imported = pt.importPkg(zcu.std_mod) catch return error.AnalysisFail;
650 try pt.ensureFileAnalyzed(std_file_imported.file_index);
651 const std_type: Type = .fromInterned(zcu.fileRootType(std_file_imported.file_index));
652 const std_namespace = std_type.getNamespaceIndex(zcu);
653 try pt.ensureNamespaceUpToDate(std_namespace);
654 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
655 const builtin_nav = zcu.namespacePtr(std_namespace).pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse
656 @panic("lib/std.zig is corrupt and missing 'builtin'");
657 try pt.ensureNavValUpToDate(builtin_nav);
658 const builtin_type: Type = .fromInterned(ip.getNav(builtin_nav).status.fully_resolved.val);
659 const builtin_namespace = builtin_type.getNamespaceIndex(zcu);
660 try pt.ensureNamespaceUpToDate(builtin_namespace);
661 const src: Zcu.LazySrcLoc = .{
662 .base_node_inst = builtin_type.typeDeclInst(zcu).?,
663 .offset = .entire_file,
664 };
665
666 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
667 defer analysis_arena.deinit();
668
669 var comptime_err_ret_trace: std.ArrayList(Zcu.LazySrcLoc) = .init(gpa);
670 defer comptime_err_ret_trace.deinit();
671
672 var sema: Sema = .{
673 .pt = pt,
674 .gpa = gpa,
675 .arena = analysis_arena.allocator(),
676 .code = .{ .instructions = .empty, .string_bytes = &.{}, .extra = &.{} },
677 .owner = unit,
678 .func_index = .none,
679 .func_is_naked = false,
680 .fn_ret_ty = .void,
681 .fn_ret_ty_ies = null,
682 .comptime_err_ret_trace = &comptime_err_ret_trace,
683 };
684 defer sema.deinit();
685
686 var block: Sema.Block = .{
687 .parent = null,
688 .sema = &sema,
689 .namespace = std_namespace,
690 .instructions = .{},
691 .inlining = null,
692 .comptime_reason = .{ .reason = .{
693 .src = src,
694 .r = .{ .simple = .type },
695 } },
696 .src_base_inst = src.base_node_inst,
697 .type_name_ctx = .empty,
698 };
699 defer block.instructions.deinit(gpa);
700
701 return sema.analyzeMemoizedState(&block, src, builtin_namespace, stage);
702}
703
563704/// Ensures that the state of the given `ComptimeUnit` is fully up-to-date, performing re-analysis
564705/// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is
565706/// free to ignore this, since the error is already registered.
......@@ -2615,7 +2756,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
26152756 // result in circular dependency errors.
26162757 // TODO: this can go away once we fix backends having to resolve `StackTrace`.
26172758 // The codegen timing guarantees that the parameter types will be populated.
2618 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {
2759 sema.resolveFnTypes(fn_ty, inner_block.nodeOffset(0)) catch |err| switch (err) {
26192760 error.GenericPoison => unreachable,
26202761 error.ComptimeReturn => unreachable,
26212762 error.ComptimeBreak => unreachable,
......@@ -3471,23 +3612,6 @@ pub fn structPackedFieldBitOffset(
34713612 unreachable; // index out of bounds
34723613}
34733614
3474pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.Nav.Index {
3475 const zcu = pt.zcu;
3476 const gpa = zcu.gpa;
3477 const ip = &zcu.intern_pool;
3478 const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
3479 const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
3480 const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).unwrap().?);
3481 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
3482 const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse
3483 @panic("lib/std.zig is corrupt and missing 'builtin'");
3484 pt.ensureNavValUpToDate(builtin_nav) catch @panic("std.builtin is corrupt");
3485 const builtin_type = Type.fromInterned(ip.getNav(builtin_nav).status.fully_resolved.val);
3486 const builtin_namespace = zcu.namespacePtr(builtin_type.getNamespace(zcu).unwrap() orelse @panic("std.builtin is corrupt"));
3487 const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
3488 return builtin_namespace.pub_decls.getKeyAdapted(name_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
3489}
3490
34913615pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Error!Type {
34923616 const zcu = pt.zcu;
34933617 const ip = &zcu.intern_pool;
src/codegen/llvm.zig+7-5
......@@ -5754,10 +5754,12 @@ pub const FuncGen = struct {
57545754 const o = fg.ng.object;
57555755 const zcu = o.pt.zcu;
57565756 const ip = &zcu.intern_pool;
5757 const msg_nav_index = zcu.panic_messages[@intFromEnum(panic_id)].unwrap().?;
5758 const msg_nav = ip.getNav(msg_nav_index);
5759 const msg_len = Type.fromInterned(msg_nav.typeOf(ip)).childType(zcu).arrayLen(zcu);
5760 const msg_ptr = try o.lowerValue(msg_nav.status.fully_resolved.val);
5757 const panic_msg_val: InternPool.Index = switch (panic_id) {
5758 inline else => |ct_panic_id| @field(zcu.builtin_decl_values, "Panic.messages." ++ @tagName(ct_panic_id)),
5759 };
5760 assert(panic_msg_val != .none);
5761 const msg_len = Value.fromInterned(panic_msg_val).typeOf(zcu).childType(zcu).arrayLen(zcu);
5762 const msg_ptr = try o.lowerValue(panic_msg_val);
57615763 const null_opt_addr_global = try fg.resolveNullOptUsize();
57625764 const target = zcu.getTarget();
57635765 const llvm_usize = try o.lowerType(Type.usize);
......@@ -5768,7 +5770,7 @@ pub const FuncGen = struct {
57685770 // ptr null, ; stack trace
57695771 // ptr @2, ; addr (null ?usize)
57705772 // )
5771 const panic_func = zcu.funcInfo(zcu.panic_func_index);
5773 const panic_func = zcu.funcInfo(zcu.builtin_decl_values.@"Panic.call");
57725774 const panic_nav = ip.getNav(panic_func.owner_nav);
57735775 const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?;
57745776 const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav);