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

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

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

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

src/Compilation.zig+16-10
...@@ -3158,16 +3158,19 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3158,16 +3158,19 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3158 if (!refs.contains(anal_unit)) continue;3158 if (!refs.contains(anal_unit)) continue;
3159 }3159 }
31603160
3161 const file_index = switch (anal_unit.unwrap()) {3161 report_ok: {
3162 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index.resolveFile(ip),3162 const file_index = switch (anal_unit.unwrap()) {
3163 .nav_val, .nav_ty => |nav| ip.getNav(nav).analysis.?.zir_index.resolveFile(ip),3163 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index.resolveFile(ip),
3164 .type => |ty| Type.fromInterned(ty).typeDeclInst(zcu).?.resolveFile(ip),3164 .nav_val, .nav_ty => |nav| ip.getNav(nav).analysis.?.zir_index.resolveFile(ip),
3165 .func => |ip_index| zcu.funcInfo(ip_index).zir_body_inst.resolveFile(ip),3165 .type => |ty| Type.fromInterned(ty).typeDeclInst(zcu).?.resolveFile(ip),
3166 };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.3170 // Skip errors for AnalUnits within files that had a parse failure.
3169 // We'll try again once parsing succeeds.3171 // We'll try again once parsing succeeds.
3170 if (!zcu.fileByIndex(file_index).okToReportErrors()) continue;3172 if (!zcu.fileByIndex(file_index).okToReportErrors()) continue;
3173 }
31713174
3172 std.log.scoped(.zcu).debug("analysis error '{s}' reported from unit '{}'", .{3175 std.log.scoped(.zcu).debug("analysis error '{s}' reported from unit '{}'", .{
3173 error_msg.msg,3176 error_msg.msg,
...@@ -3391,7 +3394,7 @@ pub fn addModuleErrorMsg(...@@ -3391,7 +3394,7 @@ pub fn addModuleErrorMsg(
3391 const ref = maybe_ref orelse break;3394 const ref = maybe_ref orelse break;
3392 const gop = try seen.getOrPut(gpa, ref.referencer);3395 const gop = try seen.getOrPut(gpa, ref.referencer);
3393 if (gop.found_existing) break;3396 if (gop.found_existing) break;
3394 if (ref_traces.items.len < max_references) {3397 if (ref_traces.items.len < max_references) skip: {
3395 const src = ref.src.upgrade(zcu);3398 const src = ref.src.upgrade(zcu);
3396 const source = try src.file_scope.getSource(gpa);3399 const source = try src.file_scope.getSource(gpa);
3397 const span = try src.span(gpa);3400 const span = try src.span(gpa);
...@@ -3403,6 +3406,7 @@ pub fn addModuleErrorMsg(...@@ -3403,6 +3406,7 @@ pub fn addModuleErrorMsg(
3403 .nav_val, .nav_ty => |nav| ip.getNav(nav).name.toSlice(ip),3406 .nav_val, .nav_ty => |nav| ip.getNav(nav).name.toSlice(ip),
3404 .type => |ty| Type.fromInterned(ty).containerTypeName(ip).toSlice(ip),3407 .type => |ty| Type.fromInterned(ty).containerTypeName(ip).toSlice(ip),
3405 .func => |f| ip.getNav(zcu.funcInfo(f).owner_nav).name.toSlice(ip),3408 .func => |f| ip.getNav(zcu.funcInfo(f).owner_nav).name.toSlice(ip),
3409 .memoized_state => break :skip,
3406 };3410 };
3407 try ref_traces.append(gpa, .{3411 try ref_traces.append(gpa, .{
3408 .decl_name = try eb.addString(name),3412 .decl_name = try eb.addString(name),
...@@ -3670,6 +3674,7 @@ fn performAllTheWorkInner(...@@ -3670,6 +3674,7 @@ fn performAllTheWorkInner(
3670 if (try zcu.findOutdatedToAnalyze()) |outdated| {3674 if (try zcu.findOutdatedToAnalyze()) |outdated| {
3671 try comp.queueJob(switch (outdated.unwrap()) {3675 try comp.queueJob(switch (outdated.unwrap()) {
3672 .func => |f| .{ .analyze_func = f },3676 .func => |f| .{ .analyze_func = f },
3677 .memoized_state,
3673 .@"comptime",3678 .@"comptime",
3674 .nav_ty,3679 .nav_ty,
3675 .nav_val,3680 .nav_val,
...@@ -3737,6 +3742,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre...@@ -3737,6 +3742,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
3737 .nav_ty => |nav| pt.ensureNavTypeUpToDate(nav),3742 .nav_ty => |nav| pt.ensureNavTypeUpToDate(nav),
3738 .nav_val => |nav| pt.ensureNavValUpToDate(nav),3743 .nav_val => |nav| pt.ensureNavValUpToDate(nav),
3739 .type => |ty| if (pt.ensureTypeUpToDate(ty)) |_| {} else |err| err,3744 .type => |ty| if (pt.ensureTypeUpToDate(ty)) |_| {} else |err| err,
3745 .memoized_state => |stage| pt.ensureMemoizedStateUpToDate(stage),
3740 .func => unreachable,3746 .func => unreachable,
3741 };3747 };
3742 maybe_err catch |err| switch (err) {3748 maybe_err catch |err| switch (err) {
src/InternPool.zig+55
...@@ -49,6 +49,11 @@ namespace_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index)...@@ -49,6 +49,11 @@ namespace_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index)
49/// Dependencies on the (non-)existence of some name in a namespace.49/// Dependencies on the (non-)existence of some name in a namespace.
50/// Value is index into `dep_entries` of the first dependency on this name.50/// Value is index into `dep_entries` of the first dependency on this name.
51namespace_name_deps: std.AutoArrayHashMapUnmanaged(NamespaceNameKey, DepEntry.Index),51namespace_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
53/// Given a `Depender`, points to an entry in `dep_entries` whose `depender`58/// Given a `Depender`, points to an entry in `dep_entries` whose `depender`
54/// matches. The `next_dependee` field can be used to iterate all such entries59/// matches. The `next_dependee` field can be used to iterate all such entries
...@@ -87,6 +92,9 @@ pub const empty: InternPool = .{...@@ -87,6 +92,9 @@ pub const empty: InternPool = .{
87 .interned_deps = .empty,92 .interned_deps = .empty,
88 .namespace_deps = .empty,93 .namespace_deps = .empty,
89 .namespace_name_deps = .empty,94 .namespace_name_deps = .empty,
95 .memoized_state_main_deps = .none,
96 .memoized_state_panic_deps = .none,
97 .memoized_state_va_list_deps = .none,
90 .first_dependency = .empty,98 .first_dependency = .empty,
91 .dep_entries = .empty,99 .dep_entries = .empty,
92 .free_dep_entries = .empty,100 .free_dep_entries = .empty,
...@@ -385,6 +393,7 @@ pub const AnalUnit = packed struct(u64) {...@@ -385,6 +393,7 @@ pub const AnalUnit = packed struct(u64) {
385 nav_ty,393 nav_ty,
386 type,394 type,
387 func,395 func,
396 memoized_state,
388 };397 };
389398
390 pub const Unwrapped = union(Kind) {399 pub const Unwrapped = union(Kind) {
...@@ -399,6 +408,8 @@ pub const AnalUnit = packed struct(u64) {...@@ -399,6 +408,8 @@ pub const AnalUnit = packed struct(u64) {
399 type: InternPool.Index,408 type: InternPool.Index,
400 /// This `AnalUnit` analyzes the body of the given runtime function.409 /// This `AnalUnit` analyzes the body of the given runtime function.
401 func: InternPool.Index,410 func: InternPool.Index,
411 /// This `AnalUnit` resolves all state which is memoized in fields on `Zcu`.
412 memoized_state: MemoizedStateStage,
402 };413 };
403414
404 pub fn unwrap(au: AnalUnit) Unwrapped {415 pub fn unwrap(au: AnalUnit) Unwrapped {
...@@ -434,6 +445,16 @@ pub const AnalUnit = packed struct(u64) {...@@ -434,6 +445,16 @@ pub const AnalUnit = packed struct(u64) {
434 };445 };
435};446};
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
437pub const ComptimeUnit = extern struct {458pub const ComptimeUnit = extern struct {
438 zir_index: TrackedInst.Index,459 zir_index: TrackedInst.Index,
439 namespace: NamespaceIndex,460 namespace: NamespaceIndex,
...@@ -769,6 +790,7 @@ pub const Dependee = union(enum) {...@@ -769,6 +790,7 @@ pub const Dependee = union(enum) {
769 interned: Index,790 interned: Index,
770 namespace: TrackedInst.Index,791 namespace: TrackedInst.Index,
771 namespace_name: NamespaceNameKey,792 namespace_name: NamespaceNameKey,
793 memoized_state: MemoizedStateStage,
772};794};
773795
774pub fn removeDependenciesForDepender(ip: *InternPool, gpa: Allocator, depender: AnalUnit) void {796pub fn removeDependenciesForDepender(ip: *InternPool, gpa: Allocator, depender: AnalUnit) void {
...@@ -819,6 +841,11 @@ pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyI...@@ -819,6 +841,11 @@ pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyI
819 .interned => |x| ip.interned_deps.get(x),841 .interned => |x| ip.interned_deps.get(x),
820 .namespace => |x| ip.namespace_deps.get(x),842 .namespace => |x| ip.namespace_deps.get(x),
821 .namespace_name => |x| ip.namespace_name_deps.get(x),843 .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 },
822 } orelse return .{849 } orelse return .{
823 .ip = ip,850 .ip = ip,
824 .next_entry = .none,851 .next_entry = .none,
...@@ -848,6 +875,33 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend...@@ -848,6 +875,33 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend
848 // This block should allocate an entry and prepend it to the relevant `*_deps` list.875 // This block should allocate an entry and prepend it to the relevant `*_deps` list.
849 // The `next` field should be correctly initialized; all other fields may be undefined.876 // The `next` field should be correctly initialized; all other fields may be undefined.
850 const new_index: DepEntry.Index = switch (dependee) {877 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 },
851 inline else => |dependee_payload, tag| new_index: {905 inline else => |dependee_payload, tag| new_index: {
852 const gop = try switch (tag) {906 const gop = try switch (tag) {
853 .file => ip.file_deps,907 .file => ip.file_deps,
...@@ -857,6 +911,7 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend...@@ -857,6 +911,7 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend
857 .interned => ip.interned_deps,911 .interned => ip.interned_deps,
858 .namespace => ip.namespace_deps,912 .namespace => ip.namespace_deps,
859 .namespace_name => ip.namespace_name_deps,913 .namespace_name => ip.namespace_name_deps,
914 .memoized_state => comptime unreachable,
860 }.getOrPut(gpa, dependee_payload);915 }.getOrPut(gpa, dependee_payload);
861916
862 if (gop.found_existing and ip.dep_entries.items[@intFromEnum(gop.value_ptr.*)].depender == .none) {917 if (gop.found_existing and ip.dep_entries.items[@intFromEnum(gop.value_ptr.*)].depender == .none) {
src/Sema.zig+208-215
...@@ -428,7 +428,7 @@ pub const Block = struct {...@@ -428,7 +428,7 @@ pub const Block = struct {
428 } });428 } });
429 }429 }
430430
431 fn nodeOffset(block: Block, node_offset: i32) LazySrcLoc {431 pub fn nodeOffset(block: Block, node_offset: i32) LazySrcLoc {
432 return block.src(LazySrcLoc.Offset.nodeOffset(node_offset));432 return block.src(LazySrcLoc.Offset.nodeOffset(node_offset));
433 }433 }
434434
...@@ -2149,7 +2149,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -2149,7 +2149,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
2149 const addrs_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(addr_arr_ty));2149 const addrs_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(addr_arr_ty));
21502150
2151 // var st: StackTrace = undefined;2151 // 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);
2153 try stack_trace_ty.resolveFields(pt);2153 try stack_trace_ty.resolveFields(pt);
2154 const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty));2154 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 {...@@ -6600,6 +6600,7 @@ fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
6600 .nav_val,6600 .nav_val,
6601 .nav_ty,6601 .nav_ty,
6602 .type,6602 .type,
6603 .memoized_state,
6603 => return, // does nothing outside a function6604 => return, // does nothing outside a function
6604 };6605 };
6605 ip.funcSetDisableInstrumentation(func);6606 ip.funcSetDisableInstrumentation(func);
...@@ -6609,7 +6610,7 @@ fn zirDisableInstrumentation(sema: *Sema) CompileError!void {...@@ -6609,7 +6610,7 @@ fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
6609fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6610fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
6610 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;6611 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
6611 const src = block.builtinCallArgSrc(extra.node, 0);6612 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 });
6613}6614}
66146615
6615fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {6616fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
...@@ -6917,7 +6918,7 @@ fn lookupInNamespace(...@@ -6917,7 +6918,7 @@ fn lookupInNamespace(
69176918
6918 ignore_self: {6919 ignore_self: {
6919 const skip_nav = switch (sema.owner.unwrap()) {6920 const skip_nav = switch (sema.owner.unwrap()) {
6920 .@"comptime", .type, .func => break :ignore_self,6921 .@"comptime", .type, .func, .memoized_state => break :ignore_self,
6921 .nav_ty, .nav_val => |nav| nav,6922 .nav_ty, .nav_val => |nav| nav,
6922 };6923 };
6923 var i: usize = 0;6924 var i: usize = 0;
...@@ -6990,7 +6991,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref...@@ -6990,7 +6991,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
69906991
6991 if (!block.ownerModule().error_tracing) return .none;6992 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);
6994 try stack_trace_ty.resolveFields(pt);6995 try stack_trace_ty.resolveFields(pt);
6995 const field_name = try zcu.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);6996 const field_name = try zcu.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);
6996 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {6997 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {
...@@ -7032,7 +7033,7 @@ fn popErrorReturnTrace(...@@ -7032,7 +7033,7 @@ fn popErrorReturnTrace(
7032 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or7033 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or
7033 // the result is comptime-known to be a non-error. Either way, pop unconditionally.7034 // 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);
7036 try stack_trace_ty.resolveFields(pt);7037 try stack_trace_ty.resolveFields(pt);
7037 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);7038 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
7038 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);7039 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
...@@ -7058,7 +7059,7 @@ fn popErrorReturnTrace(...@@ -7058,7 +7059,7 @@ fn popErrorReturnTrace(
7058 defer then_block.instructions.deinit(gpa);7059 defer then_block.instructions.deinit(gpa);
70597060
7060 // If non-error, then pop the error return trace by restoring the index.7061 // 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);
7062 try stack_trace_ty.resolveFields(pt);7063 try stack_trace_ty.resolveFields(pt);
7063 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);7064 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
7064 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);7065 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
...@@ -7178,7 +7179,7 @@ fn zirCall(...@@ -7178,7 +7179,7 @@ fn zirCall(
7178 const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);7179 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
7180 switch (sema.owner.unwrap()) {7181 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,
7182 .func => |owner_func| if (!zcu.intern_pool.funcAnalysisUnordered(owner_func).calls_or_awaits_errorable_fn) {7183 .func => |owner_func| if (!zcu.intern_pool.funcAnalysisUnordered(owner_func).calls_or_awaits_errorable_fn) {
7183 // No errorable fn actually called; we have no error return trace7184 // No errorable fn actually called; we have no error return trace
7184 input_is_error = false;7185 input_is_error = false;
...@@ -7201,7 +7202,7 @@ fn zirCall(...@@ -7201,7 +7202,7 @@ fn zirCall(
7201 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only7202 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
7202 // need to clean-up our own trace if we were passed to a non-error-handling expression.7203 // need to clean-up our own trace if we were passed to a non-error-handling expression.
7203 if (input_is_error or (pop_error_return_trace and return_ty.isError(zcu))) {7204 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);
7205 try stack_trace_ty.resolveFields(pt);7206 try stack_trace_ty.resolveFields(pt);
7206 const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "index", .no_embedded_nulls);7207 const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "index", .no_embedded_nulls);
7207 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);7208 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
...@@ -8091,7 +8092,7 @@ fn analyzeCall(...@@ -8091,7 +8092,7 @@ fn analyzeCall(
8091 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);8092 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
80928093
8093 switch (sema.owner.unwrap()) {8094 switch (sema.owner.unwrap()) {
8094 .@"comptime", .nav_ty, .nav_val, .type => {},8095 .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {},
8095 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) {8096 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) {
8096 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);8097 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
8097 },8098 },
...@@ -8557,7 +8558,7 @@ fn instantiateGenericCall(...@@ -8557,7 +8558,7 @@ fn instantiateGenericCall(
8557 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);8558 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
85588559
8559 switch (sema.owner.unwrap()) {8560 switch (sema.owner.unwrap()) {
8560 .@"comptime", .nav_ty, .nav_val, .type => {},8561 .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {},
8561 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) {8562 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) {
8562 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);8563 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
8563 },8564 },
...@@ -9537,6 +9538,7 @@ fn zirFunc(...@@ -9537,6 +9538,7 @@ fn zirFunc(
9537 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);9538 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);
9538 const target = zcu.getTarget();9539 const target = zcu.getTarget();
9539 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });9540 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
9541 var extra_index = extra.end;9543 var extra_index = extra.end;
95429544
...@@ -9588,7 +9590,7 @@ fn zirFunc(...@@ -9588,7 +9590,7 @@ fn zirFunc(
9588 // error by trying to evaluate `std.builtin.CallingConvention.c`, so for consistency,9590 // error by trying to evaluate `std.builtin.CallingConvention.c`, so for consistency,
9589 // let's eval that now and just get the transitive error. (It's guaranteed to error9591 // let's eval that now and just get the transitive error. (It's guaranteed to error
9590 // because it does the exact `cCallingConvention` call we just did.)9592 // 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);
9592 _ = try sema.namespaceLookupVal(9594 _ = try sema.namespaceLookupVal(
9593 block,9595 block,
9594 LazySrcLoc.unneeded,9596 LazySrcLoc.unneeded,
...@@ -10302,7 +10304,7 @@ fn finishFunc(...@@ -10302,7 +10304,7 @@ fn finishFunc(
10302 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {10304 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {
10303 // Make sure that StackTrace's fields are resolved so that the backend can10305 // Make sure that StackTrace's fields are resolved so that the backend can
10304 // lower this fn type.10306 // 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);
10306 try unresolved_stack_trace_ty.resolveFields(pt);10308 try unresolved_stack_trace_ty.resolveFields(pt);
10307 }10309 }
1030810310
...@@ -14283,7 +14285,7 @@ fn maybeErrorUnwrap(...@@ -14283,7 +14285,7 @@ fn maybeErrorUnwrap(
14283 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;14285 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
14284 const msg_inst = try sema.resolveInst(inst_data.operand);14286 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");
14287 const err_return_trace = try sema.getErrorReturnTrace(block);14289 const err_return_trace = try sema.getErrorReturnTrace(block);
14288 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };14290 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };
14289 try sema.callBuiltin(block, operand_src, Air.internedToRef(panic_fn), .auto, &args, .@"safety check");14291 try sema.callBuiltin(block, operand_src, Air.internedToRef(panic_fn), .auto, &args, .@"safety check");
...@@ -17477,7 +17479,7 @@ fn analyzeArithmetic(...@@ -17477,7 +17479,7 @@ fn analyzeArithmetic(
17477 if (block.wantSafety() and want_safety and scalar_tag == .int) {17479 if (block.wantSafety() and want_safety and scalar_tag == .int) {
17478 if (zcu.backendSupportsFeature(.safety_checked_instructions)) {17480 if (zcu.backendSupportsFeature(.safety_checked_instructions)) {
17479 if (air_tag != air_tag_safe) {17481 if (air_tag != air_tag_safe) {
17480 _ = try sema.preparePanicId(block, src, .integer_overflow);17482 _ = try sema.preparePanicId(src, .integer_overflow);
17481 }17483 }
17482 return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs);17484 return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs);
17483 } else {17485 } else {
...@@ -18381,7 +18383,7 @@ fn zirBuiltinSrc(...@@ -18381,7 +18383,7 @@ fn zirBuiltinSrc(
18381 } });18383 } });
18382 };18384 };
1838318385
18384 const src_loc_ty = try sema.getBuiltinType("SourceLocation");18386 const src_loc_ty = try sema.getBuiltinType(block.nodeOffset(0), .SourceLocation);
18385 const fields = .{18387 const fields = .{
18386 // module: [:0]const u8,18388 // module: [:0]const u8,
18387 module_name_val,18389 module_name_val,
...@@ -18408,7 +18410,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18408,7 +18410,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18408 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;18410 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18409 const src = block.nodeOffset(inst_data.src_node);18411 const src = block.nodeOffset(inst_data.src_node);
18410 const ty = try sema.resolveType(block, src, inst_data.operand);18412 const ty = try sema.resolveType(block, src, inst_data.operand);
18411 const type_info_ty = try sema.getBuiltinType("Type");18413 const type_info_ty = try sema.getBuiltinType(src, .Type);
18412 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;18414 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;
1841318415
18414 if (ty.typeDeclInst(zcu)) |type_decl_inst| {18416 if (ty.typeDeclInst(zcu)) |type_decl_inst| {
...@@ -18428,8 +18430,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18428,8 +18430,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18428 => |type_info_tag| return unionInitFromEnumTag(sema, block, src, type_info_ty, @intFromEnum(type_info_tag), .void_value),18430 => |type_info_tag| return unionInitFromEnumTag(sema, block, src, type_info_ty, @intFromEnum(type_info_tag), .void_value),
1842918431
18430 .@"fn" => {18432 .@"fn" => {
18431 const fn_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Fn");18433 const fn_info_ty = try sema.getBuiltinType(src, .@"Type.Fn");
18432 const param_info_ty = try getBuiltinInnerType(sema, block, src, fn_info_ty, "Type.Fn", "Param");18434 const param_info_ty = try sema.getBuiltinType(src, .@"Type.Fn.Param");
1843318435
18434 const func_ty_info = zcu.typeToFunc(ty).?;18436 const func_ty_info = zcu.typeToFunc(ty).?;
18435 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);18437 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
...@@ -18499,7 +18501,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18499,7 +18501,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18499 func_ty_info.return_type,18501 func_ty_info.return_type,
18500 } });18502 } });
1850118503
18502 const callconv_ty = try sema.getBuiltinType("CallingConvention");18504 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
18503 const callconv_val = Value.uninterpret(func_ty_info.cc, callconv_ty, pt) catch |err| switch (err) {18505 const callconv_val = Value.uninterpret(func_ty_info.cc, callconv_ty, pt) catch |err| switch (err) {
18504 error.TypeMismatch => @panic("std.builtin is corrupt"),18506 error.TypeMismatch => @panic("std.builtin is corrupt"),
18505 error.OutOfMemory => |e| return e,18507 error.OutOfMemory => |e| return e,
...@@ -18527,8 +18529,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18527,8 +18529,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18527 })));18529 })));
18528 },18530 },
18529 .int => {18531 .int => {
18530 const int_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Int");18532 const int_info_ty = try sema.getBuiltinType(src, .@"Type.Int");
18531 const signedness_ty = try sema.getBuiltinType("Signedness");18533 const signedness_ty = try sema.getBuiltinType(src, .Signedness);
18532 const info = ty.intInfo(zcu);18534 const info = ty.intInfo(zcu);
18533 const field_values = .{18535 const field_values = .{
18534 // signedness: Signedness,18536 // signedness: Signedness,
...@@ -18546,7 +18548,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18546,7 +18548,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18546 })));18548 })));
18547 },18549 },
18548 .float => {18550 .float => {
18549 const float_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Float");18551 const float_info_ty = try sema.getBuiltinType(src, .@"Type.Float");
1855018552
18551 const field_vals = .{18553 const field_vals = .{
18552 // bits: u16,18554 // bits: u16,
...@@ -18568,9 +18570,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18568,9 +18570,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18568 else18570 else
18569 try Type.fromInterned(info.child).lazyAbiAlignment(pt);18571 try Type.fromInterned(info.child).lazyAbiAlignment(pt);
1857018572
18571 const addrspace_ty = try sema.getBuiltinType("AddressSpace");18573 const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
18572 const pointer_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Pointer");18574 const pointer_ty = try sema.getBuiltinType(src, .@"Type.Pointer");
18573 const ptr_size_ty = try getBuiltinInnerType(sema, block, src, pointer_ty, "Type.Pointer", "Size");18575 const ptr_size_ty = try sema.getBuiltinType(src, .@"Type.Pointer.Size");
1857418576
18575 const field_values = .{18577 const field_values = .{
18576 // size: Size,18578 // size: Size,
...@@ -18603,7 +18605,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18603,7 +18605,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18603 })));18605 })));
18604 },18606 },
18605 .array => {18607 .array => {
18606 const array_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Array");18608 const array_field_ty = try sema.getBuiltinType(src, .@"Type.Array");
1860718609
18608 const info = ty.arrayInfo(zcu);18610 const info = ty.arrayInfo(zcu);
18609 const field_values = .{18611 const field_values = .{
...@@ -18624,7 +18626,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18624,7 +18626,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18624 })));18626 })));
18625 },18627 },
18626 .vector => {18628 .vector => {
18627 const vector_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Vector");18629 const vector_field_ty = try sema.getBuiltinType(src, .@"Type.Vector");
1862818630
18629 const info = ty.arrayInfo(zcu);18631 const info = ty.arrayInfo(zcu);
18630 const field_values = .{18632 const field_values = .{
...@@ -18643,7 +18645,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18643,7 +18645,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18643 })));18645 })));
18644 },18646 },
18645 .optional => {18647 .optional => {
18646 const optional_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Optional");18648 const optional_field_ty = try sema.getBuiltinType(src, .@"Type.Optional");
1864718649
18648 const field_values = .{18650 const field_values = .{
18649 // child: type,18651 // child: type,
...@@ -18660,7 +18662,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18660,7 +18662,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18660 },18662 },
18661 .error_set => {18663 .error_set => {
18662 // Get the Error type18664 // Get the Error type
18663 const error_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Error");18665 const error_field_ty = try sema.getBuiltinType(src, .@"Type.Error");
1866418666
18665 // Build our list of Error values18667 // Build our list of Error values
18666 // Optional value is only null if anyerror18668 // Optional value is only null if anyerror
...@@ -18756,7 +18758,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18756,7 +18758,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18756 })));18758 })));
18757 },18759 },
18758 .error_union => {18760 .error_union => {
18759 const error_union_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ErrorUnion");18761 const error_union_field_ty = try sema.getBuiltinType(src, .@"Type.ErrorUnion");
1876018762
18761 const field_values = .{18763 const field_values = .{
18762 // error_set: type,18764 // error_set: type,
...@@ -18776,7 +18778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18776,7 +18778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18776 .@"enum" => {18778 .@"enum" => {
18777 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);18779 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);
1877818780
18779 const enum_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "EnumField");18781 const enum_field_ty = try sema.getBuiltinType(src, .@"Type.EnumField");
1878018782
18781 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);18783 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);
18782 for (enum_field_vals, 0..) |*field_val, tag_index| {18784 for (enum_field_vals, 0..) |*field_val, tag_index| {
...@@ -18861,9 +18863,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18861,9 +18863,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18861 } });18863 } });
18862 };18864 };
1886318865
18864 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace.toOptional());18866 const decls_val = try sema.typeInfoDecls(block, src, ip.loadEnumType(ty.toIntern()).namespace.toOptional());
1886518867
18866 const type_enum_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Enum");18868 const type_enum_ty = try sema.getBuiltinType(src, .@"Type.Enum");
1886718869
18868 const field_values = .{18870 const field_values = .{
18869 // tag_type: type,18871 // tag_type: type,
...@@ -18885,8 +18887,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18885,8 +18887,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18885 })));18887 })));
18886 },18888 },
18887 .@"union" => {18889 .@"union" => {
18888 const type_union_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Union");18890 const type_union_ty = try sema.getBuiltinType(src, .@"Type.Union");
18889 const union_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "UnionField");18891 const union_field_ty = try sema.getBuiltinType(src, .@"Type.UnionField");
1889018892
18891 try ty.resolveLayout(pt); // Getting alignment requires type layout18893 try ty.resolveLayout(pt); // Getting alignment requires type layout
18892 const union_obj = zcu.typeToUnion(ty).?;18894 const union_obj = zcu.typeToUnion(ty).?;
...@@ -18974,14 +18976,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18974,14 +18976,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18974 } });18976 } });
18975 };18977 };
1897618978
18977 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(zcu).toOptional());18979 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespaceIndex(zcu).toOptional());
1897818980
18979 const enum_tag_ty_val = try pt.intern(.{ .opt = .{18981 const enum_tag_ty_val = try pt.intern(.{ .opt = .{
18980 .ty = (try pt.optionalType(.type_type)).toIntern(),18982 .ty = (try pt.optionalType(.type_type)).toIntern(),
18981 .val = if (ty.unionTagType(zcu)) |tag_ty| tag_ty.toIntern() else .none,18983 .val = if (ty.unionTagType(zcu)) |tag_ty| tag_ty.toIntern() else .none,
18982 } });18984 } });
1898318985
18984 const container_layout_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ContainerLayout");18986 const container_layout_ty = try sema.getBuiltinType(src, .@"Type.ContainerLayout");
1898518987
18986 const field_values = .{18988 const field_values = .{
18987 // layout: ContainerLayout,18989 // layout: ContainerLayout,
...@@ -19004,8 +19006,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19004,8 +19006,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19004 })));19006 })));
19005 },19007 },
19006 .@"struct" => {19008 .@"struct" => {
19007 const type_struct_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Struct");19009 const type_struct_ty = try sema.getBuiltinType(src, .@"Type.Struct");
19008 const struct_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "StructField");19010 const struct_field_ty = try sema.getBuiltinType(src, .@"Type.StructField");
1900919011
19010 try ty.resolveLayout(pt); // Getting alignment requires type layout19012 try ty.resolveLayout(pt); // Getting alignment requires type layout
1901119013
...@@ -19169,7 +19171,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19169,7 +19171,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19169 } });19171 } });
19170 };19172 };
1917119173
19172 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(zcu));19174 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespace(zcu));
1917319175
19174 const backing_integer_val = try pt.intern(.{ .opt = .{19176 const backing_integer_val = try pt.intern(.{ .opt = .{
19175 .ty = (try pt.optionalType(.type_type)).toIntern(),19177 .ty = (try pt.optionalType(.type_type)).toIntern(),
...@@ -19179,7 +19181,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19179,7 +19181,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19179 } else .none,19181 } else .none,
19180 } });19182 } });
1918119183
19182 const container_layout_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ContainerLayout");19184 const container_layout_ty = try sema.getBuiltinType(src, .@"Type.ContainerLayout");
1918319185
19184 const layout = ty.containerLayout(zcu);19186 const layout = ty.containerLayout(zcu);
1918519187
...@@ -19205,10 +19207,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19205,10 +19207,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19205 })));19207 })));
19206 },19208 },
19207 .@"opaque" => {19209 .@"opaque" => {
19208 const type_opaque_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Opaque");19210 const type_opaque_ty = try sema.getBuiltinType(src, .@"Type.Opaque");
1920919211
19210 try ty.resolveFields(pt);19212 try ty.resolveFields(pt);
19211 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(zcu));19213 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespace(zcu));
1921219214
19213 const field_values = .{19215 const field_values = .{
19214 // decls: []const Declaration,19216 // decls: []const Declaration,
...@@ -19232,14 +19234,13 @@ fn typeInfoDecls(...@@ -19232,14 +19234,13 @@ fn typeInfoDecls(
19232 sema: *Sema,19234 sema: *Sema,
19233 block: *Block,19235 block: *Block,
19234 src: LazySrcLoc,19236 src: LazySrcLoc,
19235 type_info_ty: Type,
19236 opt_namespace: InternPool.OptionalNamespaceIndex,19237 opt_namespace: InternPool.OptionalNamespaceIndex,
19237) CompileError!InternPool.Index {19238) CompileError!InternPool.Index {
19238 const pt = sema.pt;19239 const pt = sema.pt;
19239 const zcu = pt.zcu;19240 const zcu = pt.zcu;
19240 const gpa = sema.gpa;19241 const gpa = sema.gpa;
1924119242
19242 const declaration_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Declaration");19243 const declaration_ty = try sema.getBuiltinType(src, .@"Type.Declaration");
1924319244
19244 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);19245 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
19245 defer decl_vals.deinit();19246 defer decl_vals.deinit();
...@@ -20181,11 +20182,11 @@ fn retWithErrTracing(...@@ -20181,11 +20182,11 @@ fn retWithErrTracing(
20181 else => true,20182 else => true,
20182 };20183 };
20183 const gpa = sema.gpa;20184 const gpa = sema.gpa;
20184 const stack_trace_ty = try sema.getBuiltinType("StackTrace");20185 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
20185 try stack_trace_ty.resolveFields(pt);20186 try stack_trace_ty.resolveFields(pt);
20186 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);20187 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
20187 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);20188 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
20188 const return_err_fn = try sema.getBuiltin("returnError");20189 const return_err_fn = Air.internedToRef(try sema.getBuiltin(src, .returnError));
20189 const args: [1]Air.Inst.Ref = .{err_return_trace};20190 const args: [1]Air.Inst.Ref = .{err_return_trace};
2019020191
20191 if (!need_check) {20192 if (!need_check) {
...@@ -21607,7 +21608,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -21607,7 +21608,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
21607 const pt = sema.pt;21608 const pt = sema.pt;
21608 const zcu = pt.zcu;21609 const zcu = pt.zcu;
21609 const ip = &zcu.intern_pool;21610 const ip = &zcu.intern_pool;
21610 const stack_trace_ty = try sema.getBuiltinType("StackTrace");21611 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace);
21611 try stack_trace_ty.resolveFields(pt);21612 try stack_trace_ty.resolveFields(pt);
21612 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);21613 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
21613 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());21614 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
...@@ -21616,7 +21617,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -21616,7 +21617,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
21616 .func => |func| if (ip.funcAnalysisUnordered(func).calls_or_awaits_errorable_fn and block.ownerModule().error_tracing) {21617 .func => |func| if (ip.funcAnalysisUnordered(func).calls_or_awaits_errorable_fn and block.ownerModule().error_tracing) {
21617 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);21618 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
21618 },21619 },
21619 .@"comptime", .nav_ty, .nav_val, .type => {},21620 .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {},
21620 }21621 }
21621 return Air.internedToRef(try pt.intern(.{ .opt = .{21622 return Air.internedToRef(try pt.intern(.{ .opt = .{
21622 .ty = opt_ptr_stack_trace_ty.toIntern(),21623 .ty = opt_ptr_stack_trace_ty.toIntern(),
...@@ -21896,7 +21897,7 @@ fn zirReify(...@@ -21896,7 +21897,7 @@ fn zirReify(
21896 },21897 },
21897 },21898 },
21898 };21899 };
21899 const type_info_ty = try sema.getBuiltinType("Type");21900 const type_info_ty = try sema.getBuiltinType(src, .Type);
21900 const uncasted_operand = try sema.resolveInst(extra.operand);21901 const uncasted_operand = try sema.resolveInst(extra.operand);
21901 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);21902 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
21902 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{ .simple = .operand_Type });21903 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{ .simple = .operand_Type });
...@@ -23156,7 +23157,7 @@ fn reifyStruct(...@@ -23156,7 +23157,7 @@ fn reifyStruct(
2315623157
23157fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {23158fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
23158 const pt = sema.pt;23159 const pt = sema.pt;
23159 const va_list_ty = try sema.getBuiltinType("VaList");23160 const va_list_ty = try sema.getBuiltinType(src, .VaList);
23160 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);23161 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);
2316123162
23162 const inst = try sema.resolveInst(zir_ref);23163 const inst = try sema.resolveInst(zir_ref);
...@@ -23195,7 +23196,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)...@@ -23195,7 +23196,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
23195 const va_list_src = block.builtinCallArgSrc(extra.node, 0);23196 const va_list_src = block.builtinCallArgSrc(extra.node, 0);
2319623197
23197 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);23198 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);
23198 const va_list_ty = try sema.getBuiltinType("VaList");23199 const va_list_ty = try sema.getBuiltinType(src, .VaList);
2319923200
23200 try sema.requireRuntimeBlock(block, src, null);23201 try sema.requireRuntimeBlock(block, src, null);
23201 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);23202 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);
...@@ -23215,7 +23216,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -23215,7 +23216,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
23215fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {23216fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
23216 const src = block.nodeOffset(@bitCast(extended.operand));23217 const src = block.nodeOffset(@bitCast(extended.operand));
2321723218
23218 const va_list_ty = try sema.getBuiltinType("VaList");23219 const va_list_ty = try sema.getBuiltinType(src, .VaList);
23219 try sema.requireRuntimeBlock(block, src, null);23220 try sema.requireRuntimeBlock(block, src, null);
23220 return block.addInst(.{23221 return block.addInst(.{
23221 .tag = .c_va_start,23222 .tag = .c_va_start,
...@@ -24821,7 +24822,7 @@ fn resolveExportOptions(...@@ -24821,7 +24822,7 @@ fn resolveExportOptions(
24821 const zcu = pt.zcu;24822 const zcu = pt.zcu;
24822 const gpa = sema.gpa;24823 const gpa = sema.gpa;
24823 const ip = &zcu.intern_pool;24824 const ip = &zcu.intern_pool;
24824 const export_options_ty = try sema.getBuiltinType("ExportOptions");24825 const export_options_ty = try sema.getBuiltinType(src, .ExportOptions);
24825 const air_ref = try sema.resolveInst(zir_ref);24826 const air_ref = try sema.resolveInst(zir_ref);
24826 const options = try sema.coerce(block, export_options_ty, air_ref, src);24827 const options = try sema.coerce(block, export_options_ty, air_ref, src);
2482724828
...@@ -24871,15 +24872,15 @@ fn resolveBuiltinEnum(...@@ -24871,15 +24872,15 @@ fn resolveBuiltinEnum(
24871 block: *Block,24872 block: *Block,
24872 src: LazySrcLoc,24873 src: LazySrcLoc,
24873 zir_ref: Zir.Inst.Ref,24874 zir_ref: Zir.Inst.Ref,
24874 comptime name: []const u8,24875 comptime name: Zcu.BuiltinDecl,
24875 reason: ComptimeReason,24876 reason: ComptimeReason,
24876) CompileError!@field(std.builtin, name) {24877) CompileError!@field(std.builtin, @tagName(name)) {
24877 const pt = sema.pt;24878 const pt = sema.pt;
24878 const ty = try sema.getBuiltinType(name);24879 const ty = try sema.getBuiltinType(src, name);
24879 const air_ref = try sema.resolveInst(zir_ref);24880 const air_ref = try sema.resolveInst(zir_ref);
24880 const coerced = try sema.coerce(block, ty, air_ref, src);24881 const coerced = try sema.coerce(block, ty, air_ref, src);
24881 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);24882 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
24882 return pt.zcu.toEnum(@field(std.builtin, name), val);24883 return pt.zcu.toEnum(@field(std.builtin, @tagName(name)), val);
24883}24884}
2488424885
24885fn resolveAtomicOrder(24886fn resolveAtomicOrder(
...@@ -24889,7 +24890,7 @@ fn resolveAtomicOrder(...@@ -24889,7 +24890,7 @@ fn resolveAtomicOrder(
24889 zir_ref: Zir.Inst.Ref,24890 zir_ref: Zir.Inst.Ref,
24890 reason: ComptimeReason,24891 reason: ComptimeReason,
24891) CompileError!std.builtin.AtomicOrder {24892) CompileError!std.builtin.AtomicOrder {
24892 return sema.resolveBuiltinEnum(block, src, zir_ref, "AtomicOrder", reason);24893 return sema.resolveBuiltinEnum(block, src, zir_ref, .AtomicOrder, reason);
24893}24894}
2489424895
24895fn resolveAtomicRmwOp(24896fn resolveAtomicRmwOp(
...@@ -24898,7 +24899,7 @@ fn resolveAtomicRmwOp(...@@ -24898,7 +24899,7 @@ fn resolveAtomicRmwOp(
24898 src: LazySrcLoc,24899 src: LazySrcLoc,
24899 zir_ref: Zir.Inst.Ref,24900 zir_ref: Zir.Inst.Ref,
24900) CompileError!std.builtin.AtomicRmwOp {24901) CompileError!std.builtin.AtomicRmwOp {
24901 return sema.resolveBuiltinEnum(block, src, zir_ref, "AtomicRmwOp", .{ .simple = .operand_atomicRmw_operation });24902 return sema.resolveBuiltinEnum(block, src, zir_ref, .AtomicRmwOp, .{ .simple = .operand_atomicRmw_operation });
24902}24903}
2490324904
24904fn zirCmpxchg(24905fn zirCmpxchg(
...@@ -25078,7 +25079,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -25078,7 +25079,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
25078 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;25079 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
25079 const op_src = block.builtinCallArgSrc(inst_data.src_node, 0);25080 const op_src = block.builtinCallArgSrc(inst_data.src_node, 0);
25080 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 1);25081 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 1);
25081 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp", .{ .simple = .operand_reduce_operation });25082 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, .ReduceOp, .{ .simple = .operand_reduce_operation });
25082 const operand = try sema.resolveInst(extra.rhs);25083 const operand = try sema.resolveInst(extra.rhs);
25083 const operand_ty = sema.typeOf(operand);25084 const operand_ty = sema.typeOf(operand);
25084 const pt = sema.pt;25085 const pt = sema.pt;
...@@ -25668,7 +25669,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -25668,7 +25669,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
25668 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;25669 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
25669 const func = try sema.resolveInst(extra.callee);25670 const func = try sema.resolveInst(extra.callee);
2567025671
25671 const modifier_ty = try sema.getBuiltinType("CallModifier");25672 const modifier_ty = try sema.getBuiltinType(call_src, .CallModifier);
25672 const air_ref = try sema.resolveInst(extra.modifier);25673 const air_ref = try sema.resolveInst(extra.modifier);
25673 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);25674 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);
25674 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{ .simple = .call_modifier });25675 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{ .simple = .call_modifier });
...@@ -26630,13 +26631,13 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -26630,13 +26631,13 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26630 const body = sema.code.bodySlice(extra_index, body_len);26631 const body = sema.code.bodySlice(extra_index, body_len);
26631 extra_index += body.len;26632 extra_index += body.len;
2663226633
26633 const cc_ty = try sema.getBuiltinType("CallingConvention");26634 const cc_ty = try sema.getBuiltinType(cc_src, .CallingConvention);
26634 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{ .simple = .@"callconv" });26635 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{ .simple = .@"callconv" });
26635 break :blk try sema.analyzeValueAsCallconv(block, cc_src, val);26636 break :blk try sema.analyzeValueAsCallconv(block, cc_src, val);
26636 } else if (extra.data.bits.has_cc_ref) blk: {26637 } else if (extra.data.bits.has_cc_ref) blk: {
26637 const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);26638 const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
26638 extra_index += 1;26639 extra_index += 1;
26639 const cc_ty = try sema.getBuiltinType("CallingConvention");26640 const cc_ty = try sema.getBuiltinType(cc_src, .CallingConvention);
26640 const uncoerced_cc = try sema.resolveInst(cc_ref);26641 const uncoerced_cc = try sema.resolveInst(cc_ref);
26641 const coerced_cc = try sema.coerce(block, cc_ty, uncoerced_cc, cc_src);26642 const coerced_cc = try sema.coerce(block, cc_ty, uncoerced_cc, cc_src);
26642 const cc_val = try sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{ .simple = .@"callconv" });26643 const cc_val = try sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{ .simple = .@"callconv" });
...@@ -26656,7 +26657,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -26656,7 +26657,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26656 // error by trying to evaluate `std.builtin.CallingConvention.c`, so for consistency,26657 // error by trying to evaluate `std.builtin.CallingConvention.c`, so for consistency,
26657 // let's eval that now and just get the transitive error. (It's guaranteed to error26658 // let's eval that now and just get the transitive error. (It's guaranteed to error
26658 // because it does the exact `cCallingConvention` call we just did.)26659 // because it does the exact `cCallingConvention` call we just did.)
26659 const cc_type = try sema.getBuiltinType("CallingConvention");26660 const cc_type = try sema.getBuiltinType(cc_src, .CallingConvention);
26660 _ = try sema.namespaceLookupVal(26661 _ = try sema.namespaceLookupVal(
26661 block,26662 block,
26662 LazySrcLoc.unneeded,26663 LazySrcLoc.unneeded,
...@@ -26834,7 +26835,7 @@ fn resolvePrefetchOptions(...@@ -26834,7 +26835,7 @@ fn resolvePrefetchOptions(
26834 const zcu = pt.zcu;26835 const zcu = pt.zcu;
26835 const gpa = sema.gpa;26836 const gpa = sema.gpa;
26836 const ip = &zcu.intern_pool;26837 const ip = &zcu.intern_pool;
26837 const options_ty = try sema.getBuiltinType("PrefetchOptions");26838 const options_ty = try sema.getBuiltinType(src, .PrefetchOptions);
26838 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);26839 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
2683926840
26840 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });26841 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });
...@@ -26902,7 +26903,7 @@ fn resolveExternOptions(...@@ -26902,7 +26903,7 @@ fn resolveExternOptions(
26902 const gpa = sema.gpa;26903 const gpa = sema.gpa;
26903 const ip = &zcu.intern_pool;26904 const ip = &zcu.intern_pool;
26904 const options_inst = try sema.resolveInst(zir_ref);26905 const options_inst = try sema.resolveInst(zir_ref);
26905 const extern_options_ty = try sema.getBuiltinType("ExternOptions");26906 const extern_options_ty = try sema.getBuiltinType(src, .ExternOptions);
26906 const options = try sema.coerce(block, extern_options_ty, options_inst, src);26907 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
2690726908
26908 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });26909 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
...@@ -27004,6 +27005,7 @@ fn zirBuiltinExtern(...@@ -27004,6 +27005,7 @@ fn zirBuiltinExtern(
27004 .zir_index = switch (sema.owner.unwrap()) {27005 .zir_index = switch (sema.owner.unwrap()) {
27005 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index,27006 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index,
27006 .type => |owner_ty| Type.fromInterned(owner_ty).typeDeclInst(zcu).?,27007 .type => |owner_ty| Type.fromInterned(owner_ty).typeDeclInst(zcu).?,
27008 .memoized_state => unreachable,
27007 .nav_ty, .nav_val => |nav| ip.getNav(nav).analysis.?.zir_index,27009 .nav_ty, .nav_val => |nav| ip.getNav(nav).analysis.?.zir_index,
27008 .func => |func| zir_index: {27010 .func => |func| zir_index: {
27009 const func_info = zcu.funcInfo(func);27011 const func_info = zcu.funcInfo(func);
...@@ -27081,23 +27083,25 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -27081,23 +27083,25 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
27081 const src = block.nodeOffset(@bitCast(extended.operand));27083 const src = block.nodeOffset(@bitCast(extended.operand));
27082 const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small);27084 const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small);
2708327085
27084 const type_name = switch (value) {27086 const ty = switch (value) {
27085 .atomic_order => "AtomicOrder",27087 // zig fmt: off
27086 .atomic_rmw_op => "AtomicRmwOp",27088 .atomic_order => try sema.getBuiltinType(src, .AtomicOrder),
27087 .calling_convention => "CallingConvention",27089 .atomic_rmw_op => try sema.getBuiltinType(src, .AtomicRmwOp),
27088 .address_space => "AddressSpace",27090 .calling_convention => try sema.getBuiltinType(src, .CallingConvention),
27089 .float_mode => "FloatMode",27091 .address_space => try sema.getBuiltinType(src, .AddressSpace),
27090 .reduce_op => "ReduceOp",27092 .float_mode => try sema.getBuiltinType(src, .FloatMode),
27091 .call_modifier => "CallModifier",27093 .reduce_op => try sema.getBuiltinType(src, .ReduceOp),
27092 .prefetch_options => "PrefetchOptions",27094 .call_modifier => try sema.getBuiltinType(src, .CallModifier),
27093 .export_options => "ExportOptions",27095 .prefetch_options => try sema.getBuiltinType(src, .PrefetchOptions),
27094 .extern_options => "ExternOptions",27096 .export_options => try sema.getBuiltinType(src, .ExportOptions),
27095 .type_info => "Type",27097 .extern_options => try sema.getBuiltinType(src, .ExternOptions),
27096 .branch_hint => "BranchHint",27098 .type_info => try sema.getBuiltinType(src, .Type),
27099 .branch_hint => try sema.getBuiltinType(src, .BranchHint),
27100 // zig fmt: on
2709727101
27098 // Values are handled here.27102 // Values are handled here.
27099 .calling_convention_c => {27103 .calling_convention_c => {
27100 const callconv_ty = try sema.getBuiltinType("CallingConvention");27104 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
27101 return try sema.namespaceLookupVal(27105 return try sema.namespaceLookupVal(
27102 block,27106 block,
27103 src,27107 src,
...@@ -27107,7 +27111,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -27107,7 +27111,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
27107 },27111 },
27108 .calling_convention_inline => {27112 .calling_convention_inline => {
27109 comptime assert(@typeInfo(std.builtin.CallingConvention.Tag).@"enum".tag_type == u8);27113 comptime assert(@typeInfo(std.builtin.CallingConvention.Tag).@"enum".tag_type == u8);
27110 const callconv_ty = try sema.getBuiltinType("CallingConvention");27114 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
27111 const callconv_tag_ty = callconv_ty.unionTagType(zcu) orelse @panic("std.builtin is corrupt");27115 const callconv_tag_ty = callconv_ty.unionTagType(zcu) orelse @panic("std.builtin is corrupt");
27112 const inline_tag_val = try pt.enumValue(27116 const inline_tag_val = try pt.enumValue(
27113 callconv_tag_ty,27117 callconv_tag_ty,
...@@ -27119,7 +27123,6 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -27119,7 +27123,6 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
27119 return sema.coerce(block, callconv_ty, Air.internedToRef(inline_tag_val.toIntern()), src);27123 return sema.coerce(block, callconv_ty, Air.internedToRef(inline_tag_val.toIntern()), src);
27120 },27124 },
27121 };27125 };
27122 const ty = try sema.getBuiltinType(type_name);
27123 return Air.internedToRef(ty.toIntern());27126 return Air.internedToRef(ty.toIntern());
27124}27127}
2712527128
...@@ -27158,7 +27161,7 @@ fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -27158,7 +27161,7 @@ fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
27158 const uncoerced_hint = try sema.resolveInst(extra.operand);27161 const uncoerced_hint = try sema.resolveInst(extra.operand);
27159 const operand_src = block.builtinCallArgSrc(extra.node, 0);27162 const operand_src = block.builtinCallArgSrc(extra.node, 0);
2716027163
27161 const hint_ty = try sema.getBuiltinType("BranchHint");27164 const hint_ty = try sema.getBuiltinType(operand_src, .BranchHint);
27162 const coerced_hint = try sema.coerce(block, hint_ty, uncoerced_hint, operand_src);27165 const coerced_hint = try sema.coerce(block, hint_ty, uncoerced_hint, operand_src);
27163 const hint_val = try sema.resolveConstDefinedValue(block, operand_src, coerced_hint, .{ .simple = .operand_branchHint });27166 const hint_val = try sema.resolveConstDefinedValue(block, operand_src, coerced_hint, .{ .simple = .operand_branchHint });
2716427167
...@@ -27603,61 +27606,19 @@ fn explainWhyTypeIsNotPacked(...@@ -27603,61 +27606,19 @@ fn explainWhyTypeIsNotPacked(
27603 }27606 }
27604}27607}
2760527608
27606fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
27607 const pt = sema.pt;
27608 const zcu = pt.zcu;
27609
27610 if (zcu.panic_func_index == .none) {
27611 zcu.panic_func_index = try sema.getPanicInnerFn(block, src, "call");
27612 // Here, function body analysis must be queued up so that backends can
27613 // make calls to this function.
27614 try zcu.ensureFuncBodyAnalysisQueued(zcu.panic_func_index);
27615 }
27616
27617 if (zcu.null_stack_trace == .none) {
27618 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
27619 try stack_trace_ty.resolveFields(pt);
27620 const target = zcu.getTarget();
27621 const ptr_stack_trace_ty = try pt.ptrTypeSema(.{
27622 .child = stack_trace_ty.toIntern(),
27623 .flags = .{
27624 .address_space = target_util.defaultAddressSpace(target, .global_constant),
27625 },
27626 });
27627 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
27628 zcu.null_stack_trace = try pt.intern(.{ .opt = .{
27629 .ty = opt_ptr_stack_trace_ty.toIntern(),
27630 .val = .none,
27631 } });
27632 }
27633}
27634
27635/// Backends depend on panic decls being available when lowering safety-checked27609/// Backends depend on panic decls being available when lowering safety-checked
27636/// instructions. This function ensures the panic function will be available to27610/// instructions. This function ensures the panic function will be available to
27637/// be called during that time.27611/// be called during that time.
27638fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Zcu.PanicId) !InternPool.Nav.Index {27612fn preparePanicId(sema: *Sema, src: LazySrcLoc, panic_id: Zcu.PanicId) !InternPool.Index {
27639 const pt = sema.pt;27613 const zcu = sema.pt.zcu;
27640 const zcu = pt.zcu;27614 try sema.ensureMemoizedStateResolved(src, .panic);
27641 const gpa = sema.gpa;27615 try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.@"Panic.call");
27642 if (zcu.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;27616 switch (panic_id) {
2764327617 inline else => |ct_panic_id| {
27644 try sema.prepareSimplePanic(block, src);27618 const name = "Panic.messages." ++ @tagName(ct_panic_id);
2764527619 return @field(zcu.builtin_decl_values, name);
27646 const panic_ty = try sema.getBuiltinType("Panic");27620 },
27647 const panic_messages_ty = try sema.getBuiltinInnerType(block, src, panic_ty, "Panic", "messages");27621 }
27648 const msg_nav_index = (sema.namespaceLookup(
27649 block,
27650 LazySrcLoc.unneeded,
27651 panic_messages_ty.getNamespaceIndex(zcu),
27652 try zcu.intern_pool.getOrPutString(gpa, pt.tid, @tagName(panic_id), .no_embedded_nulls),
27653 ) catch |err| switch (err) {
27654 error.AnalysisFail => return error.AnalysisFail,
27655 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
27656 error.OutOfMemory => |e| return e,
27657 }).?;
27658 try sema.ensureNavResolved(src, msg_nav_index, .fully);
27659 zcu.panic_messages[@intFromEnum(panic_id)] = msg_nav_index.toOptional();
27660 return msg_nav_index;
27661}27622}
2766227623
27663fn addSafetyCheck(27624fn addSafetyCheck(
...@@ -27761,10 +27722,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst....@@ -27761,10 +27722,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
27761 return;27722 return;
27762 }27723 }
2776327724
27764 try sema.prepareSimplePanic(block, src);27725 try sema.ensureMemoizedStateResolved(src, .panic);
27726 try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.@"Panic.call");
2776527727
27766 const panic_func = zcu.funcInfo(zcu.panic_func_index);27728 const panic_fn = Air.internedToRef(zcu.builtin_decl_values.@"Panic.call");
27767 const panic_fn = try sema.analyzeNavVal(block, src, panic_func.owner_nav);
27768 const null_stack_trace = Air.internedToRef(zcu.null_stack_trace);27729 const null_stack_trace = Air.internedToRef(zcu.null_stack_trace);
2776927730
27770 const opt_usize_ty = try pt.optionalType(.usize_type);27731 const opt_usize_ty = try pt.optionalType(.usize_type);
...@@ -27812,7 +27773,7 @@ fn safetyPanicUnwrapError(sema: *Sema, block: *Block, src: LazySrcLoc, err: Air....@@ -27812,7 +27773,7 @@ fn safetyPanicUnwrapError(sema: *Sema, block: *Block, src: LazySrcLoc, err: Air.
27812 if (!zcu.backendSupportsFeature(.panic_fn)) {27773 if (!zcu.backendSupportsFeature(.panic_fn)) {
27813 _ = try block.addNoOp(.trap);27774 _ = try block.addNoOp(.trap);
27814 } else {27775 } else {
27815 const panic_fn = try getPanicInnerFn(sema, block, src, "unwrapError");27776 const panic_fn = try getBuiltin(sema, src, .@"Panic.unwrapError");
27816 const err_return_trace = try sema.getErrorReturnTrace(block);27777 const err_return_trace = try sema.getErrorReturnTrace(block);
27817 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };27778 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
27818 try sema.callBuiltin(block, src, Air.internedToRef(panic_fn), .auto, &args, .@"safety check");27779 try sema.callBuiltin(block, src, Air.internedToRef(panic_fn), .auto, &args, .@"safety check");
...@@ -27829,7 +27790,7 @@ fn addSafetyCheckIndexOob(...@@ -27829,7 +27790,7 @@ fn addSafetyCheckIndexOob(
27829) !void {27790) !void {
27830 assert(!parent_block.isComptime());27791 assert(!parent_block.isComptime());
27831 const ok = try parent_block.addBinOp(cmp_op, index, len);27792 const ok = try parent_block.addBinOp(cmp_op, index, len);
27832 return addSafetyCheckCall(sema, parent_block, src, ok, "outOfBounds", &.{ index, len });27793 return addSafetyCheckCall(sema, parent_block, src, ok, .@"Panic.outOfBounds", &.{ index, len });
27833}27794}
2783427795
27835fn addSafetyCheckInactiveUnionField(27796fn addSafetyCheckInactiveUnionField(
...@@ -27841,7 +27802,7 @@ fn addSafetyCheckInactiveUnionField(...@@ -27841,7 +27802,7 @@ fn addSafetyCheckInactiveUnionField(
27841) !void {27802) !void {
27842 assert(!parent_block.isComptime());27803 assert(!parent_block.isComptime());
27843 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);27804 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);
27844 return addSafetyCheckCall(sema, parent_block, src, ok, "inactiveUnionField", &.{ active_tag, wanted_tag });27805 return addSafetyCheckCall(sema, parent_block, src, ok, .@"Panic.inactiveUnionField", &.{ active_tag, wanted_tag });
27845}27806}
2784627807
27847fn addSafetyCheckSentinelMismatch(27808fn addSafetyCheckSentinelMismatch(
...@@ -27882,7 +27843,7 @@ fn addSafetyCheckSentinelMismatch(...@@ -27882,7 +27843,7 @@ fn addSafetyCheckSentinelMismatch(
27882 break :ok try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel);27843 break :ok try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel);
27883 };27844 };
2788427845
27885 return addSafetyCheckCall(sema, parent_block, src, ok, "sentinelMismatch", &.{27846 return addSafetyCheckCall(sema, parent_block, src, ok, .@"Panic.sentinelMismatch", &.{
27886 expected_sentinel, actual_sentinel,27847 expected_sentinel, actual_sentinel,
27887 });27848 });
27888}27849}
...@@ -27892,7 +27853,7 @@ fn addSafetyCheckCall(...@@ -27892,7 +27853,7 @@ fn addSafetyCheckCall(
27892 parent_block: *Block,27853 parent_block: *Block,
27893 src: LazySrcLoc,27854 src: LazySrcLoc,
27894 ok: Air.Inst.Ref,27855 ok: Air.Inst.Ref,
27895 func_name: []const u8,27856 comptime func_decl: Zcu.BuiltinDecl,
27896 args: []const Air.Inst.Ref,27857 args: []const Air.Inst.Ref,
27897) !void {27858) !void {
27898 assert(!parent_block.isComptime());27859 assert(!parent_block.isComptime());
...@@ -27916,7 +27877,7 @@ fn addSafetyCheckCall(...@@ -27916,7 +27877,7 @@ fn addSafetyCheckCall(
27916 if (!zcu.backendSupportsFeature(.panic_fn)) {27877 if (!zcu.backendSupportsFeature(.panic_fn)) {
27917 _ = try fail_block.addNoOp(.trap);27878 _ = try fail_block.addNoOp(.trap);
27918 } else {27879 } else {
27919 const panic_fn = try getPanicInnerFn(sema, &fail_block, src, func_name);27880 const panic_fn = try getBuiltin(sema, src, func_decl);
27920 try sema.callBuiltin(&fail_block, src, Air.internedToRef(panic_fn), .auto, args, .@"safety check");27881 try sema.callBuiltin(&fail_block, src, Air.internedToRef(panic_fn), .auto, args, .@"safety check");
27921 }27882 }
2792227883
...@@ -27925,9 +27886,8 @@ fn addSafetyCheckCall(...@@ -27925,9 +27886,8 @@ fn addSafetyCheckCall(
2792527886
27926/// This does not set `sema.branch_hint`.27887/// This does not set `sema.branch_hint`.
27927fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Zcu.PanicId) CompileError!void {27888fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Zcu.PanicId) CompileError!void {
27928 const msg_nav_index = try sema.preparePanicId(block, src, panic_id);27889 const msg_val = try sema.preparePanicId(src, panic_id);
27929 const msg_inst = try sema.analyzeNavVal(block, src, msg_nav_index);27890 try sema.panicWithMsg(block, src, Air.internedToRef(msg_val), .@"safety check");
27930 try sema.panicWithMsg(block, src, msg_inst, .@"safety check");
27931}27891}
2793227892
27933fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {27893fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
...@@ -32524,6 +32484,19 @@ fn addTypeReferenceEntry(...@@ -32524,6 +32484,19 @@ fn addTypeReferenceEntry(
32524 try zcu.addTypeReference(sema.owner, referenced_type, src);32484 try zcu.addTypeReference(sema.owner, referenced_type, src);
32525}32485}
3252632486
32487fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.MemoizedStateStage) SemaError!void {
32488 const pt = sema.pt;
32489
32490 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
32491 try sema.addReferenceEntry(src, unit);
32492 try sema.declareDependency(.{ .memoized_state = stage });
32493
32494 if (pt.zcu.analysis_in_progress.contains(unit)) {
32495 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(src, "dependency loop detected", .{}));
32496 }
32497 try pt.ensureMemoizedStateUpToDate(stage);
32498}
32499
32527pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void {32500pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void {
32528 const pt = sema.pt;32501 const pt = sema.pt;
32529 const zcu = pt.zcu;32502 const zcu = pt.zcu;
...@@ -33373,7 +33346,7 @@ fn analyzeSlice(...@@ -33373,7 +33346,7 @@ fn analyzeSlice(
33373 assert(!block.isComptime());33346 assert(!block.isComptime());
33374 try sema.requireRuntimeBlock(block, src, runtime_src.?);33347 try sema.requireRuntimeBlock(block, src, runtime_src.?);
33375 const ok = try block.addBinOp(.cmp_lte, start, end);33348 const ok = try block.addBinOp(.cmp_lte, start, end);
33376 try sema.addSafetyCheckCall(block, src, ok, "startGreaterThanEnd", &.{ start, end });33349 try sema.addSafetyCheckCall(block, src, ok, .@"Panic.startGreaterThanEnd", &.{ start, end });
33377 }33350 }
33378 const new_len = if (by_length)33351 const new_len = if (by_length)
33379 try sema.coerce(block, Type.usize, uncasted_end_opt, end_src)33352 try sema.coerce(block, Type.usize, uncasted_end_opt, end_src)
...@@ -35493,7 +35466,7 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void...@@ -35493,7 +35466,7 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void
35493 }35466 }
35494}35467}
3549535468
35496pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {35469pub fn resolveFnTypes(sema: *Sema, fn_ty: Type, src: LazySrcLoc) CompileError!void {
35497 const pt = sema.pt;35470 const pt = sema.pt;
35498 const zcu = pt.zcu;35471 const zcu = pt.zcu;
35499 const ip = &zcu.intern_pool;35472 const ip = &zcu.intern_pool;
...@@ -35505,7 +35478,7 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {...@@ -35505,7 +35478,7 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
35505 Type.fromInterned(fn_ty_info.return_type).isError(zcu))35478 Type.fromInterned(fn_ty_info.return_type).isError(zcu))
35506 {35479 {
35507 // Ensure the type exists so that backends can assume that.35480 // Ensure the type exists so that backends can assume that.
35508 _ = try sema.getBuiltinType("StackTrace");35481 _ = try sema.getBuiltinType(src, .StackTrace);
35509 }35482 }
3551035483
35511 for (0..fn_ty_info.param_types.len) |i| {35484 for (0..fn_ty_info.param_types.len) |i| {
...@@ -37550,7 +37523,7 @@ pub fn analyzeAsAddressSpace(...@@ -37550,7 +37523,7 @@ pub fn analyzeAsAddressSpace(
37550) !std.builtin.AddressSpace {37523) !std.builtin.AddressSpace {
37551 const pt = sema.pt;37524 const pt = sema.pt;
37552 const zcu = pt.zcu;37525 const zcu = pt.zcu;
37553 const addrspace_ty = try sema.getBuiltinType("AddressSpace");37526 const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
37554 const coerced = try sema.coerce(block, addrspace_ty, air_ref, src);37527 const coerced = try sema.coerce(block, addrspace_ty, air_ref, src);
37555 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ .simple = .@"addrspace" });37528 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ .simple = .@"addrspace" });
37556 const address_space = zcu.toEnum(std.builtin.AddressSpace, addrspace_val);37529 const address_space = zcu.toEnum(std.builtin.AddressSpace, addrspace_val);
...@@ -38747,69 +38720,15 @@ const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadR...@@ -38747,69 +38720,15 @@ const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadR
38747const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;38720const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;
38748const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult;38721const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult;
3874938722
38750fn getPanicInnerFn(38723pub fn getBuiltinType(sema: *Sema, src: LazySrcLoc, comptime decl: Zcu.BuiltinDecl) SemaError!Type {
38751 sema: *Sema,38724 comptime assert(decl.kind() == .type);
38752 block: *Block,38725 try sema.ensureMemoizedStateResolved(src, decl.stage());
38753 src: LazySrcLoc,38726 return .fromInterned(@field(sema.pt.zcu.builtin_decl_values, @tagName(decl)));
38754 inner_name: []const u8,
38755) !InternPool.Index {
38756 const gpa = sema.gpa;
38757 const pt = sema.pt;
38758 const zcu = pt.zcu;
38759 const ip = &zcu.intern_pool;
38760 const outer_ty = try sema.getBuiltinType("Panic");
38761 const inner_name_ip = try ip.getOrPutString(gpa, pt.tid, inner_name, .no_embedded_nulls);
38762 const opt_fn_ref = try namespaceLookupVal(sema, block, src, outer_ty.getNamespaceIndex(zcu), inner_name_ip);
38763 const fn_ref = opt_fn_ref orelse return sema.fail(block, src, "std.builtin.Panic missing {s}", .{inner_name});
38764 const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{ .simple = .panic_handler });
38765 if (fn_val.typeOf(zcu).zigTypeTag(zcu) != .@"fn") {
38766 return sema.fail(block, src, "std.builtin.Panic.{s} is not a function", .{inner_name});
38767 }
38768 // Better not to queue up function body analysis because the function might be generic, and
38769 // the semantic analysis for the call will already queue if necessary.
38770 return fn_val.toIntern();
38771}
38772
38773fn getBuiltinType(sema: *Sema, name: []const u8) SemaError!Type {
38774 const pt = sema.pt;
38775 const ty_inst = try sema.getBuiltin(name);
38776 const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt"));
38777 try ty.resolveFully(pt);
38778 return ty;
38779}
38780
38781fn getBuiltinInnerType(
38782 sema: *Sema,
38783 block: *Block,
38784 src: LazySrcLoc,
38785 outer_ty: Type,
38786 /// Relative to "std.builtin".
38787 compile_error_parent_name: []const u8,
38788 inner_name: []const u8,
38789) !Type {
38790 const pt = sema.pt;
38791 const zcu = pt.zcu;
38792 const ip = &zcu.intern_pool;
38793 const gpa = sema.gpa;
38794 const inner_name_ip = try ip.getOrPutString(gpa, pt.tid, inner_name, .no_embedded_nulls);
38795 const opt_nav = try sema.namespaceLookup(block, src, outer_ty.getNamespaceIndex(zcu), inner_name_ip);
38796 const nav = opt_nav orelse return sema.fail(block, src, "std.builtin.{s} missing {s}", .{
38797 compile_error_parent_name, inner_name,
38798 });
38799 try sema.ensureNavResolved(src, nav, .fully);
38800 const val = Value.fromInterned(ip.getNav(nav).status.fully_resolved.val);
38801 const ty = val.toType();
38802 try ty.resolveFully(pt);
38803 return ty;
38804}38727}
3880538728pub fn getBuiltin(sema: *Sema, src: LazySrcLoc, comptime decl: Zcu.BuiltinDecl) SemaError!InternPool.Index {
38806fn getBuiltin(sema: *Sema, name: []const u8) SemaError!Air.Inst.Ref {38729 comptime assert(decl.kind() != .type);
38807 const pt = sema.pt;38730 try sema.ensureMemoizedStateResolved(src, decl.stage());
38808 const zcu = pt.zcu;38731 return @field(sema.pt.zcu.builtin_decl_values, @tagName(decl));
38809 const ip = &zcu.intern_pool;
38810 const nav = try pt.getBuiltinNav(name);
38811 try pt.ensureNavValUpToDate(nav);
38812 return Air.internedToRef(ip.getNav(nav).status.fully_resolved.val);
38813}38732}
3881438733
38815pub const NavPtrModifiers = struct {38734pub const NavPtrModifiers = struct {
...@@ -38877,3 +38796,77 @@ pub fn resolveNavPtrModifiers(...@@ -38877,3 +38796,77 @@ pub fn resolveNavPtrModifiers(
38877 .@"addrspace" = @"addrspace",38796 .@"addrspace" = @"addrspace",
38878 };38797 };
38879}38798}
38799
38800pub fn analyzeMemoizedState(sema: *Sema, block: *Block, src: LazySrcLoc, builtin_namespace: InternPool.NamespaceIndex, stage: InternPool.MemoizedStateStage) CompileError!bool {
38801 const pt = sema.pt;
38802 const zcu = pt.zcu;
38803 const ip = &zcu.intern_pool;
38804 const gpa = zcu.gpa;
38805
38806 var any_changed = false;
38807
38808 inline for (comptime std.enums.values(Zcu.BuiltinDecl)) |builtin_decl| {
38809 if (stage == comptime builtin_decl.stage()) {
38810 const parent_ns: Zcu.Namespace.Index, const parent_name: []const u8, const name: []const u8 = switch (comptime builtin_decl.access()) {
38811 .direct => |name| .{ builtin_namespace, "std.builtin", name },
38812 .nested => |nested| access: {
38813 const parent_ty: Type = .fromInterned(@field(zcu.builtin_decl_values, @tagName(nested[0])));
38814 const parent_ns = parent_ty.getNamespace(zcu).unwrap() orelse {
38815 return sema.fail(block, src, "std.builtin.{s} is not a container type", .{@tagName(nested[0])});
38816 };
38817 break :access .{ parent_ns, "std.builtin." ++ @tagName(nested[0]), nested[1] };
38818 },
38819 };
38820
38821 const name_nts = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
38822 const result = try sema.namespaceLookupVal(block, src, parent_ns, name_nts) orelse
38823 return sema.fail(block, src, "{s} missing {s}", .{ parent_name, name });
38824
38825 const val = try sema.resolveConstDefinedValue(block, src, result, null);
38826
38827 switch (builtin_decl.kind()) {
38828 .type => if (val.typeOf(zcu).zigTypeTag(zcu) != .type) {
38829 return sema.fail(block, src, "{s}.{s} is not a type", .{ parent_name, name });
38830 } else {
38831 try val.toType().resolveFully(pt);
38832 },
38833 .func => if (val.typeOf(zcu).zigTypeTag(zcu) != .@"fn") {
38834 return sema.fail(block, src, "{s}.{s} is not a function", .{ parent_name, name });
38835 },
38836 .string => {
38837 const ty = val.typeOf(zcu);
38838 if (!ty.isSinglePointer(zcu) or
38839 !ty.isConstPtr(zcu) or
38840 ty.childType(zcu).zigTypeTag(zcu) != .array or
38841 ty.childType(zcu).childType(zcu).toIntern() != .u8_type)
38842 {
38843 return sema.fail(block, src, "{s}.{s} is not a valid string", .{ parent_name, name });
38844 }
38845 },
38846 }
38847
38848 const prev = @field(zcu.builtin_decl_values, @tagName(builtin_decl));
38849 if (val.toIntern() != prev) {
38850 @field(zcu.builtin_decl_values, @tagName(builtin_decl)) = val.toIntern();
38851 any_changed = true;
38852 }
38853 }
38854 }
38855
38856 if (stage == .panic) {
38857 // We use `getBuiltinType` because this is from an earlier stage.
38858 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
38859 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
38860 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
38861 const null_stack_trace = try pt.intern(.{ .opt = .{
38862 .ty = opt_ptr_stack_trace_ty.toIntern(),
38863 .val = .none,
38864 } });
38865 if (null_stack_trace != zcu.null_stack_trace) {
38866 zcu.null_stack_trace = null_stack_trace;
38867 any_changed = true;
38868 }
38869 }
38870
38871 return any_changed;
38872}
src/Zcu.zig+211-6
...@@ -217,15 +217,212 @@ all_type_references: std.ArrayListUnmanaged(TypeReference) = .empty,...@@ -217,15 +217,212 @@ all_type_references: std.ArrayListUnmanaged(TypeReference) = .empty,
217/// Freelist of indices in `all_type_references`.217/// Freelist of indices in `all_type_references`.
218free_type_references: std.ArrayListUnmanaged(u32) = .empty,218free_type_references: std.ArrayListUnmanaged(u32) = .empty,
219219
220panic_messages: [PanicId.len]InternPool.Nav.Index.Optional = .{.none} ** PanicId.len,220/// Populated by analysis of `AnalUnit.wrap(.{ .memoized_state = s })`, where `s` depends on the field.
221/// The panic function body.221builtin_decl_values: BuiltinDecl.Memoized = .{},
222panic_func_index: InternPool.Index = .none,222/// Populated by analysis of `AnalUnit.wrap(.{ .memoized_state = .panic })`.
223null_stack_trace: InternPool.Index = .none,223null_stack_trace: InternPool.Index = .none,
224224
225generation: u32 = 0,225generation: u32 = 0,
226226
227pub const PerThread = @import("Zcu/PerThread.zig");227pub 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
229pub const PanicId = enum {426pub const PanicId = enum {
230 reached_unreachable,427 reached_unreachable,
231 unwrap_null,428 unwrap_null,
...@@ -247,8 +444,6 @@ pub const PanicId = enum {...@@ -247,8 +444,6 @@ pub const PanicId = enum {
247 memcpy_len_mismatch,444 memcpy_len_mismatch,
248 memcpy_alias,445 memcpy_alias,
249 noreturn_returned,446 noreturn_returned,
250
251 pub const len = @typeInfo(PanicId).@"enum".fields.len;
252};447};
253448
254pub const GlobalErrorSet = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void);449pub const GlobalErrorSet = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void);
...@@ -2454,6 +2649,7 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {...@@ -2454,6 +2649,7 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
2454 .nav_ty => |nav| try zcu.markPoDependeeUpToDate(.{ .nav_ty = nav }),2649 .nav_ty => |nav| try zcu.markPoDependeeUpToDate(.{ .nav_ty = nav }),
2455 .type => |ty| try zcu.markPoDependeeUpToDate(.{ .interned = ty }),2650 .type => |ty| try zcu.markPoDependeeUpToDate(.{ .interned = ty }),
2456 .func => |func| try zcu.markPoDependeeUpToDate(.{ .interned = func }),2651 .func => |func| try zcu.markPoDependeeUpToDate(.{ .interned = func }),
2652 .memoized_state => |stage| try zcu.markPoDependeeUpToDate(.{ .memoized_state = stage }),
2457 }2653 }
2458 }2654 }
2459}2655}
...@@ -2468,6 +2664,7 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni...@@ -2468,6 +2664,7 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni
2468 .nav_ty => |nav| .{ .nav_ty = nav },2664 .nav_ty => |nav| .{ .nav_ty = nav },
2469 .type => |ty| .{ .interned = ty },2665 .type => |ty| .{ .interned = ty },
2470 .func => |func_index| .{ .interned = func_index }, // IES2666 .func => |func_index| .{ .interned = func_index }, // IES
2667 .memoized_state => |stage| .{ .memoized_state = stage },
2471 };2668 };
2472 log.debug("potentially outdated dependee: {}", .{zcu.fmtDependee(dependee)});2669 log.debug("potentially outdated dependee: {}", .{zcu.fmtDependee(dependee)});
2473 var it = ip.dependencyIterator(dependee);2670 var it = ip.dependencyIterator(dependee);
...@@ -2553,6 +2750,12 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {...@@ -2553,6 +2750,12 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
2553 .type => |ty| .{ .interned = ty },2750 .type => |ty| .{ .interned = ty },
2554 .nav_val => |nav| .{ .nav_val = nav },2751 .nav_val => |nav| .{ .nav_val = nav },
2555 .nav_ty => |nav| .{ .nav_ty = nav },2752 .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 },
2556 });2759 });
2557 while (it.next()) |_| n += 1;2760 while (it.next()) |_| n += 1;
25582761
...@@ -3462,7 +3665,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv...@@ -3462,7 +3665,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
3462 const other: AnalUnit = .wrap(switch (unit.unwrap()) {3665 const other: AnalUnit = .wrap(switch (unit.unwrap()) {
3463 .nav_val => |n| .{ .nav_ty = n },3666 .nav_val => |n| .{ .nav_ty = n },
3464 .nav_ty => |n| .{ .nav_val = n },3667 .nav_ty => |n| .{ .nav_val = n },
3465 .@"comptime", .type, .func => break :queue_paired,3668 .@"comptime", .type, .func, .memoized_state => break :queue_paired,
3466 });3669 });
3467 if (result.contains(other)) break :queue_paired;3670 if (result.contains(other)) break :queue_paired;
3468 try unit_queue.put(gpa, other, kv.value); // same reference location3671 try unit_queue.put(gpa, other, kv.value); // same reference location
...@@ -3597,6 +3800,7 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co...@@ -3597,6 +3800,7 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co
3597 const nav = zcu.funcInfo(func).owner_nav;3800 const nav = zcu.funcInfo(func).owner_nav;
3598 return writer.print("func('{}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(func) });3801 return writer.print("func('{}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(func) });
3599 },3802 },
3803 .memoized_state => return writer.writeAll("memoized_state"),
3600 }3804 }
3601}3805}
3602fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {3806fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
...@@ -3642,6 +3846,7 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com...@@ -3642,6 +3846,7 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com
3642 const file_path = zcu.fileByIndex(info.file).sub_file_path;3846 const file_path = zcu.fileByIndex(info.file).sub_file_path;
3643 return writer.print("namespace('{s}', %{d}, '{}')", .{ file_path, @intFromEnum(info.inst), k.name.fmt(ip) });3847 return writer.print("namespace('{s}', %{d}, '{}')", .{ file_path, @intFromEnum(info.inst), k.name.fmt(ip) });
3644 },3848 },
3849 .memoized_state => return writer.writeAll("memoized_state"),
3645 }3850 }
3646}3851}
36473852
src/Zcu/PerThread.zig+142-18
...@@ -560,6 +560,147 @@ pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.Sem...@@ -560,6 +560,147 @@ pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.Sem
560 return pt.semaFile(file_index);560 return pt.semaFile(file_index);
561}561}
562562
563/// Ensures that all memoized state on `Zcu` is up-to-date, performing re-analysis if necessary.
564/// Returns `error.AnalysisFail` if an analysis error is encountered; the caller is free to ignore
565/// this, since the error is already registered, but it must not use the value of memoized fields.
566pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) Zcu.SemaError!void {
567 const tracy = trace(@src());
568 defer tracy.end();
569
570 const zcu = pt.zcu;
571 const gpa = zcu.gpa;
572
573 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
574
575 log.debug("ensureMemoizedStateUpToDate", .{});
576
577 assert(!zcu.analysis_in_progress.contains(unit));
578
579 const was_outdated = zcu.outdated.swapRemove(unit) or zcu.potentially_outdated.swapRemove(unit);
580 const prev_failed = zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit);
581
582 if (was_outdated) {
583 dev.check(.incremental);
584 _ = zcu.outdated_ready.swapRemove(unit);
585 // No need for `deleteUnitExports` because we never export anything.
586 zcu.deleteUnitReferences(unit);
587 if (zcu.failed_analysis.fetchSwapRemove(unit)) |kv| {
588 kv.value.destroy(gpa);
589 }
590 _ = zcu.transitive_failed_analysis.swapRemove(unit);
591 } else {
592 if (prev_failed) return error.AnalysisFail;
593 // We use an arbitrary field to check if the state has been resolved yet.
594 const val = switch (stage) {
595 .main => zcu.builtin_decl_values.Type,
596 .panic => zcu.builtin_decl_values.Panic,
597 .va_list => zcu.builtin_decl_values.VaList,
598 };
599 if (val != .none) return;
600 }
601
602 const any_changed: bool, const new_failed: bool = if (pt.analyzeMemoizedState(stage)) |any_changed|
603 .{ any_changed or prev_failed, false }
604 else |err| switch (err) {
605 error.AnalysisFail => res: {
606 if (!zcu.failed_analysis.contains(unit)) {
607 // If this unit caused the error, it would have an entry in `failed_analysis`.
608 // Since it does not, this must be a transitive failure.
609 try zcu.transitive_failed_analysis.put(gpa, unit, {});
610 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(unit)});
611 }
612 break :res .{ !prev_failed, true };
613 },
614 error.OutOfMemory => {
615 // TODO: same as for `ensureComptimeUnitUpToDate` etc
616 return error.OutOfMemory;
617 },
618 error.GenericPoison => unreachable,
619 error.ComptimeReturn => unreachable,
620 error.ComptimeBreak => unreachable,
621 };
622
623 if (was_outdated) {
624 const dependee: InternPool.Dependee = .{ .memoized_state = stage };
625 if (any_changed) {
626 try zcu.markDependeeOutdated(.marked_po, dependee);
627 } else {
628 try zcu.markPoDependeeUpToDate(dependee);
629 }
630 }
631
632 if (new_failed) return error.AnalysisFail;
633}
634
635fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) Zcu.CompileError!bool {
636 const zcu = pt.zcu;
637 const ip = &zcu.intern_pool;
638 const gpa = zcu.gpa;
639
640 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
641
642 try zcu.analysis_in_progress.put(gpa, unit, {});
643 defer assert(zcu.analysis_in_progress.swapRemove(unit));
644
645 // Before we begin, collect:
646 // * The type `std`, and its namespace
647 // * The type `std.builtin`, and its namespace
648 // * A semi-reasonable source location
649 const std_file_imported = pt.importPkg(zcu.std_mod) catch return error.AnalysisFail;
650 try pt.ensureFileAnalyzed(std_file_imported.file_index);
651 const std_type: Type = .fromInterned(zcu.fileRootType(std_file_imported.file_index));
652 const std_namespace = std_type.getNamespaceIndex(zcu);
653 try pt.ensureNamespaceUpToDate(std_namespace);
654 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
655 const builtin_nav = zcu.namespacePtr(std_namespace).pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse
656 @panic("lib/std.zig is corrupt and missing 'builtin'");
657 try pt.ensureNavValUpToDate(builtin_nav);
658 const builtin_type: Type = .fromInterned(ip.getNav(builtin_nav).status.fully_resolved.val);
659 const builtin_namespace = builtin_type.getNamespaceIndex(zcu);
660 try pt.ensureNamespaceUpToDate(builtin_namespace);
661 const src: Zcu.LazySrcLoc = .{
662 .base_node_inst = builtin_type.typeDeclInst(zcu).?,
663 .offset = .entire_file,
664 };
665
666 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
667 defer analysis_arena.deinit();
668
669 var comptime_err_ret_trace: std.ArrayList(Zcu.LazySrcLoc) = .init(gpa);
670 defer comptime_err_ret_trace.deinit();
671
672 var sema: Sema = .{
673 .pt = pt,
674 .gpa = gpa,
675 .arena = analysis_arena.allocator(),
676 .code = .{ .instructions = .empty, .string_bytes = &.{}, .extra = &.{} },
677 .owner = unit,
678 .func_index = .none,
679 .func_is_naked = false,
680 .fn_ret_ty = .void,
681 .fn_ret_ty_ies = null,
682 .comptime_err_ret_trace = &comptime_err_ret_trace,
683 };
684 defer sema.deinit();
685
686 var block: Sema.Block = .{
687 .parent = null,
688 .sema = &sema,
689 .namespace = std_namespace,
690 .instructions = .{},
691 .inlining = null,
692 .comptime_reason = .{ .reason = .{
693 .src = src,
694 .r = .{ .simple = .type },
695 } },
696 .src_base_inst = src.base_node_inst,
697 .type_name_ctx = .empty,
698 };
699 defer block.instructions.deinit(gpa);
700
701 return sema.analyzeMemoizedState(&block, src, builtin_namespace, stage);
702}
703
563/// Ensures that the state of the given `ComptimeUnit` is fully up-to-date, performing re-analysis704/// Ensures that the state of the given `ComptimeUnit` is fully up-to-date, performing re-analysis
564/// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is705/// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is
565/// free to ignore this, since the error is already registered.706/// free to ignore this, since the error is already registered.
...@@ -2615,7 +2756,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -2615,7 +2756,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
2615 // result in circular dependency errors.2756 // result in circular dependency errors.
2616 // TODO: this can go away once we fix backends having to resolve `StackTrace`.2757 // TODO: this can go away once we fix backends having to resolve `StackTrace`.
2617 // The codegen timing guarantees that the parameter types will be populated.2758 // The codegen timing guarantees that the parameter types will be populated.
2618 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {2759 sema.resolveFnTypes(fn_ty, inner_block.nodeOffset(0)) catch |err| switch (err) {
2619 error.GenericPoison => unreachable,2760 error.GenericPoison => unreachable,
2620 error.ComptimeReturn => unreachable,2761 error.ComptimeReturn => unreachable,
2621 error.ComptimeBreak => unreachable,2762 error.ComptimeBreak => unreachable,
...@@ -3471,23 +3612,6 @@ pub fn structPackedFieldBitOffset(...@@ -3471,23 +3612,6 @@ pub fn structPackedFieldBitOffset(
3471 unreachable; // index out of bounds3612 unreachable; // index out of bounds
3472}3613}
34733614
3474pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.Nav.Index {
3475 const zcu = pt.zcu;
3476 const gpa = zcu.gpa;
3477 const ip = &zcu.intern_pool;
3478 const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
3479 const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
3480 const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).unwrap().?);
3481 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
3482 const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse
3483 @panic("lib/std.zig is corrupt and missing 'builtin'");
3484 pt.ensureNavValUpToDate(builtin_nav) catch @panic("std.builtin is corrupt");
3485 const builtin_type = Type.fromInterned(ip.getNav(builtin_nav).status.fully_resolved.val);
3486 const builtin_namespace = zcu.namespacePtr(builtin_type.getNamespace(zcu).unwrap() orelse @panic("std.builtin is corrupt"));
3487 const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
3488 return builtin_namespace.pub_decls.getKeyAdapted(name_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
3489}
3490
3491pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Error!Type {3615pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Error!Type {
3492 const zcu = pt.zcu;3616 const zcu = pt.zcu;
3493 const ip = &zcu.intern_pool;3617 const ip = &zcu.intern_pool;
src/codegen/llvm.zig+7-5
...@@ -5754,10 +5754,12 @@ pub const FuncGen = struct {...@@ -5754,10 +5754,12 @@ pub const FuncGen = struct {
5754 const o = fg.ng.object;5754 const o = fg.ng.object;
5755 const zcu = o.pt.zcu;5755 const zcu = o.pt.zcu;
5756 const ip = &zcu.intern_pool;5756 const ip = &zcu.intern_pool;
5757 const msg_nav_index = zcu.panic_messages[@intFromEnum(panic_id)].unwrap().?;5757 const panic_msg_val: InternPool.Index = switch (panic_id) {
5758 const msg_nav = ip.getNav(msg_nav_index);5758 inline else => |ct_panic_id| @field(zcu.builtin_decl_values, "Panic.messages." ++ @tagName(ct_panic_id)),
5759 const msg_len = Type.fromInterned(msg_nav.typeOf(ip)).childType(zcu).arrayLen(zcu);5759 };
5760 const msg_ptr = try o.lowerValue(msg_nav.status.fully_resolved.val);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);
5761 const null_opt_addr_global = try fg.resolveNullOptUsize();5763 const null_opt_addr_global = try fg.resolveNullOptUsize();
5762 const target = zcu.getTarget();5764 const target = zcu.getTarget();
5763 const llvm_usize = try o.lowerType(Type.usize);5765 const llvm_usize = try o.lowerType(Type.usize);
...@@ -5768,7 +5770,7 @@ pub const FuncGen = struct {...@@ -5768,7 +5770,7 @@ pub const FuncGen = struct {
5768 // ptr null, ; stack trace5770 // ptr null, ; stack trace
5769 // ptr @2, ; addr (null ?usize)5771 // ptr @2, ; addr (null ?usize)
5770 // )5772 // )
5771 const panic_func = zcu.funcInfo(zcu.panic_func_index);5773 const panic_func = zcu.funcInfo(zcu.builtin_decl_values.@"Panic.call");
5772 const panic_nav = ip.getNav(panic_func.owner_nav);5774 const panic_nav = ip.getNav(panic_func.owner_nav);
5773 const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?;5775 const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?;
5774 const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav);5776 const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav);