authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-05 00:28:06+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-01-05 00:28:06+00:00
log136c5a916ed7e421461ac5839cc0e4c289b80f16
tree81c05a0caf49489072c84ba864d5f76b8ec2abaa
parentff4f2753e4eb1226c1b18a812ee6ff5ca914fe85
parent6cc848e9f6c86184030fd4c9bc7c09ce90dd5cf9
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #22403 from mlugg/incremental

incremental: fixes

9 files changed, 839 insertions(+), 319 deletions(-)

lib/std/zig/Zir.zig+32
......@@ -5066,3 +5066,35 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {
50665066 else => unreachable, // assertion failure; not trackable
50675067 }
50685068}
5069
5070pub fn typeCapturesLen(zir: Zir, type_decl: Inst.Index) u32 {
5071 const inst = zir.instructions.get(@intFromEnum(type_decl));
5072 assert(inst.tag == .extended);
5073 switch (inst.data.extended.opcode) {
5074 .struct_decl => {
5075 const small: Inst.StructDecl.Small = @bitCast(inst.data.extended.small);
5076 if (!small.has_captures_len) return 0;
5077 const extra = zir.extraData(Inst.StructDecl, inst.data.extended.operand);
5078 return zir.extra[extra.end];
5079 },
5080 .union_decl => {
5081 const small: Inst.UnionDecl.Small = @bitCast(inst.data.extended.small);
5082 if (!small.has_captures_len) return 0;
5083 const extra = zir.extraData(Inst.UnionDecl, inst.data.extended.operand);
5084 return zir.extra[extra.end + @intFromBool(small.has_tag_type)];
5085 },
5086 .enum_decl => {
5087 const small: Inst.EnumDecl.Small = @bitCast(inst.data.extended.small);
5088 if (!small.has_captures_len) return 0;
5089 const extra = zir.extraData(Inst.EnumDecl, inst.data.extended.operand);
5090 return zir.extra[extra.end + @intFromBool(small.has_tag_type)];
5091 },
5092 .opaque_decl => {
5093 const small: Inst.OpaqueDecl.Small = @bitCast(inst.data.extended.small);
5094 if (!small.has_captures_len) return 0;
5095 const extra = zir.extraData(Inst.OpaqueDecl, inst.data.extended.operand);
5096 return zir.extra[extra.end];
5097 },
5098 else => unreachable,
5099 }
5100}
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+66-9
......@@ -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) {
......@@ -2029,15 +2084,7 @@ pub const Key = union(enum) {
20292084 pub const NamespaceType = union(enum) {
20302085 /// This type corresponds to an actual source declaration, e.g. `struct { ... }`.
20312086 /// It is hashed based on its ZIR instruction index and set of captures.
2032 declared: struct {
2033 /// A `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl` instruction.
2034 zir_index: TrackedInst.Index,
2035 /// The captured values of this type. These values must be fully resolved per the language spec.
2036 captures: union(enum) {
2037 owned: CaptureValue.Slice,
2038 external: []const CaptureValue,
2039 },
2040 },
2087 declared: Declared,
20412088 /// This type is an automatically-generated enum tag type for a union.
20422089 /// It is hashed based on the index of the union type it corresponds to.
20432090 generated_tag: struct {
......@@ -2053,6 +2100,16 @@ pub const Key = union(enum) {
20532100 /// A hash of this type's attributes, fields, etc, generated by Sema.
20542101 type_hash: u64,
20552102 },
2103
2104 pub const Declared = struct {
2105 /// A `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl` instruction.
2106 zir_index: TrackedInst.Index,
2107 /// The captured values of this type. These values must be fully resolved per the language spec.
2108 captures: union(enum) {
2109 owned: CaptureValue.Slice,
2110 external: []const CaptureValue,
2111 },
2112 };
20562113 };
20572114
20582115 pub const FuncType = struct {
src/Sema.zig+210-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 {
......@@ -18172,7 +18174,9 @@ fn zirThis(
1817218174 _ = extended;
1817318175 const pt = sema.pt;
1817418176 const namespace = pt.zcu.namespacePtr(block.namespace);
18177
1817518178 const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
18179
1817618180 switch (pt.zcu.intern_pool.indexToKey(new_ty)) {
1817718181 .struct_type, .union_type, .enum_type => try sema.declareDependency(.{ .interned = new_ty }),
1817818182 .opaque_type => {},
......@@ -18379,7 +18383,7 @@ fn zirBuiltinSrc(
1837918383 } });
1838018384 };
1838118385
18382 const src_loc_ty = try sema.getBuiltinType("SourceLocation");
18386 const src_loc_ty = try sema.getBuiltinType(block.nodeOffset(0), .SourceLocation);
1838318387 const fields = .{
1838418388 // module: [:0]const u8,
1838518389 module_name_val,
......@@ -18406,7 +18410,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1840618410 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1840718411 const src = block.nodeOffset(inst_data.src_node);
1840818412 const ty = try sema.resolveType(block, src, inst_data.operand);
18409 const type_info_ty = try sema.getBuiltinType("Type");
18413 const type_info_ty = try sema.getBuiltinType(src, .Type);
1841018414 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;
1841118415
1841218416 if (ty.typeDeclInst(zcu)) |type_decl_inst| {
......@@ -18426,8 +18430,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1842618430 => |type_info_tag| return unionInitFromEnumTag(sema, block, src, type_info_ty, @intFromEnum(type_info_tag), .void_value),
1842718431
1842818432 .@"fn" => {
18429 const fn_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Fn");
18430 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");
1843118435
1843218436 const func_ty_info = zcu.typeToFunc(ty).?;
1843318437 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
......@@ -18497,7 +18501,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1849718501 func_ty_info.return_type,
1849818502 } });
1849918503
18500 const callconv_ty = try sema.getBuiltinType("CallingConvention");
18504 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
1850118505 const callconv_val = Value.uninterpret(func_ty_info.cc, callconv_ty, pt) catch |err| switch (err) {
1850218506 error.TypeMismatch => @panic("std.builtin is corrupt"),
1850318507 error.OutOfMemory => |e| return e,
......@@ -18525,8 +18529,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1852518529 })));
1852618530 },
1852718531 .int => {
18528 const int_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Int");
18529 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);
1853018534 const info = ty.intInfo(zcu);
1853118535 const field_values = .{
1853218536 // signedness: Signedness,
......@@ -18544,7 +18548,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1854418548 })));
1854518549 },
1854618550 .float => {
18547 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");
1854818552
1854918553 const field_vals = .{
1855018554 // bits: u16,
......@@ -18566,9 +18570,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1856618570 else
1856718571 try Type.fromInterned(info.child).lazyAbiAlignment(pt);
1856818572
18569 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
18570 const pointer_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Pointer");
18571 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");
1857218576
1857318577 const field_values = .{
1857418578 // size: Size,
......@@ -18601,7 +18605,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1860118605 })));
1860218606 },
1860318607 .array => {
18604 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");
1860518609
1860618610 const info = ty.arrayInfo(zcu);
1860718611 const field_values = .{
......@@ -18622,7 +18626,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1862218626 })));
1862318627 },
1862418628 .vector => {
18625 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");
1862618630
1862718631 const info = ty.arrayInfo(zcu);
1862818632 const field_values = .{
......@@ -18641,7 +18645,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1864118645 })));
1864218646 },
1864318647 .optional => {
18644 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");
1864518649
1864618650 const field_values = .{
1864718651 // child: type,
......@@ -18658,7 +18662,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1865818662 },
1865918663 .error_set => {
1866018664 // Get the Error type
18661 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");
1866218666
1866318667 // Build our list of Error values
1866418668 // Optional value is only null if anyerror
......@@ -18754,7 +18758,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1875418758 })));
1875518759 },
1875618760 .error_union => {
18757 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");
1875818762
1875918763 const field_values = .{
1876018764 // error_set: type,
......@@ -18774,7 +18778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1877418778 .@"enum" => {
1877518779 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);
1877618780
18777 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");
1877818782
1877918783 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);
1878018784 for (enum_field_vals, 0..) |*field_val, tag_index| {
......@@ -18859,9 +18863,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1885918863 } });
1886018864 };
1886118865
18862 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());
1886318867
18864 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");
1886518869
1886618870 const field_values = .{
1886718871 // tag_type: type,
......@@ -18883,8 +18887,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1888318887 })));
1888418888 },
1888518889 .@"union" => {
18886 const type_union_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Union");
18887 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");
1888818892
1888918893 try ty.resolveLayout(pt); // Getting alignment requires type layout
1889018894 const union_obj = zcu.typeToUnion(ty).?;
......@@ -18972,14 +18976,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1897218976 } });
1897318977 };
1897418978
18975 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());
1897618980
1897718981 const enum_tag_ty_val = try pt.intern(.{ .opt = .{
1897818982 .ty = (try pt.optionalType(.type_type)).toIntern(),
1897918983 .val = if (ty.unionTagType(zcu)) |tag_ty| tag_ty.toIntern() else .none,
1898018984 } });
1898118985
18982 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");
1898318987
1898418988 const field_values = .{
1898518989 // layout: ContainerLayout,
......@@ -19002,8 +19006,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1900219006 })));
1900319007 },
1900419008 .@"struct" => {
19005 const type_struct_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Struct");
19006 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");
1900719011
1900819012 try ty.resolveLayout(pt); // Getting alignment requires type layout
1900919013
......@@ -19167,7 +19171,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1916719171 } });
1916819172 };
1916919173
19170 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));
1917119175
1917219176 const backing_integer_val = try pt.intern(.{ .opt = .{
1917319177 .ty = (try pt.optionalType(.type_type)).toIntern(),
......@@ -19177,7 +19181,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1917719181 } else .none,
1917819182 } });
1917919183
19180 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");
1918119185
1918219186 const layout = ty.containerLayout(zcu);
1918319187
......@@ -19203,10 +19207,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1920319207 })));
1920419208 },
1920519209 .@"opaque" => {
19206 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");
1920719211
1920819212 try ty.resolveFields(pt);
19209 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));
1921019214
1921119215 const field_values = .{
1921219216 // decls: []const Declaration,
......@@ -19230,14 +19234,13 @@ fn typeInfoDecls(
1923019234 sema: *Sema,
1923119235 block: *Block,
1923219236 src: LazySrcLoc,
19233 type_info_ty: Type,
1923419237 opt_namespace: InternPool.OptionalNamespaceIndex,
1923519238) CompileError!InternPool.Index {
1923619239 const pt = sema.pt;
1923719240 const zcu = pt.zcu;
1923819241 const gpa = sema.gpa;
1923919242
19240 const declaration_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Declaration");
19243 const declaration_ty = try sema.getBuiltinType(src, .@"Type.Declaration");
1924119244
1924219245 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
1924319246 defer decl_vals.deinit();
......@@ -20179,11 +20182,11 @@ fn retWithErrTracing(
2017920182 else => true,
2018020183 };
2018120184 const gpa = sema.gpa;
20182 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
20185 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
2018320186 try stack_trace_ty.resolveFields(pt);
2018420187 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
2018520188 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
20186 const return_err_fn = try sema.getBuiltin("returnError");
20189 const return_err_fn = Air.internedToRef(try sema.getBuiltin(src, .returnError));
2018720190 const args: [1]Air.Inst.Ref = .{err_return_trace};
2018820191
2018920192 if (!need_check) {
......@@ -21605,7 +21608,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
2160521608 const pt = sema.pt;
2160621609 const zcu = pt.zcu;
2160721610 const ip = &zcu.intern_pool;
21608 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
21611 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace);
2160921612 try stack_trace_ty.resolveFields(pt);
2161021613 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
2161121614 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
......@@ -21614,7 +21617,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
2161421617 .func => |func| if (ip.funcAnalysisUnordered(func).calls_or_awaits_errorable_fn and block.ownerModule().error_tracing) {
2161521618 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
2161621619 },
21617 .@"comptime", .nav_ty, .nav_val, .type => {},
21620 .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {},
2161821621 }
2161921622 return Air.internedToRef(try pt.intern(.{ .opt = .{
2162021623 .ty = opt_ptr_stack_trace_ty.toIntern(),
......@@ -21894,7 +21897,7 @@ fn zirReify(
2189421897 },
2189521898 },
2189621899 };
21897 const type_info_ty = try sema.getBuiltinType("Type");
21900 const type_info_ty = try sema.getBuiltinType(src, .Type);
2189821901 const uncasted_operand = try sema.resolveInst(extra.operand);
2189921902 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
2190021903 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{ .simple = .operand_Type });
......@@ -23154,7 +23157,7 @@ fn reifyStruct(
2315423157
2315523158fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
2315623159 const pt = sema.pt;
23157 const va_list_ty = try sema.getBuiltinType("VaList");
23160 const va_list_ty = try sema.getBuiltinType(src, .VaList);
2315823161 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);
2315923162
2316023163 const inst = try sema.resolveInst(zir_ref);
......@@ -23193,7 +23196,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
2319323196 const va_list_src = block.builtinCallArgSrc(extra.node, 0);
2319423197
2319523198 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);
23196 const va_list_ty = try sema.getBuiltinType("VaList");
23199 const va_list_ty = try sema.getBuiltinType(src, .VaList);
2319723200
2319823201 try sema.requireRuntimeBlock(block, src, null);
2319923202 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);
......@@ -23213,7 +23216,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2321323216fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
2321423217 const src = block.nodeOffset(@bitCast(extended.operand));
2321523218
23216 const va_list_ty = try sema.getBuiltinType("VaList");
23219 const va_list_ty = try sema.getBuiltinType(src, .VaList);
2321723220 try sema.requireRuntimeBlock(block, src, null);
2321823221 return block.addInst(.{
2321923222 .tag = .c_va_start,
......@@ -24819,7 +24822,7 @@ fn resolveExportOptions(
2481924822 const zcu = pt.zcu;
2482024823 const gpa = sema.gpa;
2482124824 const ip = &zcu.intern_pool;
24822 const export_options_ty = try sema.getBuiltinType("ExportOptions");
24825 const export_options_ty = try sema.getBuiltinType(src, .ExportOptions);
2482324826 const air_ref = try sema.resolveInst(zir_ref);
2482424827 const options = try sema.coerce(block, export_options_ty, air_ref, src);
2482524828
......@@ -24869,15 +24872,15 @@ fn resolveBuiltinEnum(
2486924872 block: *Block,
2487024873 src: LazySrcLoc,
2487124874 zir_ref: Zir.Inst.Ref,
24872 comptime name: []const u8,
24875 comptime name: Zcu.BuiltinDecl,
2487324876 reason: ComptimeReason,
24874) CompileError!@field(std.builtin, name) {
24877) CompileError!@field(std.builtin, @tagName(name)) {
2487524878 const pt = sema.pt;
24876 const ty = try sema.getBuiltinType(name);
24879 const ty = try sema.getBuiltinType(src, name);
2487724880 const air_ref = try sema.resolveInst(zir_ref);
2487824881 const coerced = try sema.coerce(block, ty, air_ref, src);
2487924882 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
24880 return pt.zcu.toEnum(@field(std.builtin, name), val);
24883 return pt.zcu.toEnum(@field(std.builtin, @tagName(name)), val);
2488124884}
2488224885
2488324886fn resolveAtomicOrder(
......@@ -24887,7 +24890,7 @@ fn resolveAtomicOrder(
2488724890 zir_ref: Zir.Inst.Ref,
2488824891 reason: ComptimeReason,
2488924892) CompileError!std.builtin.AtomicOrder {
24890 return sema.resolveBuiltinEnum(block, src, zir_ref, "AtomicOrder", reason);
24893 return sema.resolveBuiltinEnum(block, src, zir_ref, .AtomicOrder, reason);
2489124894}
2489224895
2489324896fn resolveAtomicRmwOp(
......@@ -24896,7 +24899,7 @@ fn resolveAtomicRmwOp(
2489624899 src: LazySrcLoc,
2489724900 zir_ref: Zir.Inst.Ref,
2489824901) CompileError!std.builtin.AtomicRmwOp {
24899 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 });
2490024903}
2490124904
2490224905fn zirCmpxchg(
......@@ -25076,7 +25079,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2507625079 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2507725080 const op_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2507825081 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 1);
25079 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 });
2508025083 const operand = try sema.resolveInst(extra.rhs);
2508125084 const operand_ty = sema.typeOf(operand);
2508225085 const pt = sema.pt;
......@@ -25666,7 +25669,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2566625669 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
2566725670 const func = try sema.resolveInst(extra.callee);
2566825671
25669 const modifier_ty = try sema.getBuiltinType("CallModifier");
25672 const modifier_ty = try sema.getBuiltinType(call_src, .CallModifier);
2567025673 const air_ref = try sema.resolveInst(extra.modifier);
2567125674 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);
2567225675 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{ .simple = .call_modifier });
......@@ -26628,13 +26631,13 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2662826631 const body = sema.code.bodySlice(extra_index, body_len);
2662926632 extra_index += body.len;
2663026633
26631 const cc_ty = try sema.getBuiltinType("CallingConvention");
26634 const cc_ty = try sema.getBuiltinType(cc_src, .CallingConvention);
2663226635 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{ .simple = .@"callconv" });
2663326636 break :blk try sema.analyzeValueAsCallconv(block, cc_src, val);
2663426637 } else if (extra.data.bits.has_cc_ref) blk: {
2663526638 const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
2663626639 extra_index += 1;
26637 const cc_ty = try sema.getBuiltinType("CallingConvention");
26640 const cc_ty = try sema.getBuiltinType(cc_src, .CallingConvention);
2663826641 const uncoerced_cc = try sema.resolveInst(cc_ref);
2663926642 const coerced_cc = try sema.coerce(block, cc_ty, uncoerced_cc, cc_src);
2664026643 const cc_val = try sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{ .simple = .@"callconv" });
......@@ -26654,7 +26657,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2665426657 // error by trying to evaluate `std.builtin.CallingConvention.c`, so for consistency,
2665526658 // let's eval that now and just get the transitive error. (It's guaranteed to error
2665626659 // because it does the exact `cCallingConvention` call we just did.)
26657 const cc_type = try sema.getBuiltinType("CallingConvention");
26660 const cc_type = try sema.getBuiltinType(cc_src, .CallingConvention);
2665826661 _ = try sema.namespaceLookupVal(
2665926662 block,
2666026663 LazySrcLoc.unneeded,
......@@ -26832,7 +26835,7 @@ fn resolvePrefetchOptions(
2683226835 const zcu = pt.zcu;
2683326836 const gpa = sema.gpa;
2683426837 const ip = &zcu.intern_pool;
26835 const options_ty = try sema.getBuiltinType("PrefetchOptions");
26838 const options_ty = try sema.getBuiltinType(src, .PrefetchOptions);
2683626839 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
2683726840
2683826841 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });
......@@ -26900,7 +26903,7 @@ fn resolveExternOptions(
2690026903 const gpa = sema.gpa;
2690126904 const ip = &zcu.intern_pool;
2690226905 const options_inst = try sema.resolveInst(zir_ref);
26903 const extern_options_ty = try sema.getBuiltinType("ExternOptions");
26906 const extern_options_ty = try sema.getBuiltinType(src, .ExternOptions);
2690426907 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
2690526908
2690626909 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
......@@ -27002,6 +27005,7 @@ fn zirBuiltinExtern(
2700227005 .zir_index = switch (sema.owner.unwrap()) {
2700327006 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index,
2700427007 .type => |owner_ty| Type.fromInterned(owner_ty).typeDeclInst(zcu).?,
27008 .memoized_state => unreachable,
2700527009 .nav_ty, .nav_val => |nav| ip.getNav(nav).analysis.?.zir_index,
2700627010 .func => |func| zir_index: {
2700727011 const func_info = zcu.funcInfo(func);
......@@ -27079,23 +27083,25 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2707927083 const src = block.nodeOffset(@bitCast(extended.operand));
2708027084 const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small);
2708127085
27082 const type_name = switch (value) {
27083 .atomic_order => "AtomicOrder",
27084 .atomic_rmw_op => "AtomicRmwOp",
27085 .calling_convention => "CallingConvention",
27086 .address_space => "AddressSpace",
27087 .float_mode => "FloatMode",
27088 .reduce_op => "ReduceOp",
27089 .call_modifier => "CallModifier",
27090 .prefetch_options => "PrefetchOptions",
27091 .export_options => "ExportOptions",
27092 .extern_options => "ExternOptions",
27093 .type_info => "Type",
27094 .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
2709527101
2709627102 // Values are handled here.
2709727103 .calling_convention_c => {
27098 const callconv_ty = try sema.getBuiltinType("CallingConvention");
27104 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
2709927105 return try sema.namespaceLookupVal(
2710027106 block,
2710127107 src,
......@@ -27105,7 +27111,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2710527111 },
2710627112 .calling_convention_inline => {
2710727113 comptime assert(@typeInfo(std.builtin.CallingConvention.Tag).@"enum".tag_type == u8);
27108 const callconv_ty = try sema.getBuiltinType("CallingConvention");
27114 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
2710927115 const callconv_tag_ty = callconv_ty.unionTagType(zcu) orelse @panic("std.builtin is corrupt");
2711027116 const inline_tag_val = try pt.enumValue(
2711127117 callconv_tag_ty,
......@@ -27117,7 +27123,6 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2711727123 return sema.coerce(block, callconv_ty, Air.internedToRef(inline_tag_val.toIntern()), src);
2711827124 },
2711927125 };
27120 const ty = try sema.getBuiltinType(type_name);
2712127126 return Air.internedToRef(ty.toIntern());
2712227127}
2712327128
......@@ -27156,7 +27161,7 @@ fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
2715627161 const uncoerced_hint = try sema.resolveInst(extra.operand);
2715727162 const operand_src = block.builtinCallArgSrc(extra.node, 0);
2715827163
27159 const hint_ty = try sema.getBuiltinType("BranchHint");
27164 const hint_ty = try sema.getBuiltinType(operand_src, .BranchHint);
2716027165 const coerced_hint = try sema.coerce(block, hint_ty, uncoerced_hint, operand_src);
2716127166 const hint_val = try sema.resolveConstDefinedValue(block, operand_src, coerced_hint, .{ .simple = .operand_branchHint });
2716227167
......@@ -27601,61 +27606,19 @@ fn explainWhyTypeIsNotPacked(
2760127606 }
2760227607}
2760327608
27604fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
27605 const pt = sema.pt;
27606 const zcu = pt.zcu;
27607
27608 if (zcu.panic_func_index == .none) {
27609 zcu.panic_func_index = try sema.getPanicInnerFn(block, src, "call");
27610 // Here, function body analysis must be queued up so that backends can
27611 // make calls to this function.
27612 try zcu.ensureFuncBodyAnalysisQueued(zcu.panic_func_index);
27613 }
27614
27615 if (zcu.null_stack_trace == .none) {
27616 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
27617 try stack_trace_ty.resolveFields(pt);
27618 const target = zcu.getTarget();
27619 const ptr_stack_trace_ty = try pt.ptrTypeSema(.{
27620 .child = stack_trace_ty.toIntern(),
27621 .flags = .{
27622 .address_space = target_util.defaultAddressSpace(target, .global_constant),
27623 },
27624 });
27625 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
27626 zcu.null_stack_trace = try pt.intern(.{ .opt = .{
27627 .ty = opt_ptr_stack_trace_ty.toIntern(),
27628 .val = .none,
27629 } });
27630 }
27631}
27632
2763327609/// Backends depend on panic decls being available when lowering safety-checked
2763427610/// instructions. This function ensures the panic function will be available to
2763527611/// be called during that time.
27636fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Zcu.PanicId) !InternPool.Nav.Index {
27637 const pt = sema.pt;
27638 const zcu = pt.zcu;
27639 const gpa = sema.gpa;
27640 if (zcu.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;
27641
27642 try sema.prepareSimplePanic(block, src);
27643
27644 const panic_ty = try sema.getBuiltinType("Panic");
27645 const panic_messages_ty = try sema.getBuiltinInnerType(block, src, panic_ty, "Panic", "messages");
27646 const msg_nav_index = (sema.namespaceLookup(
27647 block,
27648 LazySrcLoc.unneeded,
27649 panic_messages_ty.getNamespaceIndex(zcu),
27650 try zcu.intern_pool.getOrPutString(gpa, pt.tid, @tagName(panic_id), .no_embedded_nulls),
27651 ) catch |err| switch (err) {
27652 error.AnalysisFail => return error.AnalysisFail,
27653 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
27654 error.OutOfMemory => |e| return e,
27655 }).?;
27656 try sema.ensureNavResolved(src, msg_nav_index, .fully);
27657 zcu.panic_messages[@intFromEnum(panic_id)] = msg_nav_index.toOptional();
27658 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 }
2765927622}
2766027623
2766127624fn addSafetyCheck(
......@@ -27759,10 +27722,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
2775927722 return;
2776027723 }
2776127724
27762 try sema.prepareSimplePanic(block, src);
27725 try sema.ensureMemoizedStateResolved(src, .panic);
27726 try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.@"Panic.call");
2776327727
27764 const panic_func = zcu.funcInfo(zcu.panic_func_index);
27765 const panic_fn = try sema.analyzeNavVal(block, src, panic_func.owner_nav);
27728 const panic_fn = Air.internedToRef(zcu.builtin_decl_values.@"Panic.call");
2776627729 const null_stack_trace = Air.internedToRef(zcu.null_stack_trace);
2776727730
2776827731 const opt_usize_ty = try pt.optionalType(.usize_type);
......@@ -27810,7 +27773,7 @@ fn safetyPanicUnwrapError(sema: *Sema, block: *Block, src: LazySrcLoc, err: Air.
2781027773 if (!zcu.backendSupportsFeature(.panic_fn)) {
2781127774 _ = try block.addNoOp(.trap);
2781227775 } else {
27813 const panic_fn = try getPanicInnerFn(sema, block, src, "unwrapError");
27776 const panic_fn = try getBuiltin(sema, src, .@"Panic.unwrapError");
2781427777 const err_return_trace = try sema.getErrorReturnTrace(block);
2781527778 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
2781627779 try sema.callBuiltin(block, src, Air.internedToRef(panic_fn), .auto, &args, .@"safety check");
......@@ -27827,7 +27790,7 @@ fn addSafetyCheckIndexOob(
2782727790) !void {
2782827791 assert(!parent_block.isComptime());
2782927792 const ok = try parent_block.addBinOp(cmp_op, index, len);
27830 return addSafetyCheckCall(sema, parent_block, src, ok, "outOfBounds", &.{ index, len });
27793 return addSafetyCheckCall(sema, parent_block, src, ok, .@"Panic.outOfBounds", &.{ index, len });
2783127794}
2783227795
2783327796fn addSafetyCheckInactiveUnionField(
......@@ -27839,7 +27802,7 @@ fn addSafetyCheckInactiveUnionField(
2783927802) !void {
2784027803 assert(!parent_block.isComptime());
2784127804 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);
27842 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 });
2784327806}
2784427807
2784527808fn addSafetyCheckSentinelMismatch(
......@@ -27880,7 +27843,7 @@ fn addSafetyCheckSentinelMismatch(
2788027843 break :ok try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel);
2788127844 };
2788227845
27883 return addSafetyCheckCall(sema, parent_block, src, ok, "sentinelMismatch", &.{
27846 return addSafetyCheckCall(sema, parent_block, src, ok, .@"Panic.sentinelMismatch", &.{
2788427847 expected_sentinel, actual_sentinel,
2788527848 });
2788627849}
......@@ -27890,7 +27853,7 @@ fn addSafetyCheckCall(
2789027853 parent_block: *Block,
2789127854 src: LazySrcLoc,
2789227855 ok: Air.Inst.Ref,
27893 func_name: []const u8,
27856 comptime func_decl: Zcu.BuiltinDecl,
2789427857 args: []const Air.Inst.Ref,
2789527858) !void {
2789627859 assert(!parent_block.isComptime());
......@@ -27914,7 +27877,7 @@ fn addSafetyCheckCall(
2791427877 if (!zcu.backendSupportsFeature(.panic_fn)) {
2791527878 _ = try fail_block.addNoOp(.trap);
2791627879 } else {
27917 const panic_fn = try getPanicInnerFn(sema, &fail_block, src, func_name);
27880 const panic_fn = try getBuiltin(sema, src, func_decl);
2791827881 try sema.callBuiltin(&fail_block, src, Air.internedToRef(panic_fn), .auto, args, .@"safety check");
2791927882 }
2792027883
......@@ -27923,9 +27886,8 @@ fn addSafetyCheckCall(
2792327886
2792427887/// This does not set `sema.branch_hint`.
2792527888fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Zcu.PanicId) CompileError!void {
27926 const msg_nav_index = try sema.preparePanicId(block, src, panic_id);
27927 const msg_inst = try sema.analyzeNavVal(block, src, msg_nav_index);
27928 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");
2792927891}
2793027892
2793127893fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
......@@ -32522,6 +32484,19 @@ fn addTypeReferenceEntry(
3252232484 try zcu.addTypeReference(sema.owner, referenced_type, src);
3252332485}
3252432486
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
3252532500pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void {
3252632501 const pt = sema.pt;
3252732502 const zcu = pt.zcu;
......@@ -33371,7 +33346,7 @@ fn analyzeSlice(
3337133346 assert(!block.isComptime());
3337233347 try sema.requireRuntimeBlock(block, src, runtime_src.?);
3337333348 const ok = try block.addBinOp(.cmp_lte, start, end);
33374 try sema.addSafetyCheckCall(block, src, ok, "startGreaterThanEnd", &.{ start, end });
33349 try sema.addSafetyCheckCall(block, src, ok, .@"Panic.startGreaterThanEnd", &.{ start, end });
3337533350 }
3337633351 const new_len = if (by_length)
3337733352 try sema.coerce(block, Type.usize, uncasted_end_opt, end_src)
......@@ -35491,7 +35466,7 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void
3549135466 }
3549235467}
3549335468
35494pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
35469pub fn resolveFnTypes(sema: *Sema, fn_ty: Type, src: LazySrcLoc) CompileError!void {
3549535470 const pt = sema.pt;
3549635471 const zcu = pt.zcu;
3549735472 const ip = &zcu.intern_pool;
......@@ -35503,7 +35478,7 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
3550335478 Type.fromInterned(fn_ty_info.return_type).isError(zcu))
3550435479 {
3550535480 // Ensure the type exists so that backends can assume that.
35506 _ = try sema.getBuiltinType("StackTrace");
35481 _ = try sema.getBuiltinType(src, .StackTrace);
3550735482 }
3550835483
3550935484 for (0..fn_ty_info.param_types.len) |i| {
......@@ -37548,7 +37523,7 @@ pub fn analyzeAsAddressSpace(
3754837523) !std.builtin.AddressSpace {
3754937524 const pt = sema.pt;
3755037525 const zcu = pt.zcu;
37551 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
37526 const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
3755237527 const coerced = try sema.coerce(block, addrspace_ty, air_ref, src);
3755337528 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ .simple = .@"addrspace" });
3755437529 const address_space = zcu.toEnum(std.builtin.AddressSpace, addrspace_val);
......@@ -38745,69 +38720,15 @@ const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadR
3874538720const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;
3874638721const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult;
3874738722
38748fn getPanicInnerFn(
38749 sema: *Sema,
38750 block: *Block,
38751 src: LazySrcLoc,
38752 inner_name: []const u8,
38753) !InternPool.Index {
38754 const gpa = sema.gpa;
38755 const pt = sema.pt;
38756 const zcu = pt.zcu;
38757 const ip = &zcu.intern_pool;
38758 const outer_ty = try sema.getBuiltinType("Panic");
38759 const inner_name_ip = try ip.getOrPutString(gpa, pt.tid, inner_name, .no_embedded_nulls);
38760 const opt_fn_ref = try namespaceLookupVal(sema, block, src, outer_ty.getNamespaceIndex(zcu), inner_name_ip);
38761 const fn_ref = opt_fn_ref orelse return sema.fail(block, src, "std.builtin.Panic missing {s}", .{inner_name});
38762 const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{ .simple = .panic_handler });
38763 if (fn_val.typeOf(zcu).zigTypeTag(zcu) != .@"fn") {
38764 return sema.fail(block, src, "std.builtin.Panic.{s} is not a function", .{inner_name});
38765 }
38766 // Better not to queue up function body analysis because the function might be generic, and
38767 // the semantic analysis for the call will already queue if necessary.
38768 return fn_val.toIntern();
38769}
38770
38771fn getBuiltinType(sema: *Sema, name: []const u8) SemaError!Type {
38772 const pt = sema.pt;
38773 const ty_inst = try sema.getBuiltin(name);
38774 const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt"));
38775 try ty.resolveFully(pt);
38776 return ty;
38777}
38778
38779fn getBuiltinInnerType(
38780 sema: *Sema,
38781 block: *Block,
38782 src: LazySrcLoc,
38783 outer_ty: Type,
38784 /// Relative to "std.builtin".
38785 compile_error_parent_name: []const u8,
38786 inner_name: []const u8,
38787) !Type {
38788 const pt = sema.pt;
38789 const zcu = pt.zcu;
38790 const ip = &zcu.intern_pool;
38791 const gpa = sema.gpa;
38792 const inner_name_ip = try ip.getOrPutString(gpa, pt.tid, inner_name, .no_embedded_nulls);
38793 const opt_nav = try sema.namespaceLookup(block, src, outer_ty.getNamespaceIndex(zcu), inner_name_ip);
38794 const nav = opt_nav orelse return sema.fail(block, src, "std.builtin.{s} missing {s}", .{
38795 compile_error_parent_name, inner_name,
38796 });
38797 try sema.ensureNavResolved(src, nav, .fully);
38798 const val = Value.fromInterned(ip.getNav(nav).status.fully_resolved.val);
38799 const ty = val.toType();
38800 try ty.resolveFully(pt);
38801 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)));
3880238727}
38803
38804fn getBuiltin(sema: *Sema, name: []const u8) SemaError!Air.Inst.Ref {
38805 const pt = sema.pt;
38806 const zcu = pt.zcu;
38807 const ip = &zcu.intern_pool;
38808 const nav = try pt.getBuiltinNav(name);
38809 try pt.ensureNavValUpToDate(nav);
38810 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));
3881138732}
3881238733
3881338734pub const NavPtrModifiers = struct {
......@@ -38875,3 +38796,77 @@ pub fn resolveNavPtrModifiers(
3887538796 .@"addrspace" = @"addrspace",
3887638797 };
3887738798}
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+219-19
......@@ -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
......@@ -2563,19 +2766,6 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
25632766 }
25642767 }
25652768
2566 if (chosen_unit == null) {
2567 for (zcu.outdated.keys(), zcu.outdated.values()) |o, opod| {
2568 const func = o.unwrap().func;
2569 const nav = zcu.funcInfo(func).owner_nav;
2570 std.io.getStdErr().writer().print("outdated: func {}, nav {}, name '{}', [p]o deps {}\n", .{ func, nav, ip.getNav(nav).fqn.fmt(ip), opod }) catch {};
2571 }
2572 for (zcu.potentially_outdated.keys(), zcu.potentially_outdated.values()) |o, opod| {
2573 const func = o.unwrap().func;
2574 const nav = zcu.funcInfo(func).owner_nav;
2575 std.io.getStdErr().writer().print("po: func {}, nav {}, name '{}', [p]o deps {}\n", .{ func, nav, ip.getNav(nav).fqn.fmt(ip), opod }) catch {};
2576 }
2577 }
2578
25792769 log.debug("findOutdatedToAnalyze: heuristic returned '{}' ({d} dependers)", .{
25802770 zcu.fmtAnalUnit(chosen_unit.?),
25812771 chosen_unit_dependers,
......@@ -2661,6 +2851,14 @@ pub fn mapOldZirToNew(
26612851 }
26622852
26632853 while (match_stack.popOrNull()) |match_item| {
2854 // First, a check: if the number of captures of this type has changed, we can't map it, because
2855 // we wouldn't know how to correlate type information with the last update.
2856 // Synchronizes with logic in `Zcu.PerThread.recreateStructType` etc.
2857 if (old_zir.typeCapturesLen(match_item.old_inst) != new_zir.typeCapturesLen(match_item.new_inst)) {
2858 // Don't map this type or anything within it.
2859 continue;
2860 }
2861
26642862 // Match the namespace declaration itself
26652863 try inst_map.put(gpa, match_item.old_inst, match_item.new_inst);
26662864
......@@ -3467,7 +3665,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
34673665 const other: AnalUnit = .wrap(switch (unit.unwrap()) {
34683666 .nav_val => |n| .{ .nav_ty = n },
34693667 .nav_ty => |n| .{ .nav_val = n },
3470 .@"comptime", .type, .func => break :queue_paired,
3668 .@"comptime", .type, .func, .memoized_state => break :queue_paired,
34713669 });
34723670 if (result.contains(other)) break :queue_paired;
34733671 try unit_queue.put(gpa, other, kv.value); // same reference location
......@@ -3602,6 +3800,7 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co
36023800 const nav = zcu.funcInfo(func).owner_nav;
36033801 return writer.print("func('{}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(func) });
36043802 },
3803 .memoized_state => return writer.writeAll("memoized_state"),
36053804 }
36063805}
36073806fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
......@@ -3647,6 +3846,7 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com
36473846 const file_path = zcu.fileByIndex(info.file).sub_file_path;
36483847 return writer.print("namespace('{s}', %{d}, '{}')", .{ file_path, @intFromEnum(info.inst), k.name.fmt(ip) });
36493848 },
3849 .memoized_state => return writer.writeAll("memoized_state"),
36503850 }
36513851}
36523852
src/Zcu/PerThread.zig+197-61
......@@ -545,10 +545,160 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
545545pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
546546 const file_root_type = pt.zcu.fileRootType(file_index);
547547 if (file_root_type != .none) {
548 _ = try pt.ensureTypeUpToDate(file_root_type);
548 if (pt.ensureTypeUpToDate(file_root_type)) |_| {
549 return;
550 } else |err| switch (err) {
551 error.AnalysisFail => {
552 // The file's root `struct_decl` has, at some point, been lost, because the file failed AstGen.
553 // Clear `file_root_type`, and try the `semaFile` call below, in case the instruction has since
554 // been discovered under a new `TrackedInst.Index`.
555 pt.zcu.setFileRootType(file_index, .none);
556 },
557 else => |e| return e,
558 }
559 }
560 return pt.semaFile(file_index);
561}
562
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);
549591 } else {
550 return pt.semaFile(file_index);
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 }
551630 }
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);
552702}
553703
554704/// Ensures that the state of the given `ComptimeUnit` is fully up-to-date, performing re-analysis
......@@ -909,7 +1059,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
9091059 // Of course, we need to make sure we depend on it properly.
9101060 try sema.declareDependency(.{ .nav_ty = nav_id });
9111061 try pt.ensureNavTypeUpToDate(nav_id);
912 break :ty .fromInterned(ip.getNav(nav_id).status.type_resolved.type);
1062 break :ty .fromInterned(ip.getNav(nav_id).typeOf(ip));
9131063 } else null;
9141064
9151065 const final_val: ?Value = if (zir_decl.value_body) |value_body| val: {
......@@ -2606,7 +2756,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
26062756 // result in circular dependency errors.
26072757 // TODO: this can go away once we fix backends having to resolve `StackTrace`.
26082758 // The codegen timing guarantees that the parameter types will be populated.
2609 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {
2759 sema.resolveFnTypes(fn_ty, inner_block.nodeOffset(0)) catch |err| switch (err) {
26102760 error.GenericPoison => unreachable,
26112761 error.ComptimeReturn => unreachable,
26122762 error.ComptimeBreak => unreachable,
......@@ -3462,23 +3612,6 @@ pub fn structPackedFieldBitOffset(
34623612 unreachable; // index out of bounds
34633613}
34643614
3465pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.Nav.Index {
3466 const zcu = pt.zcu;
3467 const gpa = zcu.gpa;
3468 const ip = &zcu.intern_pool;
3469 const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
3470 const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
3471 const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).unwrap().?);
3472 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
3473 const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse
3474 @panic("lib/std.zig is corrupt and missing 'builtin'");
3475 pt.ensureNavValUpToDate(builtin_nav) catch @panic("std.builtin is corrupt");
3476 const builtin_type = Type.fromInterned(ip.getNav(builtin_nav).status.fully_resolved.val);
3477 const builtin_namespace = zcu.namespacePtr(builtin_type.getNamespace(zcu).unwrap() orelse @panic("std.builtin is corrupt"));
3478 const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
3479 return builtin_namespace.pub_decls.getKeyAdapted(name_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
3480}
3481
34823615pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Error!Type {
34833616 const zcu = pt.zcu;
34843617 const ip = &zcu.intern_pool;
......@@ -3524,9 +3657,11 @@ pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPo
35243657 return ty.abiAlignment(zcu);
35253658}
35263659
3527/// Given a container type requiring resolution, ensures that it is up-to-date.
3528/// If not, the type is recreated at a new `InternPool.Index`.
3529/// The new index is returned. This is the same as the old index if the fields were up-to-date.
3660/// `ty` is a container type requiring resolution (struct, union, or enum).
3661/// If `ty` is outdated, it is recreated at a new `InternPool.Index`, which is returned.
3662/// If the type cannot be recreated because it has been lost, `error.AnalysisFail` is returned.
3663/// If `ty` is not outdated, that same `InternPool.Index` is returned.
3664/// If `ty` has already been replaced by this function, the new index will not be returned again.
35303665pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError!InternPool.Index {
35313666 const zcu = pt.zcu;
35323667 const gpa = zcu.gpa;
......@@ -3536,13 +3671,30 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError
35363671 const outdated = zcu.outdated.swapRemove(anal_unit) or
35373672 zcu.potentially_outdated.swapRemove(anal_unit);
35383673
3674 if (outdated) {
3675 _ = zcu.outdated_ready.swapRemove(anal_unit);
3676 try zcu.markDependeeOutdated(.marked_po, .{ .interned = ty });
3677 }
3678
3679 const ty_key = switch (ip.indexToKey(ty)) {
3680 .struct_type, .union_type, .enum_type => |key| key,
3681 else => unreachable,
3682 };
3683 const declared_ty_key = switch (ty_key) {
3684 .reified => unreachable, // never outdated
3685 .generated_tag => unreachable, // never outdated
3686 .declared => |d| d,
3687 };
3688
3689 if (declared_ty_key.zir_index.resolve(ip) == null) {
3690 // The instruction has been lost -- this type is dead.
3691 return error.AnalysisFail;
3692 }
3693
35393694 if (!outdated) return ty;
35403695
35413696 // We will recreate the type at a new `InternPool.Index`.
35423697
3543 _ = zcu.outdated_ready.swapRemove(anal_unit);
3544 try zcu.markDependeeOutdated(.marked_po, .{ .interned = ty });
3545
35463698 // Delete old state which is no longer in use. Technically, this is not necessary: these exports,
35473699 // references, etc, will be ignored because the type itself is unreferenced. However, it allows
35483700 // reusing the memory which is currently being used to track this state.
......@@ -3555,9 +3707,9 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError
35553707 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
35563708
35573709 switch (ip.indexToKey(ty)) {
3558 .struct_type => |key| return pt.recreateStructType(ty, key),
3559 .union_type => |key| return pt.recreateUnionType(ty, key),
3560 .enum_type => |key| return pt.recreateEnumType(ty, key),
3710 .struct_type => return pt.recreateStructType(ty, declared_ty_key),
3711 .union_type => return pt.recreateUnionType(ty, declared_ty_key),
3712 .enum_type => return pt.recreateEnumType(ty, declared_ty_key),
35613713 else => unreachable,
35623714 }
35633715}
......@@ -3565,21 +3717,15 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError
35653717fn recreateStructType(
35663718 pt: Zcu.PerThread,
35673719 old_ty: InternPool.Index,
3568 full_key: InternPool.Key.NamespaceType,
3569) Zcu.SemaError!InternPool.Index {
3720 key: InternPool.Key.NamespaceType.Declared,
3721) Allocator.Error!InternPool.Index {
35703722 const zcu = pt.zcu;
35713723 const gpa = zcu.gpa;
35723724 const ip = &zcu.intern_pool;
35733725
3574 const key = switch (full_key) {
3575 .reified => unreachable, // never outdated
3576 .generated_tag => unreachable, // not a struct
3577 .declared => |d| d,
3578 };
3579
3580 const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
3726 const inst_info = key.zir_index.resolveFull(ip).?;
35813727 const file = zcu.fileByIndex(inst_info.file);
3582 if (file.status != .success_zir) return error.AnalysisFail;
3728 assert(file.status == .success_zir); // otherwise inst tracking failed
35833729 const zir = file.zir;
35843730
35853731 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
......@@ -3600,7 +3746,7 @@ fn recreateStructType(
36003746 break :blk fields_len;
36013747 } else 0;
36023748
3603 if (captures_len != key.captures.owned.len) return error.AnalysisFail;
3749 assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew`
36043750
36053751 const struct_obj = ip.loadStructType(old_ty);
36063752
......@@ -3644,21 +3790,15 @@ fn recreateStructType(
36443790fn recreateUnionType(
36453791 pt: Zcu.PerThread,
36463792 old_ty: InternPool.Index,
3647 full_key: InternPool.Key.NamespaceType,
3648) Zcu.SemaError!InternPool.Index {
3793 key: InternPool.Key.NamespaceType.Declared,
3794) Allocator.Error!InternPool.Index {
36493795 const zcu = pt.zcu;
36503796 const gpa = zcu.gpa;
36513797 const ip = &zcu.intern_pool;
36523798
3653 const key = switch (full_key) {
3654 .reified => unreachable, // never outdated
3655 .generated_tag => unreachable, // not a union
3656 .declared => |d| d,
3657 };
3658
3659 const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
3799 const inst_info = key.zir_index.resolveFull(ip).?;
36603800 const file = zcu.fileByIndex(inst_info.file);
3661 if (file.status != .success_zir) return error.AnalysisFail;
3801 assert(file.status == .success_zir); // otherwise inst tracking failed
36623802 const zir = file.zir;
36633803
36643804 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
......@@ -3681,7 +3821,7 @@ fn recreateUnionType(
36813821 break :blk fields_len;
36823822 } else 0;
36833823
3684 if (captures_len != key.captures.owned.len) return error.AnalysisFail;
3824 assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew`
36853825
36863826 const union_obj = ip.loadUnionType(old_ty);
36873827
......@@ -3731,23 +3871,19 @@ fn recreateUnionType(
37313871 return wip_ty.finish(ip, namespace_index);
37323872}
37333873
3874// TODO: is it safe for this to return `SemaError`? enum type resolution is a bit weird...
37343875fn recreateEnumType(
37353876 pt: Zcu.PerThread,
37363877 old_ty: InternPool.Index,
3737 full_key: InternPool.Key.NamespaceType,
3878 key: InternPool.Key.NamespaceType.Declared,
37383879) Zcu.SemaError!InternPool.Index {
37393880 const zcu = pt.zcu;
37403881 const gpa = zcu.gpa;
37413882 const ip = &zcu.intern_pool;
37423883
3743 const key = switch (full_key) {
3744 .reified, .generated_tag => unreachable, // never outdated
3745 .declared => |d| d,
3746 };
3747
3748 const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
3884 const inst_info = key.zir_index.resolveFull(ip).?;
37493885 const file = zcu.fileByIndex(inst_info.file);
3750 if (file.status != .success_zir) return error.AnalysisFail;
3886 assert(file.status == .success_zir); // otherwise inst tracking failed
37513887 const zir = file.zir;
37523888
37533889 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
......@@ -3787,7 +3923,7 @@ fn recreateEnumType(
37873923 break :blk decls_len;
37883924 } else 0;
37893925
3790 if (captures_len != key.captures.owned.len) return error.AnalysisFail;
3926 assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew`
37913927
37923928 extra_index += captures_len;
37933929 extra_index += decls_len;
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);
test/incremental/change_panic_handler created+74
......@@ -0,0 +1,74 @@
1#target=x86_64-linux-selfhosted
2#target=x86_64-linux-cbe
3#target=x86_64-windows-cbe
4#update=initial version
5#file=main.zig
6pub fn main() !u8 {
7 var a: u8 = undefined;
8 a = 255;
9 _ = a + 1;
10 return 1;
11}
12pub const Panic = struct {
13 pub const call = myPanic;
14 pub const sentinelMismatch = std.debug.FormattedPanic.sentinelMismatch;
15 pub const unwrapError = std.debug.FormattedPanic.unwrapError;
16 pub const outOfBounds = std.debug.FormattedPanic.outOfBounds;
17 pub const startGreaterThanEnd = std.debug.FormattedPanic.startGreaterThanEnd;
18 pub const inactiveUnionField = std.debug.FormattedPanic.inactiveUnionField;
19 pub const messages = std.debug.FormattedPanic.messages;
20};
21fn myPanic(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
22 std.io.getStdOut().writer().print("panic message: {s}\n", .{msg}) catch {};
23 std.process.exit(0);
24}
25const std = @import("std");
26#expect_stdout="panic message: integer overflow\n"
27
28#update=change the panic handler body
29#file=main.zig
30pub fn main() !u8 {
31 var a: u8 = undefined;
32 a = 255;
33 _ = a + 1;
34 return 1;
35}
36pub const Panic = struct {
37 pub const call = myPanic;
38 pub const sentinelMismatch = std.debug.FormattedPanic.sentinelMismatch;
39 pub const unwrapError = std.debug.FormattedPanic.unwrapError;
40 pub const outOfBounds = std.debug.FormattedPanic.outOfBounds;
41 pub const startGreaterThanEnd = std.debug.FormattedPanic.startGreaterThanEnd;
42 pub const inactiveUnionField = std.debug.FormattedPanic.inactiveUnionField;
43 pub const messages = std.debug.FormattedPanic.messages;
44};
45fn myPanic(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
46 std.io.getStdOut().writer().print("new panic message: {s}\n", .{msg}) catch {};
47 std.process.exit(0);
48}
49const std = @import("std");
50#expect_stdout="new panic message: integer overflow\n"
51
52#update=change the panic handler function value
53#file=main.zig
54pub fn main() !u8 {
55 var a: u8 = undefined;
56 a = 255;
57 _ = a + 1;
58 return 1;
59}
60pub const Panic = struct {
61 pub const call = myPanicNew;
62 pub const sentinelMismatch = std.debug.FormattedPanic.sentinelMismatch;
63 pub const unwrapError = std.debug.FormattedPanic.unwrapError;
64 pub const outOfBounds = std.debug.FormattedPanic.outOfBounds;
65 pub const startGreaterThanEnd = std.debug.FormattedPanic.startGreaterThanEnd;
66 pub const inactiveUnionField = std.debug.FormattedPanic.inactiveUnionField;
67 pub const messages = std.debug.FormattedPanic.messages;
68};
69fn myPanicNew(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
70 std.io.getStdOut().writer().print("third panic message: {s}\n", .{msg}) catch {};
71 std.process.exit(0);
72}
73const std = @import("std");
74#expect_stdout="third panic message: integer overflow\n"
test/incremental/temporary_parse_error created+18
......@@ -0,0 +1,18 @@
1#target=x86_64-linux-selfhosted
2#target=x86_64-linux-cbe
3#target=x86_64-windows-cbe
4#update=initial version
5#file=main.zig
6const std = @import("std");
7pub fn main() !void {}
8#expect_stdout=""
9
10#update=introduce parse error
11#file=main.zig
12pub fn main() !void {
13#expect_error=ignored
14
15#update=fix parse error
16#file=main.zig
17pub fn main() !void {}
18#expect_stdout=""