authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-02 17:35:02+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-10 10:26:14+00:00
logc2b42383eb058f4c2bd17738cd73382e6a6672eb
tree064a6184bbb51ac4c6985deab38b0c0e5bc37132
parent9c9a5e722b84d12de34d16f53355adbe1f5e11d3
signaturelock-open Commit is signed but in an unrecognized format.

compiler,std: various little fixes


11 files changed, 246 insertions(+), 98 deletions(-)

lib/std/hash_map.zig+3-3
......@@ -1526,9 +1526,9 @@ pub fn HashMapUnmanaged(
15261526 }
15271527
15281528 comptime {
1529 if (!builtin.strip_debug_info) _ = switch (builtin.zig_backend) {
1530 .stage2_llvm => &dbHelper,
1531 .stage2_x86_64 => KV,
1529 if (!builtin.strip_debug_info) switch (builtin.zig_backend) {
1530 .stage2_llvm => _ = &dbHelper,
1531 .stage2_x86_64 => _ = @as(KV, undefined),
15321532 else => {},
15331533 };
15341534 }
src/InternPool.zig+14-2
......@@ -3334,11 +3334,17 @@ pub const LoadedStructType = struct {
33343334 field_defaults: Index.Slice,
33353335 field_aligns: Alignment.Slice,
33363336 field_is_comptime_bits: ComptimeBits,
3337 /// If `layout` is `.@"packed"`, this is `.empty`.
33373338 field_runtime_order: RuntimeOrder.Slice,
3339 /// If `layout` is `.@"packed"`, this is `.empty`.
33383340 field_offsets: Offsets,
3341 /// Only valid if `layout` is `.@"packed"`.
33393342 packed_backing_int_type: Index,
3343 /// Only valid if `layout` is *not* `.@"packed"`.
33403344 class: TypeClass,
3345 /// Only valid if `layout` is *not* `.@"packed"`.
33413346 size: u32,
3347 /// Only valid if `layout` is *not* `.@"packed"`.
33423348 alignment: Alignment,
33433349
33443350 pub const ComptimeBits = struct {
......@@ -3516,15 +3522,21 @@ pub const LoadedUnionType = struct {
35163522 tag_usage: TagUsage,
35173523 /// While `tag_usage` indicates whether the union should logically contain a tag, it may be
35183524 /// omitted if the union layout is resolved as OPV or NPV. This field is `true` iff there is an
3519 /// actual runtime tag in the union layout.
3525 /// actual runtime tag, with one or more runtime bits, in the union layout. It is always `false`
3526 /// if `layout` is not `.auto`.
35203527 has_runtime_tag: bool,
35213528 /// Even if `tag_usage == .none` and `has_runtime_tag == false`, this is still populated with
35223529 /// the union's "hypothetical" tag type.
35233530 enum_tag_type: Index,
3531 /// Only valid if `layout` is `.@"packed"`.
35243532 packed_backing_int_type: Index,
3533 /// Not valid if `layout` is `.@"packed"`.
35253534 class: TypeClass,
3535 /// Not valid if `layout` is `.@"packed"`.
35263536 size: u32,
3537 /// Not valid if `layout` is `.@"packed"`.
35273538 padding: u32,
3539 /// Not valid if `layout` is `.@"packed"`.
35283540 alignment: Alignment,
35293541
35303542 pub const TagUsage = enum(u2) {
......@@ -3898,7 +3910,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
38983910 .want_layout = extra.data.bits.want_layout,
38993911 .field_types = field_types,
39003912 .field_aligns = .empty,
3901 .has_runtime_tag = undefined,
3913 .has_runtime_tag = false,
39023914 .class = undefined,
39033915 .size = undefined,
39043916 .padding = undefined,
src/Sema.zig+50-42
......@@ -13777,45 +13777,44 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1377713777 const many_alloc = try block.addBitCast(many_ty, mutable_alloc);
1377813778
1377913779 // lhs_dest_slice = dest[0..lhs.len]
13780 const slice_ty_ref = Air.internedToRef(slice_ty.toIntern());
13781 const lhs_len_ref = try pt.intRef(.usize, lhs_len);
13782 const lhs_dest_slice = try block.addInst(.{
13783 .tag = .slice,
13784 .data = .{ .ty_pl = .{
13785 .ty = slice_ty_ref,
13786 .payload = try sema.addExtra(Air.Bin{
13787 .lhs = many_alloc,
13788 .rhs = lhs_len_ref,
13789 }),
13790 } },
13791 });
13792
13793 _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
13780 if (lhs_len > 0) {
13781 const lhs_dest_slice = try block.addInst(.{
13782 .tag = .slice,
13783 .data = .{ .ty_pl = .{
13784 .ty = .fromType(slice_ty),
13785 .payload = try sema.addExtra(Air.Bin{
13786 .lhs = many_alloc,
13787 .rhs = try pt.intRef(.usize, lhs_len),
13788 }),
13789 } },
13790 });
13791 _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
13792 }
1379413793
1379513794 // rhs_dest_slice = dest[lhs.len..][0..rhs.len]
13796 const rhs_len_ref = try pt.intRef(.usize, rhs_len);
13797 const rhs_dest_offset = try block.addInst(.{
13798 .tag = .ptr_add,
13799 .data = .{ .ty_pl = .{
13800 .ty = Air.internedToRef(many_ty.toIntern()),
13801 .payload = try sema.addExtra(Air.Bin{
13802 .lhs = many_alloc,
13803 .rhs = lhs_len_ref,
13804 }),
13805 } },
13806 });
13807 const rhs_dest_slice = try block.addInst(.{
13808 .tag = .slice,
13809 .data = .{ .ty_pl = .{
13810 .ty = slice_ty_ref,
13811 .payload = try sema.addExtra(Air.Bin{
13812 .lhs = rhs_dest_offset,
13813 .rhs = rhs_len_ref,
13814 }),
13815 } },
13816 });
13817
13818 _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);
13795 if (rhs_len > 0) {
13796 const rhs_dest_offset = try block.addInst(.{
13797 .tag = .ptr_add,
13798 .data = .{ .ty_pl = .{
13799 .ty = Air.internedToRef(many_ty.toIntern()),
13800 .payload = try sema.addExtra(Air.Bin{
13801 .lhs = many_alloc,
13802 .rhs = try pt.intRef(.usize, lhs_len),
13803 }),
13804 } },
13805 });
13806 const rhs_dest_slice = try block.addInst(.{
13807 .tag = .slice,
13808 .data = .{ .ty_pl = .{
13809 .ty = .fromType(slice_ty),
13810 .payload = try sema.addExtra(Air.Bin{
13811 .lhs = rhs_dest_offset,
13812 .rhs = try pt.intRef(.usize, rhs_len),
13813 }),
13814 } },
13815 });
13816 _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);
13817 }
1381913818
1382013819 if (res_sent_val) |sent_val| {
1382113820 const elem_index = try pt.intRef(.usize, result_len);
......@@ -18829,7 +18828,7 @@ fn finishStructInit(
1882918828 return sema.addConstantMaybeRef(sema.resolveValue(final_val_ref).?, is_ref);
1883018829 },
1883118830 .@"packed" => {
18832 const buf = try sema.arena.alloc(u8, (struct_ty.bitSize(zcu) + 7) / 8);
18831 const buf = try sema.arena.alloc(u8, @intCast((struct_ty.bitSize(zcu) + 7) / 8));
1883318832 var bit_offset: u16 = 0;
1883418833 for (field_inits) |field_init| {
1883518834 const field_val = sema.resolveValue(field_init).?;
......@@ -21113,7 +21112,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2111321112 else => unreachable,
2111421113 };
2111521114
21116 if (!dest_err_ty.isAnyError(zcu) and !dest_err_ty.errorSetHasField(err_name, zcu)) {
21115 if (result != .superset and !dest_err_ty.errorSetHasField(err_name, zcu)) {
2111721116 return sema.fail(block, src, "'error.{f}' not a member of error set '{f}'", .{
2111821117 err_name.fmt(ip), dest_err_ty.fmt(pt),
2111921118 });
......@@ -25186,9 +25185,18 @@ pub fn explainWhyTypeIsNotExtern(
2518625185 else => |cc| try sema.errNote(src_loc, msg, "{t} function cannot be extern", .{cc}),
2518725186 },
2518825187 .@"enum" => {
25189 const tag_ty = ty.intTagType(zcu);
25190 try sema.errNote(src_loc, msg, "enum tag type '{f}' is not extern compatible", .{tag_ty.fmt(pt)});
25191 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);
25188 const enum_obj = zcu.intern_pool.loadEnumType(ty.toIntern());
25189 switch (enum_obj.int_tag_mode) {
25190 .auto => {
25191 try sema.errNote(ty.srcLoc(zcu), msg, "integer tag type of enum is inferred", .{});
25192 try sema.errNote(ty.srcLoc(zcu), msg, "consider explicitly specifying the integer tag type", .{});
25193 },
25194 .explicit => {
25195 const tag_ty: Type = .fromInterned(enum_obj.int_tag_type);
25196 try sema.errNote(ty.srcLoc(zcu), msg, "enum tag type '{f}' is not extern compatible", .{tag_ty.fmt(pt)});
25197 try sema.explainWhyTypeIsNotExtern(msg, ty.srcLoc(zcu), tag_ty, position);
25198 },
25199 }
2519225200 },
2519325201 .@"struct" => {
2519425202 const struct_obj = zcu.intern_pool.loadStructType(ty.toIntern());
src/Value.zig+2-2
......@@ -895,7 +895,7 @@ pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {
895895 // Avoid hitting gpa for accesses to small packed structs
896896 var sfba_state = std.heap.stackFallback(128, zcu.comp.gpa);
897897 const sfba = sfba_state.get();
898 const buf = try sfba.alloc(u8, (ty.bitSize(zcu) + 7) / 8);
898 const buf = try sfba.alloc(u8, @intCast((ty.bitSize(zcu) + 7) / 8));
899899 defer sfba.free(buf);
900900 int_val.writeToPackedMemory(pt, buf, 0) catch |err| switch (err) {
901901 error.ReinterpretDeclRef => unreachable, // it's an integer
......@@ -2419,7 +2419,7 @@ pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory
24192419 }
24202420 for (field_vals, 0..) |*field_val, field_idx| {
24212421 if (field_val.* == .none) {
2422 const default_init = struct_obj.field_inits.get(ip)[field_idx];
2422 const default_init = struct_obj.field_defaults.get(ip)[field_idx];
24232423 if (default_init == .none) return error.TypeMismatch;
24242424 field_val.* = default_init;
24252425 }
src/Zcu.zig+6-1
......@@ -3686,6 +3686,11 @@ pub const ImportResult = struct {
36863686pub fn resetUnit(zcu: *Zcu, unit: AnalUnit) void {
36873687 const gpa = zcu.comp.gpa;
36883688
3689 if (!dev.env.supports(.incremental)) {
3690 // This is the first time `unit` is being analyzed, so there is no stale data to clear.
3691 return;
3692 }
3693
36893694 // Compile errors
36903695 if (zcu.failed_analysis.fetchSwapRemove(unit)) |kv| {
36913696 kv.value.destroy(gpa);
......@@ -4309,7 +4314,7 @@ fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.AutoArrayHashMapUnmanag
43094314 });
43104315 const gop = try units.getOrPut(gpa, other);
43114316 if (gop.found_existing) break :queue_paired;
4312 gop.value_ptr.* = units.values()[unit_idx]; // same reference location
4317 gop.value_ptr.* = units.values()[unit_idx - 1]; // same reference location
43134318 }
43144319
43154320 refs_log.debug("handle unit '{f}'", .{zcu.fmtAnalUnit(unit)});
src/Zcu/PerThread.zig+54-26
......@@ -1075,7 +1075,6 @@ pub fn ensureMemoizedStateUpToDate(
10751075 const prev_failed = zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit);
10761076
10771077 if (was_outdated) {
1078 dev.check(.incremental);
10791078 zcu.resetUnit(unit);
10801079 } else {
10811080 if (prev_failed) return error.AnalysisFail;
......@@ -1193,10 +1192,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU
11931192 const was_outdated = zcu.clearOutdatedState(anal_unit);
11941193
11951194 if (was_outdated) {
1196 // `was_outdated` can be true in the initial update for comptime units, so this isn't a `dev.check`.
1197 if (dev.env.supports(.incremental)) {
1198 zcu.resetUnit(anal_unit);
1199 }
1195 zcu.resetUnit(anal_unit);
12001196 } else {
12011197 // We can trust the current information about this unit.
12021198 if (zcu.failed_analysis.contains(anal_unit)) return error.AnalysisFail;
......@@ -1366,10 +1362,7 @@ pub fn ensureTypeLayoutUpToDate(
13661362 };
13671363
13681364 if (was_outdated) {
1369 // `was_outdated` is true in the initial update, so this isn't a `dev.check`.
1370 if (dev.env.supports(.incremental)) {
1371 zcu.resetUnit(anal_unit);
1372 }
1365 zcu.resetUnit(anal_unit);
13731366 // For types, we already know that we have to invalidate all dependees.
13741367 // TODO: we actually *could* detect whether everything was the same. should we bother?
13751368 try zcu.markDependeeOutdated(.marked_po, .{ .type_layout = ty.toIntern() });
......@@ -1492,10 +1485,7 @@ pub fn ensureStructDefaultsUpToDate(
14921485 };
14931486
14941487 if (was_outdated) {
1495 // `was_outdated` is true in the initial update, so this isn't a `dev.check`.
1496 if (dev.env.supports(.incremental)) {
1497 zcu.resetUnit(anal_unit);
1498 }
1488 zcu.resetUnit(anal_unit);
14991489 // For types, we already know that we have to invalidate all dependees.
15001490 // TODO: we actually *could* detect whether everything was the same. should we bother?
15011491 try zcu.markDependeeOutdated(.marked_po, .{ .struct_defaults = ty.toIntern() });
......@@ -1609,7 +1599,6 @@ pub fn ensureNavValUpToDate(
16091599 zcu.transitive_failed_analysis.contains(anal_unit);
16101600
16111601 if (was_outdated) {
1612 dev.check(.incremental);
16131602 zcu.resetUnit(anal_unit);
16141603 } else {
16151604 // We can trust the current information about this unit.
......@@ -1893,6 +1882,30 @@ fn analyzeNavVal(
18931882 }
18941883 }
18951884
1885 // We're about to resolve the value of the Nav. This causes the information about what the value
1886 // was last update to be lost; therefore, if the `nav_ty` is currently out of date, it would
1887 // incorrectly think it was unchanged when eventually analyzed. To avoid this, we need to detect
1888 // that case and invalidate the dependee right now.
1889 if (zcu.clearOutdatedState(.wrap(.{ .nav_ty = nav_id }))) {
1890 assert(zir_decl.type_body == null); // otherwise we already resolved it with `Sema.ensureNavResolved`
1891 zcu.resetUnit(.wrap(.{ .nav_ty = nav_id }));
1892 try pt.addDependency(.wrap(.{ .nav_ty = nav_id }), .{ .nav_val = nav_id }); // inferred type depends on the value (that's us!)
1893 if (comp.debugIncremental()) {
1894 const info = try zcu.incremental_debug_state.getUnitInfo(gpa, .wrap(.{ .nav_ty = nav_id }));
1895 info.last_update_gen = zcu.generation;
1896 info.deps.clearRetainingCapacity();
1897 }
1898 const type_changed: bool = switch (old_nav.status) {
1899 .unresolved => true,
1900 .type_resolved => |old| old.type != nav_ty.toIntern(),
1901 .fully_resolved => |old| ip.typeOf(old.val) != nav_ty.toIntern(),
1902 };
1903 if (type_changed) {
1904 try zcu.markDependeeOutdated(.marked_po, .{ .nav_ty = nav_id });
1905 } else {
1906 try zcu.markPoDependeeUpToDate(.{ .nav_ty = nav_id });
1907 }
1908 }
18961909 ip.resolveNavValue(io, nav_id, .{
18971910 .val = nav_val.toIntern(),
18981911 .is_const = is_const,
......@@ -1930,10 +1943,10 @@ fn analyzeNavVal(
19301943 try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern());
19311944 }
19321945
1933 switch (old_nav.status) {
1934 .unresolved, .type_resolved => return .{ .val_changed = true },
1935 .fully_resolved => |old| return .{ .val_changed = old.val != nav_val.toIntern() },
1936 }
1946 return switch (old_nav.status) {
1947 .unresolved, .type_resolved => .{ .val_changed = true },
1948 .fully_resolved => |old| .{ .val_changed = old.val != nav_val.toIntern() },
1949 };
19371950}
19381951
19391952pub fn ensureNavTypeUpToDate(
......@@ -1973,7 +1986,6 @@ pub fn ensureNavTypeUpToDate(
19731986 zcu.transitive_failed_analysis.contains(anal_unit);
19741987
19751988 if (was_outdated) {
1976 dev.check(.incremental);
19771989 zcu.resetUnit(anal_unit);
19781990 } else {
19791991 // We can trust the current information about this unit.
......@@ -2107,12 +2119,29 @@ fn analyzeNavType(
21072119
21082120 const type_body = zir_decl.type_body orelse {
21092121 // There is no type annotation, so we just need to use the declaration's value.
2122 // If the value had already been re-analyzed, it would have resolved the `nav_ty` unit as
2123 // either outdated or up-to-date. So we know that `old_nav` does contain information from
2124 // the previous update. As such, after this call, we will be able to determine whether the
2125 // type changed.
21102126 try sema.ensureNavResolved(&block, init_src, nav_id, .fully);
2111 // We don't actually know what the type of this Nav was before it was resolved, so we just
2112 // have to assume we were outdated. This isn't too bad, because assuming there was also no
2113 // type annotation last update, we should only be re-analyzed if the value changes (it's our
2114 // only dependency), or if there was a dependency loop.
2115 return .{ .type_changed = true };
2127 const new = ip.getNav(nav_id).status.fully_resolved;
2128 const new_is_extern_decl = ip.indexToKey(new.val) == .@"extern";
2129 const changed = switch (old_nav.status) {
2130 .unresolved => true,
2131 .type_resolved => |r| r.type != ip.typeOf(new.val) or
2132 r.alignment != new.alignment or
2133 r.@"linksection" != new.@"linksection" or
2134 r.@"addrspace" != new.@"addrspace" or
2135 r.is_const != new.is_const or
2136 r.is_extern_decl != new_is_extern_decl,
2137 .fully_resolved => |r| ip.typeOf(r.val) != ip.typeOf(new.val) or
2138 r.alignment != new.alignment or
2139 r.@"linksection" != new.@"linksection" or
2140 r.@"addrspace" != new.@"addrspace" or
2141 r.is_const != new.is_const or
2142 (old_nav.getExtern(ip) != null) != new_is_extern_decl,
2143 };
2144 return .{ .type_changed = changed };
21162145 };
21172146
21182147 block.comptime_reason = .{ .reason = .{
......@@ -2210,7 +2239,6 @@ pub fn ensureFuncBodyUpToDate(
22102239 const prev_failed = zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit);
22112240
22122241 if (was_outdated) {
2213 dev.check(.incremental);
22142242 zcu.resetUnit(anal_unit);
22152243 } else {
22162244 // We can trust the current information about this function.
......@@ -2292,7 +2320,7 @@ fn analyzeFuncBody(
22922320
22932321 var air = try pt.analyzeFuncBodyInner(func_index, reason);
22942322 var air_owned = true;
2295 errdefer if (air_owned) air.deinit(gpa);
2323 defer if (air_owned) air.deinit(gpa);
22962324
22972325 const ies_outdated = !func.analysisUnordered(ip).inferred_error_set or
22982326 func.resolvedErrorSetUnordered(ip) != old_resolved_ies;
src/codegen/c.zig+3-3
......@@ -7132,9 +7132,9 @@ fn formatIntLiteral(data: FormatIntLiteralContext, w: *Writer) Writer.Error!void
71327132 var limb_buf: [std.math.big.int.calcTwosCompLimbCount(65535)]std.math.big.Limb = undefined;
71337133 for (0..big.limbs_len) |limb_index| {
71347134 if (limb_index != 0) try w.writeAll(", ");
7135 const limb_bit_offset: u64 = switch (target.cpu.arch.endian()) {
7136 .little => limb_index * big.limb_size.bits(),
7137 .big => (big.limbs_len - limb_index - 1) * big.limb_size.bits(),
7135 const limb_bit_offset: u16 = switch (target.cpu.arch.endian()) {
7136 .little => @intCast(limb_index * big.limb_size.bits()),
7137 .big => @intCast((big.limbs_len - limb_index - 1) * big.limb_size.bits()),
71387138 };
71397139 var limb_bigint: std.math.big.int.Mutable = .{
71407140 .limbs = &limb_buf,
src/codegen/llvm.zig+1-1
......@@ -2432,7 +2432,7 @@ pub const Object = struct {
24322432 const debug_payload_type = try o.builder.debugUnionType(
24332433 payload_name: {
24342434 if (layout.tag_size == 0) break :payload_name name;
2435 break :payload_name try o.builder.metadataStringFmt("{s}:Payload", .{name.slice(&o.builder)});
2435 break :payload_name try o.builder.metadataStringFmt("{f}:Payload", .{ty.fmt(pt)});
24362436 },
24372437 file,
24382438 scope,
src/link.zig+4-1
......@@ -1557,7 +1557,10 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
15571557 .link_func => |codegen_task| nav: {
15581558 timer.pause(io);
15591559 const func, var mir = codegen_task.wait(&zcu.codegen_task_pool, io) catch |err| switch (err) {
1560 error.Canceled, error.AlreadyReported => return,
1560 error.Canceled, error.AlreadyReported => {
1561 comp.link_prog_node.completeOne();
1562 return;
1563 },
15611564 };
15621565 defer mir.deinit(zcu);
15631566 timer.@"resume"(io);
src/link/Dwarf.zig+101-9
......@@ -3344,6 +3344,7 @@ pub fn updateConstIncomplete(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index
33443344}
33453345fn updateConstIncompleteInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.ConstPool.Index, value_index: InternPool.Index) !void {
33463346 const zcu = pt.zcu;
3347 const ip = &zcu.intern_pool;
33473348
33483349 const val: Value = .fromInterned(value_index);
33493350
......@@ -3383,20 +3384,109 @@ fn updateConstIncompleteInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_inde
33833384 .debug_loclists = .init(dwarf.gpa),
33843385 };
33853386 defer wip_nav.deinit();
3386 switch (val.typeOf(zcu).toIntern()) {
3387 .type_type => {
3388 try wip_nav.abbrevCode(.generated_empty_struct_type);
3389 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3390 try wip_nav.debug_info.writer.writeByte(@intFromBool(true));
3387
3388 switch (ip.indexToKey(value_index)) {
3389 // Container types still need to be valid namespaces.
3390 .struct_type => {
3391 const loaded_struct = ip.loadStructType(value_index);
3392 const root_of_file: ?Zcu.File.Index = if (loaded_struct.zir_index.resolveFull(ip)) |r| f: {
3393 if (r.inst != .main_struct_inst) break :f null;
3394 break :f r.file;
3395 } else null;
3396 if (root_of_file) |file_index| {
3397 assert(loaded_struct.name_nav == .none);
3398 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, file_index);
3399 try wip_nav.abbrevCode(.empty_file);
3400 try wip_nav.debug_info.writer.writeUleb128(file_gop.index);
3401 try wip_nav.strp(loaded_struct.name.toSlice(ip));
3402 } else {
3403 try dwarf.emitIncompleteContainerType(
3404 &wip_nav,
3405 loaded_struct.zir_index,
3406 loaded_struct.name,
3407 loaded_struct.name_nav,
3408 );
3409 }
33913410 },
3392 else => |ty| {
3393 try wip_nav.abbrevCode(.undefined_comptime_value);
3394 try wip_nav.refType(.fromInterned(ty));
3411 .union_type => {
3412 const loaded_union = ip.loadUnionType(value_index);
3413 try dwarf.emitIncompleteContainerType(
3414 &wip_nav,
3415 loaded_union.zir_index,
3416 loaded_union.name,
3417 loaded_union.name_nav,
3418 );
3419 },
3420 .enum_type => {
3421 const loaded_enum = ip.loadEnumType(value_index);
3422 if (loaded_enum.zir_index.unwrap()) |zir_index| {
3423 try dwarf.emitIncompleteContainerType(
3424 &wip_nav,
3425 zir_index,
3426 loaded_enum.name,
3427 loaded_enum.name_nav,
3428 );
3429 } else {
3430 try wip_nav.abbrevCode(.generated_empty_struct_type);
3431 try wip_nav.strp(loaded_enum.name.toSlice(ip));
3432 try wip_nav.debug_info.writer.writeByte(@intFromBool(true));
3433 }
3434 },
3435 .opaque_type => {
3436 const loaded_opaque = ip.loadOpaqueType(value_index);
3437 try dwarf.emitIncompleteContainerType(
3438 &wip_nav,
3439 loaded_opaque.zir_index,
3440 loaded_opaque.name,
3441 loaded_opaque.name_nav,
3442 );
3443 },
3444 // Not a container type, so just emit a dummy entry. If `val` happens to be a type, we'll
3445 // emit it as if it were an opaque type so that we can name it.
3446 else => |val_key| switch (val_key.typeOf()) {
3447 .type_type => {
3448 try wip_nav.abbrevCode(.generated_empty_struct_type);
3449 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3450 try wip_nav.debug_info.writer.writeByte(@intFromBool(true));
3451 },
3452 else => |ty| {
3453 try wip_nav.abbrevCode(.undefined_comptime_value);
3454 try wip_nav.refType(.fromInterned(ty));
3455 },
33953456 },
33963457 }
33973458 try dwarf.debug_info.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_info.written());
33983459 try dwarf.debug_loclists.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_loclists.written());
33993460}
3461fn emitIncompleteContainerType(
3462 dwarf: *Dwarf,
3463 wip_nav: *WipNav,
3464 zir_index: InternPool.TrackedInst.Index,
3465 name: InternPool.NullTerminatedString,
3466 name_nav: InternPool.Nav.Index.Optional,
3467) !void {
3468 const zcu = wip_nav.pt.zcu;
3469 const ip = &zcu.intern_pool;
3470 const file = zir_index.resolveFile(ip);
3471 if (name_nav.unwrap()) |nav_index| {
3472 const nav = ip.getNav(nav_index);
3473 const decl_inst = nav.srcInst(ip).resolve(ip).?;
3474 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
3475 try wip_nav.declCommon(.{
3476 .decl = .decl_namespace_struct,
3477 .generic_decl = .generic_decl_const,
3478 .decl_instance = .decl_instance_namespace_struct,
3479 }, &nav, file, &decl);
3480 try wip_nav.debug_info.writer.writeByte(@intFromBool(true));
3481 } else {
3482 const diw = &wip_nav.debug_info.writer;
3483 const file_gop = try dwarf.getModInfo(wip_nav.unit).files.getOrPut(dwarf.gpa, file);
3484 try wip_nav.abbrevCode(.empty_struct_type);
3485 try diw.writeUleb128(file_gop.index);
3486 try wip_nav.strp(name.toSlice(ip));
3487 try diw.writeByte(@intFromBool(true));
3488 }
3489}
34003490/// Should only be called by the `link.ConstPool` implementation.
34013491///
34023492/// Emits a DIE for the given comptime-only value (which may be a type).
......@@ -3418,6 +3508,8 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
34183508 val.typeOf(zcu).assertHasLayout(zcu);
34193509 }
34203510
3511 if (value_index == .anyerror_type) return; // handled in `flush` instead
3512
34213513 const value_ip_key = ip.indexToKey(value_index);
34223514 switch (value_ip_key) {
34233515 .func => return, // populated by the Nav instead (`updateComptimeNav` or `initWipNav`)
......@@ -3746,7 +3838,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
37463838 try wip_nav.abbrevCode(.void_type);
37473839 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
37483840 },
3749 .anyerror => return, // delay until flush
3841 .anyerror => unreachable, // already did early return above
37503842 .adhoc_inferred_error_set => unreachable,
37513843 },
37523844 .tuple_type => |tuple_type| if (tuple_type.types.len == 0) {
tools/incr-check.zig+8-8
......@@ -311,12 +311,12 @@ const Eval = struct {
311311 .error_bundle => {
312312 const result_error_bundle = try std.zig.Server.allocErrorBundle(arena, body);
313313 if (stderr.bufferedLen() > 0) {
314 const stderr_data = try mr.toOwnedSlice(1);
315314 if (eval.allow_stderr) {
316 std.log.info("error_bundle stderr:\n{s}", .{stderr_data});
315 std.log.info("error_bundle stderr:\n{s}", .{stderr.buffered()});
317316 } else {
318 eval.fatal("error_bundle unexpected stderr:\n{s}", .{stderr_data});
317 eval.fatal("error_bundle unexpected stderr:\n{s}", .{stderr.buffered()});
319318 }
319 stderr.tossBuffered();
320320 }
321321 if (result_error_bundle.errorMessageCount() != 0) {
322322 try eval.checkErrorOutcome(update, result_error_bundle);
......@@ -327,15 +327,15 @@ const Eval = struct {
327327 .emit_digest => {
328328 var r: std.Io.Reader = .fixed(body);
329329 _ = r.takeStruct(std.zig.Server.Message.EmitDigest, .little) catch unreachable;
330
330331 if (stderr.bufferedLen() > 0) {
331 const stderr_data = try mr.toOwnedSlice(1);
332332 if (eval.allow_stderr) {
333 std.log.info("emit_digest stderr:\n{s}", .{stderr_data});
333 std.log.info("emit_digest stderr:\n{s}", .{stderr.buffered()});
334334 } else {
335 eval.fatal("emit_digest unexpected stderr:\n{s}", .{stderr_data});
335 eval.fatal("emit_digest unexpected stderr:\n{s}", .{stderr.buffered()});
336336 }
337 stderr.tossBuffered();
337338 }
338
339339 if (eval.target.backend == .sema) {
340340 try eval.checkSuccessOutcome(update, null, prog_node);
341341 continue;
......@@ -369,7 +369,7 @@ const Eval = struct {
369369 }
370370
371371 waitChild(eval.child, eval);
372 eval.fatal("compiler failed to send error_bundle or emit_bin_path", .{});
372 eval.fatal("compiler failed to send terminating error_bundle", .{});
373373 }
374374
375375 fn checkErrorOutcome(eval: *Eval, update: Case.Update, error_bundle: std.zig.ErrorBundle) !void {