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

Merge pull request #22403 from mlugg/incremental

incremental: fixes

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

lib/std/zig/Zir.zig+32
...@@ -5066,3 +5066,35 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {...@@ -5066,3 +5066,35 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {
5066 else => unreachable, // assertion failure; not trackable5066 else => unreachable, // assertion failure; not trackable
5067 }5067 }
5068}5068}
5069
5070pub fn typeCapturesLen(zir: Zir, type_decl: Inst.Index) u32 {
5071 const inst = zir.instructions.get(@intFromEnum(type_decl));
5072 assert(inst.tag == .extended);
5073 switch (inst.data.extended.opcode) {
5074 .struct_decl => {
5075 const small: Inst.StructDecl.Small = @bitCast(inst.data.extended.small);
5076 if (!small.has_captures_len) return 0;
5077 const extra = zir.extraData(Inst.StructDecl, inst.data.extended.operand);
5078 return zir.extra[extra.end];
5079 },
5080 .union_decl => {
5081 const small: Inst.UnionDecl.Small = @bitCast(inst.data.extended.small);
5082 if (!small.has_captures_len) return 0;
5083 const extra = zir.extraData(Inst.UnionDecl, inst.data.extended.operand);
5084 return zir.extra[extra.end + @intFromBool(small.has_tag_type)];
5085 },
5086 .enum_decl => {
5087 const small: Inst.EnumDecl.Small = @bitCast(inst.data.extended.small);
5088 if (!small.has_captures_len) return 0;
5089 const extra = zir.extraData(Inst.EnumDecl, inst.data.extended.operand);
5090 return zir.extra[extra.end + @intFromBool(small.has_tag_type)];
5091 },
5092 .opaque_decl => {
5093 const small: Inst.OpaqueDecl.Small = @bitCast(inst.data.extended.small);
5094 if (!small.has_captures_len) return 0;
5095 const extra = zir.extraData(Inst.OpaqueDecl, inst.data.extended.operand);
5096 return zir.extra[extra.end];
5097 },
5098 else => unreachable,
5099 }
5100}
src/Compilation.zig+16-10
...@@ -3158,16 +3158,19 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -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+66-9
...@@ -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) {
...@@ -2029,15 +2084,7 @@ pub const Key = union(enum) {...@@ -2029,15 +2084,7 @@ pub const Key = union(enum) {
2029 pub const NamespaceType = union(enum) {2084 pub const NamespaceType = union(enum) {
2030 /// This type corresponds to an actual source declaration, e.g. `struct { ... }`.2085 /// This type corresponds to an actual source declaration, e.g. `struct { ... }`.
2031 /// It is hashed based on its ZIR instruction index and set of captures.2086 /// It is hashed based on its ZIR instruction index and set of captures.
2032 declared: struct {2087 declared: Declared,
2033 /// A `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl` instruction.
2034 zir_index: TrackedInst.Index,
2035 /// The captured values of this type. These values must be fully resolved per the language spec.
2036 captures: union(enum) {
2037 owned: CaptureValue.Slice,
2038 external: []const CaptureValue,
2039 },
2040 },
2041 /// This type is an automatically-generated enum tag type for a union.2088 /// This type is an automatically-generated enum tag type for a union.
2042 /// It is hashed based on the index of the union type it corresponds to.2089 /// It is hashed based on the index of the union type it corresponds to.
2043 generated_tag: struct {2090 generated_tag: struct {
...@@ -2053,6 +2100,16 @@ pub const Key = union(enum) {...@@ -2053,6 +2100,16 @@ pub const Key = union(enum) {
2053 /// A hash of this type's attributes, fields, etc, generated by Sema.2100 /// A hash of this type's attributes, fields, etc, generated by Sema.
2054 type_hash: u64,2101 type_hash: u64,
2055 },2102 },
2103
2104 pub const Declared = struct {
2105 /// A `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl` instruction.
2106 zir_index: TrackedInst.Index,
2107 /// The captured values of this type. These values must be fully resolved per the language spec.
2108 captures: union(enum) {
2109 owned: CaptureValue.Slice,
2110 external: []const CaptureValue,
2111 },
2112 };
2056 };2113 };
20572114
2058 pub const FuncType = struct {2115 pub const FuncType = struct {
src/Sema.zig+210-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 {
...@@ -18172,7 +18174,9 @@ fn zirThis(...@@ -18172,7 +18174,9 @@ fn zirThis(
18172 _ = extended;18174 _ = extended;
18173 const pt = sema.pt;18175 const pt = sema.pt;
18174 const namespace = pt.zcu.namespacePtr(block.namespace);18176 const namespace = pt.zcu.namespacePtr(block.namespace);
18177
18175 const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);18178 const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
18179
18176 switch (pt.zcu.intern_pool.indexToKey(new_ty)) {18180 switch (pt.zcu.intern_pool.indexToKey(new_ty)) {
18177 .struct_type, .union_type, .enum_type => try sema.declareDependency(.{ .interned = new_ty }),18181 .struct_type, .union_type, .enum_type => try sema.declareDependency(.{ .interned = new_ty }),
18178 .opaque_type => {},18182 .opaque_type => {},
...@@ -18379,7 +18383,7 @@ fn zirBuiltinSrc(...@@ -18379,7 +18383,7 @@ fn zirBuiltinSrc(
18379 } });18383 } });
18380 };18384 };
1838118385
18382 const src_loc_ty = try sema.getBuiltinType("SourceLocation");18386 const src_loc_ty = try sema.getBuiltinType(block.nodeOffset(0), .SourceLocation);
18383 const fields = .{18387 const fields = .{
18384 // module: [:0]const u8,18388 // module: [:0]const u8,
18385 module_name_val,18389 module_name_val,
...@@ -18406,7 +18410,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18406,7 +18410,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18406 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;
18407 const src = block.nodeOffset(inst_data.src_node);18411 const src = block.nodeOffset(inst_data.src_node);
18408 const ty = try sema.resolveType(block, src, inst_data.operand);18412 const ty = try sema.resolveType(block, src, inst_data.operand);
18409 const type_info_ty = try sema.getBuiltinType("Type");18413 const type_info_ty = try sema.getBuiltinType(src, .Type);
18410 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;18414 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;
1841118415
18412 if (ty.typeDeclInst(zcu)) |type_decl_inst| {18416 if (ty.typeDeclInst(zcu)) |type_decl_inst| {
...@@ -18426,8 +18430,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18426,8 +18430,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18426 => |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),
1842718431
18428 .@"fn" => {18432 .@"fn" => {
18429 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");
18430 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");
1843118435
18432 const func_ty_info = zcu.typeToFunc(ty).?;18436 const func_ty_info = zcu.typeToFunc(ty).?;
18433 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);
...@@ -18497,7 +18501,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18497,7 +18501,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18497 func_ty_info.return_type,18501 func_ty_info.return_type,
18498 } });18502 } });
1849918503
18500 const callconv_ty = try sema.getBuiltinType("CallingConvention");18504 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
18501 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) {
18502 error.TypeMismatch => @panic("std.builtin is corrupt"),18506 error.TypeMismatch => @panic("std.builtin is corrupt"),
18503 error.OutOfMemory => |e| return e,18507 error.OutOfMemory => |e| return e,
...@@ -18525,8 +18529,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18525,8 +18529,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18525 })));18529 })));
18526 },18530 },
18527 .int => {18531 .int => {
18528 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");
18529 const signedness_ty = try sema.getBuiltinType("Signedness");18533 const signedness_ty = try sema.getBuiltinType(src, .Signedness);
18530 const info = ty.intInfo(zcu);18534 const info = ty.intInfo(zcu);
18531 const field_values = .{18535 const field_values = .{
18532 // signedness: Signedness,18536 // signedness: Signedness,
...@@ -18544,7 +18548,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18544,7 +18548,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18544 })));18548 })));
18545 },18549 },
18546 .float => {18550 .float => {
18547 const float_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Float");18551 const float_info_ty = try sema.getBuiltinType(src, .@"Type.Float");
1854818552
18549 const field_vals = .{18553 const field_vals = .{
18550 // bits: u16,18554 // bits: u16,
...@@ -18566,9 +18570,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18566,9 +18570,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18566 else18570 else
18567 try Type.fromInterned(info.child).lazyAbiAlignment(pt);18571 try Type.fromInterned(info.child).lazyAbiAlignment(pt);
1856818572
18569 const addrspace_ty = try sema.getBuiltinType("AddressSpace");18573 const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
18570 const pointer_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Pointer");18574 const pointer_ty = try sema.getBuiltinType(src, .@"Type.Pointer");
18571 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");
1857218576
18573 const field_values = .{18577 const field_values = .{
18574 // size: Size,18578 // size: Size,
...@@ -18601,7 +18605,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18601,7 +18605,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18601 })));18605 })));
18602 },18606 },
18603 .array => {18607 .array => {
18604 const array_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Array");18608 const array_field_ty = try sema.getBuiltinType(src, .@"Type.Array");
1860518609
18606 const info = ty.arrayInfo(zcu);18610 const info = ty.arrayInfo(zcu);
18607 const field_values = .{18611 const field_values = .{
...@@ -18622,7 +18626,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18622,7 +18626,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18622 })));18626 })));
18623 },18627 },
18624 .vector => {18628 .vector => {
18625 const vector_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Vector");18629 const vector_field_ty = try sema.getBuiltinType(src, .@"Type.Vector");
1862618630
18627 const info = ty.arrayInfo(zcu);18631 const info = ty.arrayInfo(zcu);
18628 const field_values = .{18632 const field_values = .{
...@@ -18641,7 +18645,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18641,7 +18645,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18641 })));18645 })));
18642 },18646 },
18643 .optional => {18647 .optional => {
18644 const optional_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Optional");18648 const optional_field_ty = try sema.getBuiltinType(src, .@"Type.Optional");
1864518649
18646 const field_values = .{18650 const field_values = .{
18647 // child: type,18651 // child: type,
...@@ -18658,7 +18662,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18658,7 +18662,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18658 },18662 },
18659 .error_set => {18663 .error_set => {
18660 // Get the Error type18664 // Get the Error type
18661 const error_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Error");18665 const error_field_ty = try sema.getBuiltinType(src, .@"Type.Error");
1866218666
18663 // Build our list of Error values18667 // Build our list of Error values
18664 // Optional value is only null if anyerror18668 // Optional value is only null if anyerror
...@@ -18754,7 +18758,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18754,7 +18758,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18754 })));18758 })));
18755 },18759 },
18756 .error_union => {18760 .error_union => {
18757 const error_union_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ErrorUnion");18761 const error_union_field_ty = try sema.getBuiltinType(src, .@"Type.ErrorUnion");
1875818762
18759 const field_values = .{18763 const field_values = .{
18760 // error_set: type,18764 // error_set: type,
...@@ -18774,7 +18778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18774,7 +18778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18774 .@"enum" => {18778 .@"enum" => {
18775 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);
1877618780
18777 const enum_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "EnumField");18781 const enum_field_ty = try sema.getBuiltinType(src, .@"Type.EnumField");
1877818782
18779 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);
18780 for (enum_field_vals, 0..) |*field_val, tag_index| {18784 for (enum_field_vals, 0..) |*field_val, tag_index| {
...@@ -18859,9 +18863,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18859,9 +18863,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18859 } });18863 } });
18860 };18864 };
1886118865
18862 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace.toOptional());18866 const decls_val = try sema.typeInfoDecls(block, src, ip.loadEnumType(ty.toIntern()).namespace.toOptional());
1886318867
18864 const type_enum_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Enum");18868 const type_enum_ty = try sema.getBuiltinType(src, .@"Type.Enum");
1886518869
18866 const field_values = .{18870 const field_values = .{
18867 // tag_type: type,18871 // tag_type: type,
...@@ -18883,8 +18887,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18883,8 +18887,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18883 })));18887 })));
18884 },18888 },
18885 .@"union" => {18889 .@"union" => {
18886 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");
18887 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");
1888818892
18889 try ty.resolveLayout(pt); // Getting alignment requires type layout18893 try ty.resolveLayout(pt); // Getting alignment requires type layout
18890 const union_obj = zcu.typeToUnion(ty).?;18894 const union_obj = zcu.typeToUnion(ty).?;
...@@ -18972,14 +18976,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18972,14 +18976,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18972 } });18976 } });
18973 };18977 };
1897418978
18975 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(zcu).toOptional());18979 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespaceIndex(zcu).toOptional());
1897618980
18977 const enum_tag_ty_val = try pt.intern(.{ .opt = .{18981 const enum_tag_ty_val = try pt.intern(.{ .opt = .{
18978 .ty = (try pt.optionalType(.type_type)).toIntern(),18982 .ty = (try pt.optionalType(.type_type)).toIntern(),
18979 .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,
18980 } });18984 } });
1898118985
18982 const container_layout_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ContainerLayout");18986 const container_layout_ty = try sema.getBuiltinType(src, .@"Type.ContainerLayout");
1898318987
18984 const field_values = .{18988 const field_values = .{
18985 // layout: ContainerLayout,18989 // layout: ContainerLayout,
...@@ -19002,8 +19006,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19002,8 +19006,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19002 })));19006 })));
19003 },19007 },
19004 .@"struct" => {19008 .@"struct" => {
19005 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");
19006 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");
1900719011
19008 try ty.resolveLayout(pt); // Getting alignment requires type layout19012 try ty.resolveLayout(pt); // Getting alignment requires type layout
1900919013
...@@ -19167,7 +19171,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19167,7 +19171,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19167 } });19171 } });
19168 };19172 };
1916919173
19170 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(zcu));19174 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespace(zcu));
1917119175
19172 const backing_integer_val = try pt.intern(.{ .opt = .{19176 const backing_integer_val = try pt.intern(.{ .opt = .{
19173 .ty = (try pt.optionalType(.type_type)).toIntern(),19177 .ty = (try pt.optionalType(.type_type)).toIntern(),
...@@ -19177,7 +19181,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19177,7 +19181,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19177 } else .none,19181 } else .none,
19178 } });19182 } });
1917919183
19180 const container_layout_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ContainerLayout");19184 const container_layout_ty = try sema.getBuiltinType(src, .@"Type.ContainerLayout");
1918119185
19182 const layout = ty.containerLayout(zcu);19186 const layout = ty.containerLayout(zcu);
1918319187
...@@ -19203,10 +19207,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19203,10 +19207,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19203 })));19207 })));
19204 },19208 },
19205 .@"opaque" => {19209 .@"opaque" => {
19206 const type_opaque_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Opaque");19210 const type_opaque_ty = try sema.getBuiltinType(src, .@"Type.Opaque");
1920719211
19208 try ty.resolveFields(pt);19212 try ty.resolveFields(pt);
19209 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(zcu));19213 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespace(zcu));
1921019214
19211 const field_values = .{19215 const field_values = .{
19212 // decls: []const Declaration,19216 // decls: []const Declaration,
...@@ -19230,14 +19234,13 @@ fn typeInfoDecls(...@@ -19230,14 +19234,13 @@ fn typeInfoDecls(
19230 sema: *Sema,19234 sema: *Sema,
19231 block: *Block,19235 block: *Block,
19232 src: LazySrcLoc,19236 src: LazySrcLoc,
19233 type_info_ty: Type,
19234 opt_namespace: InternPool.OptionalNamespaceIndex,19237 opt_namespace: InternPool.OptionalNamespaceIndex,
19235) CompileError!InternPool.Index {19238) CompileError!InternPool.Index {
19236 const pt = sema.pt;19239 const pt = sema.pt;
19237 const zcu = pt.zcu;19240 const zcu = pt.zcu;
19238 const gpa = sema.gpa;19241 const gpa = sema.gpa;
1923919242
19240 const declaration_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Declaration");19243 const declaration_ty = try sema.getBuiltinType(src, .@"Type.Declaration");
1924119244
19242 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);19245 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
19243 defer decl_vals.deinit();19246 defer decl_vals.deinit();
...@@ -20179,11 +20182,11 @@ fn retWithErrTracing(...@@ -20179,11 +20182,11 @@ fn retWithErrTracing(
20179 else => true,20182 else => true,
20180 };20183 };
20181 const gpa = sema.gpa;20184 const gpa = sema.gpa;
20182 const stack_trace_ty = try sema.getBuiltinType("StackTrace");20185 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
20183 try stack_trace_ty.resolveFields(pt);20186 try stack_trace_ty.resolveFields(pt);
20184 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);20187 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
20185 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);
20186 const return_err_fn = try sema.getBuiltin("returnError");20189 const return_err_fn = Air.internedToRef(try sema.getBuiltin(src, .returnError));
20187 const args: [1]Air.Inst.Ref = .{err_return_trace};20190 const args: [1]Air.Inst.Ref = .{err_return_trace};
2018820191
20189 if (!need_check) {20192 if (!need_check) {
...@@ -21605,7 +21608,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -21605,7 +21608,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
21605 const pt = sema.pt;21608 const pt = sema.pt;
21606 const zcu = pt.zcu;21609 const zcu = pt.zcu;
21607 const ip = &zcu.intern_pool;21610 const ip = &zcu.intern_pool;
21608 const stack_trace_ty = try sema.getBuiltinType("StackTrace");21611 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace);
21609 try stack_trace_ty.resolveFields(pt);21612 try stack_trace_ty.resolveFields(pt);
21610 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);21613 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
21611 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());
...@@ -21614,7 +21617,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -21614,7 +21617,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
21614 .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) {
21615 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);21618 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
21616 },21619 },
21617 .@"comptime", .nav_ty, .nav_val, .type => {},21620 .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {},
21618 }21621 }
21619 return Air.internedToRef(try pt.intern(.{ .opt = .{21622 return Air.internedToRef(try pt.intern(.{ .opt = .{
21620 .ty = opt_ptr_stack_trace_ty.toIntern(),21623 .ty = opt_ptr_stack_trace_ty.toIntern(),
...@@ -21894,7 +21897,7 @@ fn zirReify(...@@ -21894,7 +21897,7 @@ fn zirReify(
21894 },21897 },
21895 },21898 },
21896 };21899 };
21897 const type_info_ty = try sema.getBuiltinType("Type");21900 const type_info_ty = try sema.getBuiltinType(src, .Type);
21898 const uncasted_operand = try sema.resolveInst(extra.operand);21901 const uncasted_operand = try sema.resolveInst(extra.operand);
21899 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);
21900 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 });
...@@ -23154,7 +23157,7 @@ fn reifyStruct(...@@ -23154,7 +23157,7 @@ fn reifyStruct(
2315423157
23155fn 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 {
23156 const pt = sema.pt;23159 const pt = sema.pt;
23157 const va_list_ty = try sema.getBuiltinType("VaList");23160 const va_list_ty = try sema.getBuiltinType(src, .VaList);
23158 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);23161 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);
2315923162
23160 const inst = try sema.resolveInst(zir_ref);23163 const inst = try sema.resolveInst(zir_ref);
...@@ -23193,7 +23196,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)...@@ -23193,7 +23196,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
23193 const va_list_src = block.builtinCallArgSrc(extra.node, 0);23196 const va_list_src = block.builtinCallArgSrc(extra.node, 0);
2319423197
23195 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);
23196 const va_list_ty = try sema.getBuiltinType("VaList");23199 const va_list_ty = try sema.getBuiltinType(src, .VaList);
2319723200
23198 try sema.requireRuntimeBlock(block, src, null);23201 try sema.requireRuntimeBlock(block, src, null);
23199 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);
...@@ -23213,7 +23216,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -23213,7 +23216,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
23213fn 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 {
23214 const src = block.nodeOffset(@bitCast(extended.operand));23217 const src = block.nodeOffset(@bitCast(extended.operand));
2321523218
23216 const va_list_ty = try sema.getBuiltinType("VaList");23219 const va_list_ty = try sema.getBuiltinType(src, .VaList);
23217 try sema.requireRuntimeBlock(block, src, null);23220 try sema.requireRuntimeBlock(block, src, null);
23218 return block.addInst(.{23221 return block.addInst(.{
23219 .tag = .c_va_start,23222 .tag = .c_va_start,
...@@ -24819,7 +24822,7 @@ fn resolveExportOptions(...@@ -24819,7 +24822,7 @@ fn resolveExportOptions(
24819 const zcu = pt.zcu;24822 const zcu = pt.zcu;
24820 const gpa = sema.gpa;24823 const gpa = sema.gpa;
24821 const ip = &zcu.intern_pool;24824 const ip = &zcu.intern_pool;
24822 const export_options_ty = try sema.getBuiltinType("ExportOptions");24825 const export_options_ty = try sema.getBuiltinType(src, .ExportOptions);
24823 const air_ref = try sema.resolveInst(zir_ref);24826 const air_ref = try sema.resolveInst(zir_ref);
24824 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);
2482524828
...@@ -24869,15 +24872,15 @@ fn resolveBuiltinEnum(...@@ -24869,15 +24872,15 @@ fn resolveBuiltinEnum(
24869 block: *Block,24872 block: *Block,
24870 src: LazySrcLoc,24873 src: LazySrcLoc,
24871 zir_ref: Zir.Inst.Ref,24874 zir_ref: Zir.Inst.Ref,
24872 comptime name: []const u8,24875 comptime name: Zcu.BuiltinDecl,
24873 reason: ComptimeReason,24876 reason: ComptimeReason,
24874) CompileError!@field(std.builtin, name) {24877) CompileError!@field(std.builtin, @tagName(name)) {
24875 const pt = sema.pt;24878 const pt = sema.pt;
24876 const ty = try sema.getBuiltinType(name);24879 const ty = try sema.getBuiltinType(src, name);
24877 const air_ref = try sema.resolveInst(zir_ref);24880 const air_ref = try sema.resolveInst(zir_ref);
24878 const coerced = try sema.coerce(block, ty, air_ref, src);24881 const coerced = try sema.coerce(block, ty, air_ref, src);
24879 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);24882 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
24880 return pt.zcu.toEnum(@field(std.builtin, name), val);24883 return pt.zcu.toEnum(@field(std.builtin, @tagName(name)), val);
24881}24884}
2488224885
24883fn resolveAtomicOrder(24886fn resolveAtomicOrder(
...@@ -24887,7 +24890,7 @@ fn resolveAtomicOrder(...@@ -24887,7 +24890,7 @@ fn resolveAtomicOrder(
24887 zir_ref: Zir.Inst.Ref,24890 zir_ref: Zir.Inst.Ref,
24888 reason: ComptimeReason,24891 reason: ComptimeReason,
24889) CompileError!std.builtin.AtomicOrder {24892) CompileError!std.builtin.AtomicOrder {
24890 return sema.resolveBuiltinEnum(block, src, zir_ref, "AtomicOrder", reason);24893 return sema.resolveBuiltinEnum(block, src, zir_ref, .AtomicOrder, reason);
24891}24894}
2489224895
24893fn resolveAtomicRmwOp(24896fn resolveAtomicRmwOp(
...@@ -24896,7 +24899,7 @@ fn resolveAtomicRmwOp(...@@ -24896,7 +24899,7 @@ fn resolveAtomicRmwOp(
24896 src: LazySrcLoc,24899 src: LazySrcLoc,
24897 zir_ref: Zir.Inst.Ref,24900 zir_ref: Zir.Inst.Ref,
24898) CompileError!std.builtin.AtomicRmwOp {24901) CompileError!std.builtin.AtomicRmwOp {
24899 return sema.resolveBuiltinEnum(block, src, zir_ref, "AtomicRmwOp", .{ .simple = .operand_atomicRmw_operation });24902 return sema.resolveBuiltinEnum(block, src, zir_ref, .AtomicRmwOp, .{ .simple = .operand_atomicRmw_operation });
24900}24903}
2490124904
24902fn zirCmpxchg(24905fn zirCmpxchg(
...@@ -25076,7 +25079,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -25076,7 +25079,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
25076 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;
25077 const op_src = block.builtinCallArgSrc(inst_data.src_node, 0);25080 const op_src = block.builtinCallArgSrc(inst_data.src_node, 0);
25078 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 1);25081 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 1);
25079 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp", .{ .simple = .operand_reduce_operation });25082 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, .ReduceOp, .{ .simple = .operand_reduce_operation });
25080 const operand = try sema.resolveInst(extra.rhs);25083 const operand = try sema.resolveInst(extra.rhs);
25081 const operand_ty = sema.typeOf(operand);25084 const operand_ty = sema.typeOf(operand);
25082 const pt = sema.pt;25085 const pt = sema.pt;
...@@ -25666,7 +25669,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -25666,7 +25669,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
25666 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;
25667 const func = try sema.resolveInst(extra.callee);25670 const func = try sema.resolveInst(extra.callee);
2566825671
25669 const modifier_ty = try sema.getBuiltinType("CallModifier");25672 const modifier_ty = try sema.getBuiltinType(call_src, .CallModifier);
25670 const air_ref = try sema.resolveInst(extra.modifier);25673 const air_ref = try sema.resolveInst(extra.modifier);
25671 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);
25672 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 });
...@@ -26628,13 +26631,13 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -26628,13 +26631,13 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26628 const body = sema.code.bodySlice(extra_index, body_len);26631 const body = sema.code.bodySlice(extra_index, body_len);
26629 extra_index += body.len;26632 extra_index += body.len;
2663026633
26631 const cc_ty = try sema.getBuiltinType("CallingConvention");26634 const cc_ty = try sema.getBuiltinType(cc_src, .CallingConvention);
26632 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" });
26633 break :blk try sema.analyzeValueAsCallconv(block, cc_src, val);26636 break :blk try sema.analyzeValueAsCallconv(block, cc_src, val);
26634 } else if (extra.data.bits.has_cc_ref) blk: {26637 } else if (extra.data.bits.has_cc_ref) blk: {
26635 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]);
26636 extra_index += 1;26639 extra_index += 1;
26637 const cc_ty = try sema.getBuiltinType("CallingConvention");26640 const cc_ty = try sema.getBuiltinType(cc_src, .CallingConvention);
26638 const uncoerced_cc = try sema.resolveInst(cc_ref);26641 const uncoerced_cc = try sema.resolveInst(cc_ref);
26639 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);
26640 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" });
...@@ -26654,7 +26657,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -26654,7 +26657,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26654 // 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,
26655 // 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
26656 // because it does the exact `cCallingConvention` call we just did.)26659 // because it does the exact `cCallingConvention` call we just did.)
26657 const cc_type = try sema.getBuiltinType("CallingConvention");26660 const cc_type = try sema.getBuiltinType(cc_src, .CallingConvention);
26658 _ = try sema.namespaceLookupVal(26661 _ = try sema.namespaceLookupVal(
26659 block,26662 block,
26660 LazySrcLoc.unneeded,26663 LazySrcLoc.unneeded,
...@@ -26832,7 +26835,7 @@ fn resolvePrefetchOptions(...@@ -26832,7 +26835,7 @@ fn resolvePrefetchOptions(
26832 const zcu = pt.zcu;26835 const zcu = pt.zcu;
26833 const gpa = sema.gpa;26836 const gpa = sema.gpa;
26834 const ip = &zcu.intern_pool;26837 const ip = &zcu.intern_pool;
26835 const options_ty = try sema.getBuiltinType("PrefetchOptions");26838 const options_ty = try sema.getBuiltinType(src, .PrefetchOptions);
26836 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);
2683726840
26838 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 });
...@@ -26900,7 +26903,7 @@ fn resolveExternOptions(...@@ -26900,7 +26903,7 @@ fn resolveExternOptions(
26900 const gpa = sema.gpa;26903 const gpa = sema.gpa;
26901 const ip = &zcu.intern_pool;26904 const ip = &zcu.intern_pool;
26902 const options_inst = try sema.resolveInst(zir_ref);26905 const options_inst = try sema.resolveInst(zir_ref);
26903 const extern_options_ty = try sema.getBuiltinType("ExternOptions");26906 const extern_options_ty = try sema.getBuiltinType(src, .ExternOptions);
26904 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);
2690526908
26906 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 });
...@@ -27002,6 +27005,7 @@ fn zirBuiltinExtern(...@@ -27002,6 +27005,7 @@ fn zirBuiltinExtern(
27002 .zir_index = switch (sema.owner.unwrap()) {27005 .zir_index = switch (sema.owner.unwrap()) {
27003 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index,27006 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index,
27004 .type => |owner_ty| Type.fromInterned(owner_ty).typeDeclInst(zcu).?,27007 .type => |owner_ty| Type.fromInterned(owner_ty).typeDeclInst(zcu).?,
27008 .memoized_state => unreachable,
27005 .nav_ty, .nav_val => |nav| ip.getNav(nav).analysis.?.zir_index,27009 .nav_ty, .nav_val => |nav| ip.getNav(nav).analysis.?.zir_index,
27006 .func => |func| zir_index: {27010 .func => |func| zir_index: {
27007 const func_info = zcu.funcInfo(func);27011 const func_info = zcu.funcInfo(func);
...@@ -27079,23 +27083,25 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -27079,23 +27083,25 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
27079 const src = block.nodeOffset(@bitCast(extended.operand));27083 const src = block.nodeOffset(@bitCast(extended.operand));
27080 const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small);27084 const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small);
2708127085
27082 const type_name = switch (value) {27086 const ty = switch (value) {
27083 .atomic_order => "AtomicOrder",27087 // zig fmt: off
27084 .atomic_rmw_op => "AtomicRmwOp",27088 .atomic_order => try sema.getBuiltinType(src, .AtomicOrder),
27085 .calling_convention => "CallingConvention",27089 .atomic_rmw_op => try sema.getBuiltinType(src, .AtomicRmwOp),
27086 .address_space => "AddressSpace",27090 .calling_convention => try sema.getBuiltinType(src, .CallingConvention),
27087 .float_mode => "FloatMode",27091 .address_space => try sema.getBuiltinType(src, .AddressSpace),
27088 .reduce_op => "ReduceOp",27092 .float_mode => try sema.getBuiltinType(src, .FloatMode),
27089 .call_modifier => "CallModifier",27093 .reduce_op => try sema.getBuiltinType(src, .ReduceOp),
27090 .prefetch_options => "PrefetchOptions",27094 .call_modifier => try sema.getBuiltinType(src, .CallModifier),
27091 .export_options => "ExportOptions",27095 .prefetch_options => try sema.getBuiltinType(src, .PrefetchOptions),
27092 .extern_options => "ExternOptions",27096 .export_options => try sema.getBuiltinType(src, .ExportOptions),
27093 .type_info => "Type",27097 .extern_options => try sema.getBuiltinType(src, .ExternOptions),
27094 .branch_hint => "BranchHint",27098 .type_info => try sema.getBuiltinType(src, .Type),
27099 .branch_hint => try sema.getBuiltinType(src, .BranchHint),
27100 // zig fmt: on
2709527101
27096 // Values are handled here.27102 // Values are handled here.
27097 .calling_convention_c => {27103 .calling_convention_c => {
27098 const callconv_ty = try sema.getBuiltinType("CallingConvention");27104 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
27099 return try sema.namespaceLookupVal(27105 return try sema.namespaceLookupVal(
27100 block,27106 block,
27101 src,27107 src,
...@@ -27105,7 +27111,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -27105,7 +27111,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
27105 },27111 },
27106 .calling_convention_inline => {27112 .calling_convention_inline => {
27107 comptime assert(@typeInfo(std.builtin.CallingConvention.Tag).@"enum".tag_type == u8);27113 comptime assert(@typeInfo(std.builtin.CallingConvention.Tag).@"enum".tag_type == u8);
27108 const callconv_ty = try sema.getBuiltinType("CallingConvention");27114 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
27109 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");
27110 const inline_tag_val = try pt.enumValue(27116 const inline_tag_val = try pt.enumValue(
27111 callconv_tag_ty,27117 callconv_tag_ty,
...@@ -27117,7 +27123,6 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -27117,7 +27123,6 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
27117 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);
27118 },27124 },
27119 };27125 };
27120 const ty = try sema.getBuiltinType(type_name);
27121 return Air.internedToRef(ty.toIntern());27126 return Air.internedToRef(ty.toIntern());
27122}27127}
2712327128
...@@ -27156,7 +27161,7 @@ fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -27156,7 +27161,7 @@ fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
27156 const uncoerced_hint = try sema.resolveInst(extra.operand);27161 const uncoerced_hint = try sema.resolveInst(extra.operand);
27157 const operand_src = block.builtinCallArgSrc(extra.node, 0);27162 const operand_src = block.builtinCallArgSrc(extra.node, 0);
2715827163
27159 const hint_ty = try sema.getBuiltinType("BranchHint");27164 const hint_ty = try sema.getBuiltinType(operand_src, .BranchHint);
27160 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);
27161 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 });
2716227167
...@@ -27601,61 +27606,19 @@ fn explainWhyTypeIsNotPacked(...@@ -27601,61 +27606,19 @@ fn explainWhyTypeIsNotPacked(
27601 }27606 }
27602}27607}
2760327608
27604fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
27605 const pt = sema.pt;
27606 const zcu = pt.zcu;
27607
27608 if (zcu.panic_func_index == .none) {
27609 zcu.panic_func_index = try sema.getPanicInnerFn(block, src, "call");
27610 // Here, function body analysis must be queued up so that backends can
27611 // make calls to this function.
27612 try zcu.ensureFuncBodyAnalysisQueued(zcu.panic_func_index);
27613 }
27614
27615 if (zcu.null_stack_trace == .none) {
27616 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
27617 try stack_trace_ty.resolveFields(pt);
27618 const target = zcu.getTarget();
27619 const ptr_stack_trace_ty = try pt.ptrTypeSema(.{
27620 .child = stack_trace_ty.toIntern(),
27621 .flags = .{
27622 .address_space = target_util.defaultAddressSpace(target, .global_constant),
27623 },
27624 });
27625 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
27626 zcu.null_stack_trace = try pt.intern(.{ .opt = .{
27627 .ty = opt_ptr_stack_trace_ty.toIntern(),
27628 .val = .none,
27629 } });
27630 }
27631}
27632
27633/// Backends depend on panic decls being available when lowering safety-checked27609/// Backends depend on panic decls being available when lowering safety-checked
27634/// instructions. This function ensures the panic function will be available to27610/// instructions. This function ensures the panic function will be available to
27635/// be called during that time.27611/// be called during that time.
27636fn 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 {
27637 const pt = sema.pt;27613 const zcu = sema.pt.zcu;
27638 const zcu = pt.zcu;27614 try sema.ensureMemoizedStateResolved(src, .panic);
27639 const gpa = sema.gpa;27615 try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.@"Panic.call");
27640 if (zcu.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;27616 switch (panic_id) {
2764127617 inline else => |ct_panic_id| {
27642 try sema.prepareSimplePanic(block, src);27618 const name = "Panic.messages." ++ @tagName(ct_panic_id);
2764327619 return @field(zcu.builtin_decl_values, name);
27644 const panic_ty = try sema.getBuiltinType("Panic");27620 },
27645 const panic_messages_ty = try sema.getBuiltinInnerType(block, src, panic_ty, "Panic", "messages");27621 }
27646 const msg_nav_index = (sema.namespaceLookup(
27647 block,
27648 LazySrcLoc.unneeded,
27649 panic_messages_ty.getNamespaceIndex(zcu),
27650 try zcu.intern_pool.getOrPutString(gpa, pt.tid, @tagName(panic_id), .no_embedded_nulls),
27651 ) catch |err| switch (err) {
27652 error.AnalysisFail => return error.AnalysisFail,
27653 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
27654 error.OutOfMemory => |e| return e,
27655 }).?;
27656 try sema.ensureNavResolved(src, msg_nav_index, .fully);
27657 zcu.panic_messages[@intFromEnum(panic_id)] = msg_nav_index.toOptional();
27658 return msg_nav_index;
27659}27622}
2766027623
27661fn addSafetyCheck(27624fn addSafetyCheck(
...@@ -27759,10 +27722,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst....@@ -27759,10 +27722,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
27759 return;27722 return;
27760 }27723 }
2776127724
27762 try sema.prepareSimplePanic(block, src);27725 try sema.ensureMemoizedStateResolved(src, .panic);
27726 try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.@"Panic.call");
2776327727
27764 const panic_func = zcu.funcInfo(zcu.panic_func_index);27728 const panic_fn = Air.internedToRef(zcu.builtin_decl_values.@"Panic.call");
27765 const panic_fn = try sema.analyzeNavVal(block, src, panic_func.owner_nav);
27766 const null_stack_trace = Air.internedToRef(zcu.null_stack_trace);27729 const null_stack_trace = Air.internedToRef(zcu.null_stack_trace);
2776727730
27768 const opt_usize_ty = try pt.optionalType(.usize_type);27731 const opt_usize_ty = try pt.optionalType(.usize_type);
...@@ -27810,7 +27773,7 @@ fn safetyPanicUnwrapError(sema: *Sema, block: *Block, src: LazySrcLoc, err: Air....@@ -27810,7 +27773,7 @@ fn safetyPanicUnwrapError(sema: *Sema, block: *Block, src: LazySrcLoc, err: Air.
27810 if (!zcu.backendSupportsFeature(.panic_fn)) {27773 if (!zcu.backendSupportsFeature(.panic_fn)) {
27811 _ = try block.addNoOp(.trap);27774 _ = try block.addNoOp(.trap);
27812 } else {27775 } else {
27813 const panic_fn = try getPanicInnerFn(sema, block, src, "unwrapError");27776 const panic_fn = try getBuiltin(sema, src, .@"Panic.unwrapError");
27814 const err_return_trace = try sema.getErrorReturnTrace(block);27777 const err_return_trace = try sema.getErrorReturnTrace(block);
27815 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };27778 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
27816 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");
...@@ -27827,7 +27790,7 @@ fn addSafetyCheckIndexOob(...@@ -27827,7 +27790,7 @@ fn addSafetyCheckIndexOob(
27827) !void {27790) !void {
27828 assert(!parent_block.isComptime());27791 assert(!parent_block.isComptime());
27829 const ok = try parent_block.addBinOp(cmp_op, index, len);27792 const ok = try parent_block.addBinOp(cmp_op, index, len);
27830 return addSafetyCheckCall(sema, parent_block, src, ok, "outOfBounds", &.{ index, len });27793 return addSafetyCheckCall(sema, parent_block, src, ok, .@"Panic.outOfBounds", &.{ index, len });
27831}27794}
2783227795
27833fn addSafetyCheckInactiveUnionField(27796fn addSafetyCheckInactiveUnionField(
...@@ -27839,7 +27802,7 @@ fn addSafetyCheckInactiveUnionField(...@@ -27839,7 +27802,7 @@ fn addSafetyCheckInactiveUnionField(
27839) !void {27802) !void {
27840 assert(!parent_block.isComptime());27803 assert(!parent_block.isComptime());
27841 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);
27842 return addSafetyCheckCall(sema, parent_block, src, ok, "inactiveUnionField", &.{ active_tag, wanted_tag });27805 return addSafetyCheckCall(sema, parent_block, src, ok, .@"Panic.inactiveUnionField", &.{ active_tag, wanted_tag });
27843}27806}
2784427807
27845fn addSafetyCheckSentinelMismatch(27808fn addSafetyCheckSentinelMismatch(
...@@ -27880,7 +27843,7 @@ fn addSafetyCheckSentinelMismatch(...@@ -27880,7 +27843,7 @@ fn addSafetyCheckSentinelMismatch(
27880 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);
27881 };27844 };
2788227845
27883 return addSafetyCheckCall(sema, parent_block, src, ok, "sentinelMismatch", &.{27846 return addSafetyCheckCall(sema, parent_block, src, ok, .@"Panic.sentinelMismatch", &.{
27884 expected_sentinel, actual_sentinel,27847 expected_sentinel, actual_sentinel,
27885 });27848 });
27886}27849}
...@@ -27890,7 +27853,7 @@ fn addSafetyCheckCall(...@@ -27890,7 +27853,7 @@ fn addSafetyCheckCall(
27890 parent_block: *Block,27853 parent_block: *Block,
27891 src: LazySrcLoc,27854 src: LazySrcLoc,
27892 ok: Air.Inst.Ref,27855 ok: Air.Inst.Ref,
27893 func_name: []const u8,27856 comptime func_decl: Zcu.BuiltinDecl,
27894 args: []const Air.Inst.Ref,27857 args: []const Air.Inst.Ref,
27895) !void {27858) !void {
27896 assert(!parent_block.isComptime());27859 assert(!parent_block.isComptime());
...@@ -27914,7 +27877,7 @@ fn addSafetyCheckCall(...@@ -27914,7 +27877,7 @@ fn addSafetyCheckCall(
27914 if (!zcu.backendSupportsFeature(.panic_fn)) {27877 if (!zcu.backendSupportsFeature(.panic_fn)) {
27915 _ = try fail_block.addNoOp(.trap);27878 _ = try fail_block.addNoOp(.trap);
27916 } else {27879 } else {
27917 const panic_fn = try getPanicInnerFn(sema, &fail_block, src, func_name);27880 const panic_fn = try getBuiltin(sema, src, func_decl);
27918 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");
27919 }27882 }
2792027883
...@@ -27923,9 +27886,8 @@ fn addSafetyCheckCall(...@@ -27923,9 +27886,8 @@ fn addSafetyCheckCall(
2792327886
27924/// This does not set `sema.branch_hint`.27887/// This does not set `sema.branch_hint`.
27925fn 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 {
27926 const msg_nav_index = try sema.preparePanicId(block, src, panic_id);27889 const msg_val = try sema.preparePanicId(src, panic_id);
27927 const msg_inst = try sema.analyzeNavVal(block, src, msg_nav_index);27890 try sema.panicWithMsg(block, src, Air.internedToRef(msg_val), .@"safety check");
27928 try sema.panicWithMsg(block, src, msg_inst, .@"safety check");
27929}27891}
2793027892
27931fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {27893fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
...@@ -32522,6 +32484,19 @@ fn addTypeReferenceEntry(...@@ -32522,6 +32484,19 @@ fn addTypeReferenceEntry(
32522 try zcu.addTypeReference(sema.owner, referenced_type, src);32484 try zcu.addTypeReference(sema.owner, referenced_type, src);
32523}32485}
3252432486
32487fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.MemoizedStateStage) SemaError!void {
32488 const pt = sema.pt;
32489
32490 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
32491 try sema.addReferenceEntry(src, unit);
32492 try sema.declareDependency(.{ .memoized_state = stage });
32493
32494 if (pt.zcu.analysis_in_progress.contains(unit)) {
32495 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(src, "dependency loop detected", .{}));
32496 }
32497 try pt.ensureMemoizedStateUpToDate(stage);
32498}
32499
32525pub 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 {
32526 const pt = sema.pt;32501 const pt = sema.pt;
32527 const zcu = pt.zcu;32502 const zcu = pt.zcu;
...@@ -33371,7 +33346,7 @@ fn analyzeSlice(...@@ -33371,7 +33346,7 @@ fn analyzeSlice(
33371 assert(!block.isComptime());33346 assert(!block.isComptime());
33372 try sema.requireRuntimeBlock(block, src, runtime_src.?);33347 try sema.requireRuntimeBlock(block, src, runtime_src.?);
33373 const ok = try block.addBinOp(.cmp_lte, start, end);33348 const ok = try block.addBinOp(.cmp_lte, start, end);
33374 try sema.addSafetyCheckCall(block, src, ok, "startGreaterThanEnd", &.{ start, end });33349 try sema.addSafetyCheckCall(block, src, ok, .@"Panic.startGreaterThanEnd", &.{ start, end });
33375 }33350 }
33376 const new_len = if (by_length)33351 const new_len = if (by_length)
33377 try sema.coerce(block, Type.usize, uncasted_end_opt, end_src)33352 try sema.coerce(block, Type.usize, uncasted_end_opt, end_src)
...@@ -35491,7 +35466,7 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void...@@ -35491,7 +35466,7 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void
35491 }35466 }
35492}35467}
3549335468
35494pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {35469pub fn resolveFnTypes(sema: *Sema, fn_ty: Type, src: LazySrcLoc) CompileError!void {
35495 const pt = sema.pt;35470 const pt = sema.pt;
35496 const zcu = pt.zcu;35471 const zcu = pt.zcu;
35497 const ip = &zcu.intern_pool;35472 const ip = &zcu.intern_pool;
...@@ -35503,7 +35478,7 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {...@@ -35503,7 +35478,7 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
35503 Type.fromInterned(fn_ty_info.return_type).isError(zcu))35478 Type.fromInterned(fn_ty_info.return_type).isError(zcu))
35504 {35479 {
35505 // Ensure the type exists so that backends can assume that.35480 // Ensure the type exists so that backends can assume that.
35506 _ = try sema.getBuiltinType("StackTrace");35481 _ = try sema.getBuiltinType(src, .StackTrace);
35507 }35482 }
3550835483
35509 for (0..fn_ty_info.param_types.len) |i| {35484 for (0..fn_ty_info.param_types.len) |i| {
...@@ -37548,7 +37523,7 @@ pub fn analyzeAsAddressSpace(...@@ -37548,7 +37523,7 @@ pub fn analyzeAsAddressSpace(
37548) !std.builtin.AddressSpace {37523) !std.builtin.AddressSpace {
37549 const pt = sema.pt;37524 const pt = sema.pt;
37550 const zcu = pt.zcu;37525 const zcu = pt.zcu;
37551 const addrspace_ty = try sema.getBuiltinType("AddressSpace");37526 const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
37552 const coerced = try sema.coerce(block, addrspace_ty, air_ref, src);37527 const coerced = try sema.coerce(block, addrspace_ty, air_ref, src);
37553 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ .simple = .@"addrspace" });37528 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ .simple = .@"addrspace" });
37554 const address_space = zcu.toEnum(std.builtin.AddressSpace, addrspace_val);37529 const address_space = zcu.toEnum(std.builtin.AddressSpace, addrspace_val);
...@@ -38745,69 +38720,15 @@ const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadR...@@ -38745,69 +38720,15 @@ const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadR
38745const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;38720const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;
38746const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult;38721const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult;
3874738722
38748fn getPanicInnerFn(38723pub fn getBuiltinType(sema: *Sema, src: LazySrcLoc, comptime decl: Zcu.BuiltinDecl) SemaError!Type {
38749 sema: *Sema,38724 comptime assert(decl.kind() == .type);
38750 block: *Block,38725 try sema.ensureMemoizedStateResolved(src, decl.stage());
38751 src: LazySrcLoc,38726 return .fromInterned(@field(sema.pt.zcu.builtin_decl_values, @tagName(decl)));
38752 inner_name: []const u8,
38753) !InternPool.Index {
38754 const gpa = sema.gpa;
38755 const pt = sema.pt;
38756 const zcu = pt.zcu;
38757 const ip = &zcu.intern_pool;
38758 const outer_ty = try sema.getBuiltinType("Panic");
38759 const inner_name_ip = try ip.getOrPutString(gpa, pt.tid, inner_name, .no_embedded_nulls);
38760 const opt_fn_ref = try namespaceLookupVal(sema, block, src, outer_ty.getNamespaceIndex(zcu), inner_name_ip);
38761 const fn_ref = opt_fn_ref orelse return sema.fail(block, src, "std.builtin.Panic missing {s}", .{inner_name});
38762 const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{ .simple = .panic_handler });
38763 if (fn_val.typeOf(zcu).zigTypeTag(zcu) != .@"fn") {
38764 return sema.fail(block, src, "std.builtin.Panic.{s} is not a function", .{inner_name});
38765 }
38766 // Better not to queue up function body analysis because the function might be generic, and
38767 // the semantic analysis for the call will already queue if necessary.
38768 return fn_val.toIntern();
38769}
38770
38771fn getBuiltinType(sema: *Sema, name: []const u8) SemaError!Type {
38772 const pt = sema.pt;
38773 const ty_inst = try sema.getBuiltin(name);
38774 const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt"));
38775 try ty.resolveFully(pt);
38776 return ty;
38777}
38778
38779fn getBuiltinInnerType(
38780 sema: *Sema,
38781 block: *Block,
38782 src: LazySrcLoc,
38783 outer_ty: Type,
38784 /// Relative to "std.builtin".
38785 compile_error_parent_name: []const u8,
38786 inner_name: []const u8,
38787) !Type {
38788 const pt = sema.pt;
38789 const zcu = pt.zcu;
38790 const ip = &zcu.intern_pool;
38791 const gpa = sema.gpa;
38792 const inner_name_ip = try ip.getOrPutString(gpa, pt.tid, inner_name, .no_embedded_nulls);
38793 const opt_nav = try sema.namespaceLookup(block, src, outer_ty.getNamespaceIndex(zcu), inner_name_ip);
38794 const nav = opt_nav orelse return sema.fail(block, src, "std.builtin.{s} missing {s}", .{
38795 compile_error_parent_name, inner_name,
38796 });
38797 try sema.ensureNavResolved(src, nav, .fully);
38798 const val = Value.fromInterned(ip.getNav(nav).status.fully_resolved.val);
38799 const ty = val.toType();
38800 try ty.resolveFully(pt);
38801 return ty;
38802}38727}
3880338728pub fn getBuiltin(sema: *Sema, src: LazySrcLoc, comptime decl: Zcu.BuiltinDecl) SemaError!InternPool.Index {
38804fn getBuiltin(sema: *Sema, name: []const u8) SemaError!Air.Inst.Ref {38729 comptime assert(decl.kind() != .type);
38805 const pt = sema.pt;38730 try sema.ensureMemoizedStateResolved(src, decl.stage());
38806 const zcu = pt.zcu;38731 return @field(sema.pt.zcu.builtin_decl_values, @tagName(decl));
38807 const ip = &zcu.intern_pool;
38808 const nav = try pt.getBuiltinNav(name);
38809 try pt.ensureNavValUpToDate(nav);
38810 return Air.internedToRef(ip.getNav(nav).status.fully_resolved.val);
38811}38732}
3881238733
38813pub const NavPtrModifiers = struct {38734pub const NavPtrModifiers = struct {
...@@ -38875,3 +38796,77 @@ pub fn resolveNavPtrModifiers(...@@ -38875,3 +38796,77 @@ pub fn resolveNavPtrModifiers(
38875 .@"addrspace" = @"addrspace",38796 .@"addrspace" = @"addrspace",
38876 };38797 };
38877}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+219-19
...@@ -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
...@@ -2563,19 +2766,6 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {...@@ -2563,19 +2766,6 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
2563 }2766 }
2564 }2767 }
25652768
2566 if (chosen_unit == null) {
2567 for (zcu.outdated.keys(), zcu.outdated.values()) |o, opod| {
2568 const func = o.unwrap().func;
2569 const nav = zcu.funcInfo(func).owner_nav;
2570 std.io.getStdErr().writer().print("outdated: func {}, nav {}, name '{}', [p]o deps {}\n", .{ func, nav, ip.getNav(nav).fqn.fmt(ip), opod }) catch {};
2571 }
2572 for (zcu.potentially_outdated.keys(), zcu.potentially_outdated.values()) |o, opod| {
2573 const func = o.unwrap().func;
2574 const nav = zcu.funcInfo(func).owner_nav;
2575 std.io.getStdErr().writer().print("po: func {}, nav {}, name '{}', [p]o deps {}\n", .{ func, nav, ip.getNav(nav).fqn.fmt(ip), opod }) catch {};
2576 }
2577 }
2578
2579 log.debug("findOutdatedToAnalyze: heuristic returned '{}' ({d} dependers)", .{2769 log.debug("findOutdatedToAnalyze: heuristic returned '{}' ({d} dependers)", .{
2580 zcu.fmtAnalUnit(chosen_unit.?),2770 zcu.fmtAnalUnit(chosen_unit.?),
2581 chosen_unit_dependers,2771 chosen_unit_dependers,
...@@ -2661,6 +2851,14 @@ pub fn mapOldZirToNew(...@@ -2661,6 +2851,14 @@ pub fn mapOldZirToNew(
2661 }2851 }
26622852
2663 while (match_stack.popOrNull()) |match_item| {2853 while (match_stack.popOrNull()) |match_item| {
2854 // First, a check: if the number of captures of this type has changed, we can't map it, because
2855 // we wouldn't know how to correlate type information with the last update.
2856 // Synchronizes with logic in `Zcu.PerThread.recreateStructType` etc.
2857 if (old_zir.typeCapturesLen(match_item.old_inst) != new_zir.typeCapturesLen(match_item.new_inst)) {
2858 // Don't map this type or anything within it.
2859 continue;
2860 }
2861
2664 // Match the namespace declaration itself2862 // Match the namespace declaration itself
2665 try inst_map.put(gpa, match_item.old_inst, match_item.new_inst);2863 try inst_map.put(gpa, match_item.old_inst, match_item.new_inst);
26662864
...@@ -3467,7 +3665,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv...@@ -3467,7 +3665,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
3467 const other: AnalUnit = .wrap(switch (unit.unwrap()) {3665 const other: AnalUnit = .wrap(switch (unit.unwrap()) {
3468 .nav_val => |n| .{ .nav_ty = n },3666 .nav_val => |n| .{ .nav_ty = n },
3469 .nav_ty => |n| .{ .nav_val = n },3667 .nav_ty => |n| .{ .nav_val = n },
3470 .@"comptime", .type, .func => break :queue_paired,3668 .@"comptime", .type, .func, .memoized_state => break :queue_paired,
3471 });3669 });
3472 if (result.contains(other)) break :queue_paired;3670 if (result.contains(other)) break :queue_paired;
3473 try unit_queue.put(gpa, other, kv.value); // same reference location3671 try unit_queue.put(gpa, other, kv.value); // same reference location
...@@ -3602,6 +3800,7 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co...@@ -3602,6 +3800,7 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co
3602 const nav = zcu.funcInfo(func).owner_nav;3800 const nav = zcu.funcInfo(func).owner_nav;
3603 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) });
3604 },3802 },
3803 .memoized_state => return writer.writeAll("memoized_state"),
3605 }3804 }
3606}3805}
3607fn 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 {
...@@ -3647,6 +3846,7 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com...@@ -3647,6 +3846,7 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com
3647 const file_path = zcu.fileByIndex(info.file).sub_file_path;3846 const file_path = zcu.fileByIndex(info.file).sub_file_path;
3648 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) });
3649 },3848 },
3849 .memoized_state => return writer.writeAll("memoized_state"),
3650 }3850 }
3651}3851}
36523852
src/Zcu/PerThread.zig+197-61
...@@ -545,10 +545,160 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {...@@ -545,10 +545,160 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
545pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {545pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
546 const file_root_type = pt.zcu.fileRootType(file_index);546 const file_root_type = pt.zcu.fileRootType(file_index);
547 if (file_root_type != .none) {547 if (file_root_type != .none) {
548 _ = try pt.ensureTypeUpToDate(file_root_type);548 if (pt.ensureTypeUpToDate(file_root_type)) |_| {
549 return;
550 } else |err| switch (err) {
551 error.AnalysisFail => {
552 // The file's root `struct_decl` has, at some point, been lost, because the file failed AstGen.
553 // Clear `file_root_type`, and try the `semaFile` call below, in case the instruction has since
554 // been discovered under a new `TrackedInst.Index`.
555 pt.zcu.setFileRootType(file_index, .none);
556 },
557 else => |e| return e,
558 }
559 }
560 return pt.semaFile(file_index);
561}
562
563/// Ensures that all memoized state on `Zcu` is up-to-date, performing re-analysis if necessary.
564/// Returns `error.AnalysisFail` if an analysis error is encountered; the caller is free to ignore
565/// this, since the error is already registered, but it must not use the value of memoized fields.
566pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) Zcu.SemaError!void {
567 const tracy = trace(@src());
568 defer tracy.end();
569
570 const zcu = pt.zcu;
571 const gpa = zcu.gpa;
572
573 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
574
575 log.debug("ensureMemoizedStateUpToDate", .{});
576
577 assert(!zcu.analysis_in_progress.contains(unit));
578
579 const was_outdated = zcu.outdated.swapRemove(unit) or zcu.potentially_outdated.swapRemove(unit);
580 const prev_failed = zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit);
581
582 if (was_outdated) {
583 dev.check(.incremental);
584 _ = zcu.outdated_ready.swapRemove(unit);
585 // No need for `deleteUnitExports` because we never export anything.
586 zcu.deleteUnitReferences(unit);
587 if (zcu.failed_analysis.fetchSwapRemove(unit)) |kv| {
588 kv.value.destroy(gpa);
589 }
590 _ = zcu.transitive_failed_analysis.swapRemove(unit);
549 } else {591 } else {
550 return pt.semaFile(file_index);592 if (prev_failed) return error.AnalysisFail;
593 // We use an arbitrary field to check if the state has been resolved yet.
594 const val = switch (stage) {
595 .main => zcu.builtin_decl_values.Type,
596 .panic => zcu.builtin_decl_values.Panic,
597 .va_list => zcu.builtin_decl_values.VaList,
598 };
599 if (val != .none) return;
600 }
601
602 const any_changed: bool, const new_failed: bool = if (pt.analyzeMemoizedState(stage)) |any_changed|
603 .{ any_changed or prev_failed, false }
604 else |err| switch (err) {
605 error.AnalysisFail => res: {
606 if (!zcu.failed_analysis.contains(unit)) {
607 // If this unit caused the error, it would have an entry in `failed_analysis`.
608 // Since it does not, this must be a transitive failure.
609 try zcu.transitive_failed_analysis.put(gpa, unit, {});
610 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(unit)});
611 }
612 break :res .{ !prev_failed, true };
613 },
614 error.OutOfMemory => {
615 // TODO: same as for `ensureComptimeUnitUpToDate` etc
616 return error.OutOfMemory;
617 },
618 error.GenericPoison => unreachable,
619 error.ComptimeReturn => unreachable,
620 error.ComptimeBreak => unreachable,
621 };
622
623 if (was_outdated) {
624 const dependee: InternPool.Dependee = .{ .memoized_state = stage };
625 if (any_changed) {
626 try zcu.markDependeeOutdated(.marked_po, dependee);
627 } else {
628 try zcu.markPoDependeeUpToDate(dependee);
629 }
551 }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);
552}702}
553703
554/// 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
...@@ -909,7 +1059,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -909,7 +1059,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
909 // Of course, we need to make sure we depend on it properly.1059 // Of course, we need to make sure we depend on it properly.
910 try sema.declareDependency(.{ .nav_ty = nav_id });1060 try sema.declareDependency(.{ .nav_ty = nav_id });
911 try pt.ensureNavTypeUpToDate(nav_id);1061 try pt.ensureNavTypeUpToDate(nav_id);
912 break :ty .fromInterned(ip.getNav(nav_id).status.type_resolved.type);1062 break :ty .fromInterned(ip.getNav(nav_id).typeOf(ip));
913 } else null;1063 } else null;
9141064
915 const final_val: ?Value = if (zir_decl.value_body) |value_body| val: {1065 const final_val: ?Value = if (zir_decl.value_body) |value_body| val: {
...@@ -2606,7 +2756,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -2606,7 +2756,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
2606 // result in circular dependency errors.2756 // result in circular dependency errors.
2607 // 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`.
2608 // The codegen timing guarantees that the parameter types will be populated.2758 // The codegen timing guarantees that the parameter types will be populated.
2609 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {2759 sema.resolveFnTypes(fn_ty, inner_block.nodeOffset(0)) catch |err| switch (err) {
2610 error.GenericPoison => unreachable,2760 error.GenericPoison => unreachable,
2611 error.ComptimeReturn => unreachable,2761 error.ComptimeReturn => unreachable,
2612 error.ComptimeBreak => unreachable,2762 error.ComptimeBreak => unreachable,
...@@ -3462,23 +3612,6 @@ pub fn structPackedFieldBitOffset(...@@ -3462,23 +3612,6 @@ pub fn structPackedFieldBitOffset(
3462 unreachable; // index out of bounds3612 unreachable; // index out of bounds
3463}3613}
34643614
3465pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.Nav.Index {
3466 const zcu = pt.zcu;
3467 const gpa = zcu.gpa;
3468 const ip = &zcu.intern_pool;
3469 const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
3470 const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
3471 const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).unwrap().?);
3472 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
3473 const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse
3474 @panic("lib/std.zig is corrupt and missing 'builtin'");
3475 pt.ensureNavValUpToDate(builtin_nav) catch @panic("std.builtin is corrupt");
3476 const builtin_type = Type.fromInterned(ip.getNav(builtin_nav).status.fully_resolved.val);
3477 const builtin_namespace = zcu.namespacePtr(builtin_type.getNamespace(zcu).unwrap() orelse @panic("std.builtin is corrupt"));
3478 const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
3479 return builtin_namespace.pub_decls.getKeyAdapted(name_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
3480}
3481
3482pub 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 {
3483 const zcu = pt.zcu;3616 const zcu = pt.zcu;
3484 const ip = &zcu.intern_pool;3617 const ip = &zcu.intern_pool;
...@@ -3524,9 +3657,11 @@ pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPo...@@ -3524,9 +3657,11 @@ pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPo
3524 return ty.abiAlignment(zcu);3657 return ty.abiAlignment(zcu);
3525}3658}
35263659
3527/// Given a container type requiring resolution, ensures that it is up-to-date.3660/// `ty` is a container type requiring resolution (struct, union, or enum).
3528/// If not, the type is recreated at a new `InternPool.Index`.3661/// If `ty` is outdated, it is recreated at a new `InternPool.Index`, which is returned.
3529/// The new index is returned. This is the same as the old index if the fields were up-to-date.3662/// If the type cannot be recreated because it has been lost, `error.AnalysisFail` is returned.
3663/// If `ty` is not outdated, that same `InternPool.Index` is returned.
3664/// If `ty` has already been replaced by this function, the new index will not be returned again.
3530pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError!InternPool.Index {3665pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError!InternPool.Index {
3531 const zcu = pt.zcu;3666 const zcu = pt.zcu;
3532 const gpa = zcu.gpa;3667 const gpa = zcu.gpa;
...@@ -3536,13 +3671,30 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError...@@ -3536,13 +3671,30 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError
3536 const outdated = zcu.outdated.swapRemove(anal_unit) or3671 const outdated = zcu.outdated.swapRemove(anal_unit) or
3537 zcu.potentially_outdated.swapRemove(anal_unit);3672 zcu.potentially_outdated.swapRemove(anal_unit);
35383673
3674 if (outdated) {
3675 _ = zcu.outdated_ready.swapRemove(anal_unit);
3676 try zcu.markDependeeOutdated(.marked_po, .{ .interned = ty });
3677 }
3678
3679 const ty_key = switch (ip.indexToKey(ty)) {
3680 .struct_type, .union_type, .enum_type => |key| key,
3681 else => unreachable,
3682 };
3683 const declared_ty_key = switch (ty_key) {
3684 .reified => unreachable, // never outdated
3685 .generated_tag => unreachable, // never outdated
3686 .declared => |d| d,
3687 };
3688
3689 if (declared_ty_key.zir_index.resolve(ip) == null) {
3690 // The instruction has been lost -- this type is dead.
3691 return error.AnalysisFail;
3692 }
3693
3539 if (!outdated) return ty;3694 if (!outdated) return ty;
35403695
3541 // We will recreate the type at a new `InternPool.Index`.3696 // We will recreate the type at a new `InternPool.Index`.
35423697
3543 _ = zcu.outdated_ready.swapRemove(anal_unit);
3544 try zcu.markDependeeOutdated(.marked_po, .{ .interned = ty });
3545
3546 // Delete old state which is no longer in use. Technically, this is not necessary: these exports,3698 // Delete old state which is no longer in use. Technically, this is not necessary: these exports,
3547 // references, etc, will be ignored because the type itself is unreferenced. However, it allows3699 // references, etc, will be ignored because the type itself is unreferenced. However, it allows
3548 // reusing the memory which is currently being used to track this state.3700 // reusing the memory which is currently being used to track this state.
...@@ -3555,9 +3707,9 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError...@@ -3555,9 +3707,9 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError
3555 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);3707 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
35563708
3557 switch (ip.indexToKey(ty)) {3709 switch (ip.indexToKey(ty)) {
3558 .struct_type => |key| return pt.recreateStructType(ty, key),3710 .struct_type => return pt.recreateStructType(ty, declared_ty_key),
3559 .union_type => |key| return pt.recreateUnionType(ty, key),3711 .union_type => return pt.recreateUnionType(ty, declared_ty_key),
3560 .enum_type => |key| return pt.recreateEnumType(ty, key),3712 .enum_type => return pt.recreateEnumType(ty, declared_ty_key),
3561 else => unreachable,3713 else => unreachable,
3562 }3714 }
3563}3715}
...@@ -3565,21 +3717,15 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError...@@ -3565,21 +3717,15 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError
3565fn recreateStructType(3717fn recreateStructType(
3566 pt: Zcu.PerThread,3718 pt: Zcu.PerThread,
3567 old_ty: InternPool.Index,3719 old_ty: InternPool.Index,
3568 full_key: InternPool.Key.NamespaceType,3720 key: InternPool.Key.NamespaceType.Declared,
3569) Zcu.SemaError!InternPool.Index {3721) Allocator.Error!InternPool.Index {
3570 const zcu = pt.zcu;3722 const zcu = pt.zcu;
3571 const gpa = zcu.gpa;3723 const gpa = zcu.gpa;
3572 const ip = &zcu.intern_pool;3724 const ip = &zcu.intern_pool;
35733725
3574 const key = switch (full_key) {3726 const inst_info = key.zir_index.resolveFull(ip).?;
3575 .reified => unreachable, // never outdated
3576 .generated_tag => unreachable, // not a struct
3577 .declared => |d| d,
3578 };
3579
3580 const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
3581 const file = zcu.fileByIndex(inst_info.file);3727 const file = zcu.fileByIndex(inst_info.file);
3582 if (file.status != .success_zir) return error.AnalysisFail;3728 assert(file.status == .success_zir); // otherwise inst tracking failed
3583 const zir = file.zir;3729 const zir = file.zir;
35843730
3585 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);3731 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
...@@ -3600,7 +3746,7 @@ fn recreateStructType(...@@ -3600,7 +3746,7 @@ fn recreateStructType(
3600 break :blk fields_len;3746 break :blk fields_len;
3601 } else 0;3747 } else 0;
36023748
3603 if (captures_len != key.captures.owned.len) return error.AnalysisFail;3749 assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew`
36043750
3605 const struct_obj = ip.loadStructType(old_ty);3751 const struct_obj = ip.loadStructType(old_ty);
36063752
...@@ -3644,21 +3790,15 @@ fn recreateStructType(...@@ -3644,21 +3790,15 @@ fn recreateStructType(
3644fn recreateUnionType(3790fn recreateUnionType(
3645 pt: Zcu.PerThread,3791 pt: Zcu.PerThread,
3646 old_ty: InternPool.Index,3792 old_ty: InternPool.Index,
3647 full_key: InternPool.Key.NamespaceType,3793 key: InternPool.Key.NamespaceType.Declared,
3648) Zcu.SemaError!InternPool.Index {3794) Allocator.Error!InternPool.Index {
3649 const zcu = pt.zcu;3795 const zcu = pt.zcu;
3650 const gpa = zcu.gpa;3796 const gpa = zcu.gpa;
3651 const ip = &zcu.intern_pool;3797 const ip = &zcu.intern_pool;
36523798
3653 const key = switch (full_key) {3799 const inst_info = key.zir_index.resolveFull(ip).?;
3654 .reified => unreachable, // never outdated
3655 .generated_tag => unreachable, // not a union
3656 .declared => |d| d,
3657 };
3658
3659 const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
3660 const file = zcu.fileByIndex(inst_info.file);3800 const file = zcu.fileByIndex(inst_info.file);
3661 if (file.status != .success_zir) return error.AnalysisFail;3801 assert(file.status == .success_zir); // otherwise inst tracking failed
3662 const zir = file.zir;3802 const zir = file.zir;
36633803
3664 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);3804 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
...@@ -3681,7 +3821,7 @@ fn recreateUnionType(...@@ -3681,7 +3821,7 @@ fn recreateUnionType(
3681 break :blk fields_len;3821 break :blk fields_len;
3682 } else 0;3822 } else 0;
36833823
3684 if (captures_len != key.captures.owned.len) return error.AnalysisFail;3824 assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew`
36853825
3686 const union_obj = ip.loadUnionType(old_ty);3826 const union_obj = ip.loadUnionType(old_ty);
36873827
...@@ -3731,23 +3871,19 @@ fn recreateUnionType(...@@ -3731,23 +3871,19 @@ fn recreateUnionType(
3731 return wip_ty.finish(ip, namespace_index);3871 return wip_ty.finish(ip, namespace_index);
3732}3872}
37333873
3874// TODO: is it safe for this to return `SemaError`? enum type resolution is a bit weird...
3734fn recreateEnumType(3875fn recreateEnumType(
3735 pt: Zcu.PerThread,3876 pt: Zcu.PerThread,
3736 old_ty: InternPool.Index,3877 old_ty: InternPool.Index,
3737 full_key: InternPool.Key.NamespaceType,3878 key: InternPool.Key.NamespaceType.Declared,
3738) Zcu.SemaError!InternPool.Index {3879) Zcu.SemaError!InternPool.Index {
3739 const zcu = pt.zcu;3880 const zcu = pt.zcu;
3740 const gpa = zcu.gpa;3881 const gpa = zcu.gpa;
3741 const ip = &zcu.intern_pool;3882 const ip = &zcu.intern_pool;
37423883
3743 const key = switch (full_key) {3884 const inst_info = key.zir_index.resolveFull(ip).?;
3744 .reified, .generated_tag => unreachable, // never outdated
3745 .declared => |d| d,
3746 };
3747
3748 const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
3749 const file = zcu.fileByIndex(inst_info.file);3885 const file = zcu.fileByIndex(inst_info.file);
3750 if (file.status != .success_zir) return error.AnalysisFail;3886 assert(file.status == .success_zir); // otherwise inst tracking failed
3751 const zir = file.zir;3887 const zir = file.zir;
37523888
3753 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);3889 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
...@@ -3787,7 +3923,7 @@ fn recreateEnumType(...@@ -3787,7 +3923,7 @@ fn recreateEnumType(
3787 break :blk decls_len;3923 break :blk decls_len;
3788 } else 0;3924 } else 0;
37893925
3790 if (captures_len != key.captures.owned.len) return error.AnalysisFail;3926 assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew`
37913927
3792 extra_index += captures_len;3928 extra_index += captures_len;
3793 extra_index += decls_len;3929 extra_index += decls_len;
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);
test/incremental/change_panic_handler created+74
...@@ -0,0 +1,74 @@
1#target=x86_64-linux-selfhosted
2#target=x86_64-linux-cbe
3#target=x86_64-windows-cbe
4#update=initial version
5#file=main.zig
6pub fn main() !u8 {
7 var a: u8 = undefined;
8 a = 255;
9 _ = a + 1;
10 return 1;
11}
12pub const Panic = struct {
13 pub const call = myPanic;
14 pub const sentinelMismatch = std.debug.FormattedPanic.sentinelMismatch;
15 pub const unwrapError = std.debug.FormattedPanic.unwrapError;
16 pub const outOfBounds = std.debug.FormattedPanic.outOfBounds;
17 pub const startGreaterThanEnd = std.debug.FormattedPanic.startGreaterThanEnd;
18 pub const inactiveUnionField = std.debug.FormattedPanic.inactiveUnionField;
19 pub const messages = std.debug.FormattedPanic.messages;
20};
21fn myPanic(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
22 std.io.getStdOut().writer().print("panic message: {s}\n", .{msg}) catch {};
23 std.process.exit(0);
24}
25const std = @import("std");
26#expect_stdout="panic message: integer overflow\n"
27
28#update=change the panic handler body
29#file=main.zig
30pub fn main() !u8 {
31 var a: u8 = undefined;
32 a = 255;
33 _ = a + 1;
34 return 1;
35}
36pub const Panic = struct {
37 pub const call = myPanic;
38 pub const sentinelMismatch = std.debug.FormattedPanic.sentinelMismatch;
39 pub const unwrapError = std.debug.FormattedPanic.unwrapError;
40 pub const outOfBounds = std.debug.FormattedPanic.outOfBounds;
41 pub const startGreaterThanEnd = std.debug.FormattedPanic.startGreaterThanEnd;
42 pub const inactiveUnionField = std.debug.FormattedPanic.inactiveUnionField;
43 pub const messages = std.debug.FormattedPanic.messages;
44};
45fn myPanic(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
46 std.io.getStdOut().writer().print("new panic message: {s}\n", .{msg}) catch {};
47 std.process.exit(0);
48}
49const std = @import("std");
50#expect_stdout="new panic message: integer overflow\n"
51
52#update=change the panic handler function value
53#file=main.zig
54pub fn main() !u8 {
55 var a: u8 = undefined;
56 a = 255;
57 _ = a + 1;
58 return 1;
59}
60pub const Panic = struct {
61 pub const call = myPanicNew;
62 pub const sentinelMismatch = std.debug.FormattedPanic.sentinelMismatch;
63 pub const unwrapError = std.debug.FormattedPanic.unwrapError;
64 pub const outOfBounds = std.debug.FormattedPanic.outOfBounds;
65 pub const startGreaterThanEnd = std.debug.FormattedPanic.startGreaterThanEnd;
66 pub const inactiveUnionField = std.debug.FormattedPanic.inactiveUnionField;
67 pub const messages = std.debug.FormattedPanic.messages;
68};
69fn myPanicNew(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
70 std.io.getStdOut().writer().print("third panic message: {s}\n", .{msg}) catch {};
71 std.process.exit(0);
72}
73const std = @import("std");
74#expect_stdout="third panic message: integer overflow\n"
test/incremental/temporary_parse_error created+18
...@@ -0,0 +1,18 @@
1#target=x86_64-linux-selfhosted
2#target=x86_64-linux-cbe
3#target=x86_64-windows-cbe
4#update=initial version
5#file=main.zig
6const std = @import("std");
7pub fn main() !void {}
8#expect_stdout=""
9
10#update=introduce parse error
11#file=main.zig
12pub fn main() !void {
13#expect_error=ignored
14
15#update=fix parse error
16#file=main.zig
17pub fn main() !void {}
18#expect_stdout=""