| author | |
| committer | |
| log | c2b42383eb058f4c2bd17738cd73382e6a6672eb |
| tree | 064a6184bbb51ac4c6985deab38b0c0e5bc37132 |
| parent | 9c9a5e722b84d12de34d16f53355adbe1f5e11d3 |
| signature |
11 files changed, 246 insertions(+), 98 deletions(-)
lib/std/hash_map.zig+3-3| ... | @@ -1526,9 +1526,9 @@ pub fn HashMapUnmanaged( | ... | @@ -1526,9 +1526,9 @@ pub fn HashMapUnmanaged( |
| 1526 | } | 1526 | } |
| 1527 | 1527 | ||
| 1528 | comptime { | 1528 | comptime { |
| 1529 | if (!builtin.strip_debug_info) _ = switch (builtin.zig_backend) { | 1529 | if (!builtin.strip_debug_info) switch (builtin.zig_backend) { |
| 1530 | .stage2_llvm => &dbHelper, | 1530 | .stage2_llvm => _ = &dbHelper, |
| 1531 | .stage2_x86_64 => KV, | 1531 | .stage2_x86_64 => _ = @as(KV, undefined), |
| 1532 | else => {}, | 1532 | else => {}, |
| 1533 | }; | 1533 | }; |
| 1534 | } | 1534 | } |
src/InternPool.zig+14-2| ... | @@ -3334,11 +3334,17 @@ pub const LoadedStructType = struct { | ... | @@ -3334,11 +3334,17 @@ pub const LoadedStructType = struct { |
| 3334 | field_defaults: Index.Slice, | 3334 | field_defaults: Index.Slice, |
| 3335 | field_aligns: Alignment.Slice, | 3335 | field_aligns: Alignment.Slice, |
| 3336 | field_is_comptime_bits: ComptimeBits, | 3336 | field_is_comptime_bits: ComptimeBits, |
| 3337 | /// If `layout` is `.@"packed"`, this is `.empty`. | ||
| 3337 | field_runtime_order: RuntimeOrder.Slice, | 3338 | field_runtime_order: RuntimeOrder.Slice, |
| 3339 | /// If `layout` is `.@"packed"`, this is `.empty`. | ||
| 3338 | field_offsets: Offsets, | 3340 | field_offsets: Offsets, |
| 3341 | /// Only valid if `layout` is `.@"packed"`. | ||
| 3339 | packed_backing_int_type: Index, | 3342 | packed_backing_int_type: Index, |
| 3343 | /// Only valid if `layout` is *not* `.@"packed"`. | ||
| 3340 | class: TypeClass, | 3344 | class: TypeClass, |
| 3345 | /// Only valid if `layout` is *not* `.@"packed"`. | ||
| 3341 | size: u32, | 3346 | size: u32, |
| 3347 | /// Only valid if `layout` is *not* `.@"packed"`. | ||
| 3342 | alignment: Alignment, | 3348 | alignment: Alignment, |
| 3343 | 3349 | ||
| 3344 | pub const ComptimeBits = struct { | 3350 | pub const ComptimeBits = struct { |
| ... | @@ -3516,15 +3522,21 @@ pub const LoadedUnionType = struct { | ... | @@ -3516,15 +3522,21 @@ pub const LoadedUnionType = struct { |
| 3516 | tag_usage: TagUsage, | 3522 | tag_usage: TagUsage, |
| 3517 | /// While `tag_usage` indicates whether the union should logically contain a tag, it may be | 3523 | /// While `tag_usage` indicates whether the union should logically contain a tag, it may be |
| 3518 | /// omitted if the union layout is resolved as OPV or NPV. This field is `true` iff there is an | 3524 | /// 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`. | ||
| 3520 | has_runtime_tag: bool, | 3527 | has_runtime_tag: bool, |
| 3521 | /// Even if `tag_usage == .none` and `has_runtime_tag == false`, this is still populated with | 3528 | /// Even if `tag_usage == .none` and `has_runtime_tag == false`, this is still populated with |
| 3522 | /// the union's "hypothetical" tag type. | 3529 | /// the union's "hypothetical" tag type. |
| 3523 | enum_tag_type: Index, | 3530 | enum_tag_type: Index, |
| 3531 | /// Only valid if `layout` is `.@"packed"`. | ||
| 3524 | packed_backing_int_type: Index, | 3532 | packed_backing_int_type: Index, |
| 3533 | /// Not valid if `layout` is `.@"packed"`. | ||
| 3525 | class: TypeClass, | 3534 | class: TypeClass, |
| 3535 | /// Not valid if `layout` is `.@"packed"`. | ||
| 3526 | size: u32, | 3536 | size: u32, |
| 3537 | /// Not valid if `layout` is `.@"packed"`. | ||
| 3527 | padding: u32, | 3538 | padding: u32, |
| 3539 | /// Not valid if `layout` is `.@"packed"`. | ||
| 3528 | alignment: Alignment, | 3540 | alignment: Alignment, |
| 3529 | 3541 | ||
| 3530 | pub const TagUsage = enum(u2) { | 3542 | pub const TagUsage = enum(u2) { |
| ... | @@ -3898,7 +3910,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType { | ... | @@ -3898,7 +3910,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType { |
| 3898 | .want_layout = extra.data.bits.want_layout, | 3910 | .want_layout = extra.data.bits.want_layout, |
| 3899 | .field_types = field_types, | 3911 | .field_types = field_types, |
| 3900 | .field_aligns = .empty, | 3912 | .field_aligns = .empty, |
| 3901 | .has_runtime_tag = undefined, | 3913 | .has_runtime_tag = false, |
| 3902 | .class = undefined, | 3914 | .class = undefined, |
| 3903 | .size = undefined, | 3915 | .size = undefined, |
| 3904 | .padding = undefined, | 3916 | .padding = undefined, |
src/Sema.zig+50-42| ... | @@ -13777,45 +13777,44 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13777,45 +13777,44 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13777 | const many_alloc = try block.addBitCast(many_ty, mutable_alloc); | 13777 | const many_alloc = try block.addBitCast(many_ty, mutable_alloc); |
| 13778 | 13778 | ||
| 13779 | // lhs_dest_slice = dest[0..lhs.len] | 13779 | // lhs_dest_slice = dest[0..lhs.len] |
| 13780 | const slice_ty_ref = Air.internedToRef(slice_ty.toIntern()); | 13780 | if (lhs_len > 0) { |
| 13781 | const lhs_len_ref = try pt.intRef(.usize, lhs_len); | 13781 | const lhs_dest_slice = try block.addInst(.{ |
| 13782 | const lhs_dest_slice = try block.addInst(.{ | 13782 | .tag = .slice, |
| 13783 | .tag = .slice, | 13783 | .data = .{ .ty_pl = .{ |
| 13784 | .data = .{ .ty_pl = .{ | 13784 | .ty = .fromType(slice_ty), |
| 13785 | .ty = slice_ty_ref, | 13785 | .payload = try sema.addExtra(Air.Bin{ |
| 13786 | .payload = try sema.addExtra(Air.Bin{ | 13786 | .lhs = many_alloc, |
| 13787 | .lhs = many_alloc, | 13787 | .rhs = try pt.intRef(.usize, lhs_len), |
| 13788 | .rhs = lhs_len_ref, | 13788 | }), |
| 13789 | }), | 13789 | } }, |
| 13790 | } }, | 13790 | }); |
| 13791 | }); | 13791 | _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs); |
| 13792 | 13792 | } | |
| 13793 | _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs); | ||
| 13794 | 13793 | ||
| 13795 | // rhs_dest_slice = dest[lhs.len..][0..rhs.len] | 13794 | // rhs_dest_slice = dest[lhs.len..][0..rhs.len] |
| 13796 | const rhs_len_ref = try pt.intRef(.usize, rhs_len); | 13795 | if (rhs_len > 0) { |
| 13797 | const rhs_dest_offset = try block.addInst(.{ | 13796 | const rhs_dest_offset = try block.addInst(.{ |
| 13798 | .tag = .ptr_add, | 13797 | .tag = .ptr_add, |
| 13799 | .data = .{ .ty_pl = .{ | 13798 | .data = .{ .ty_pl = .{ |
| 13800 | .ty = Air.internedToRef(many_ty.toIntern()), | 13799 | .ty = Air.internedToRef(many_ty.toIntern()), |
| 13801 | .payload = try sema.addExtra(Air.Bin{ | 13800 | .payload = try sema.addExtra(Air.Bin{ |
| 13802 | .lhs = many_alloc, | 13801 | .lhs = many_alloc, |
| 13803 | .rhs = lhs_len_ref, | 13802 | .rhs = try pt.intRef(.usize, lhs_len), |
| 13804 | }), | 13803 | }), |
| 13805 | } }, | 13804 | } }, |
| 13806 | }); | 13805 | }); |
| 13807 | const rhs_dest_slice = try block.addInst(.{ | 13806 | const rhs_dest_slice = try block.addInst(.{ |
| 13808 | .tag = .slice, | 13807 | .tag = .slice, |
| 13809 | .data = .{ .ty_pl = .{ | 13808 | .data = .{ .ty_pl = .{ |
| 13810 | .ty = slice_ty_ref, | 13809 | .ty = .fromType(slice_ty), |
| 13811 | .payload = try sema.addExtra(Air.Bin{ | 13810 | .payload = try sema.addExtra(Air.Bin{ |
| 13812 | .lhs = rhs_dest_offset, | 13811 | .lhs = rhs_dest_offset, |
| 13813 | .rhs = rhs_len_ref, | 13812 | .rhs = try pt.intRef(.usize, rhs_len), |
| 13814 | }), | 13813 | }), |
| 13815 | } }, | 13814 | } }, |
| 13816 | }); | 13815 | }); |
| 13817 | 13816 | _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs); | |
| 13818 | _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs); | 13817 | } |
| 13819 | 13818 | ||
| 13820 | if (res_sent_val) |sent_val| { | 13819 | if (res_sent_val) |sent_val| { |
| 13821 | const elem_index = try pt.intRef(.usize, result_len); | 13820 | const elem_index = try pt.intRef(.usize, result_len); |
| ... | @@ -18829,7 +18828,7 @@ fn finishStructInit( | ... | @@ -18829,7 +18828,7 @@ fn finishStructInit( |
| 18829 | return sema.addConstantMaybeRef(sema.resolveValue(final_val_ref).?, is_ref); | 18828 | return sema.addConstantMaybeRef(sema.resolveValue(final_val_ref).?, is_ref); |
| 18830 | }, | 18829 | }, |
| 18831 | .@"packed" => { | 18830 | .@"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)); |
| 18833 | var bit_offset: u16 = 0; | 18832 | var bit_offset: u16 = 0; |
| 18834 | for (field_inits) |field_init| { | 18833 | for (field_inits) |field_init| { |
| 18835 | const field_val = sema.resolveValue(field_init).?; | 18834 | const field_val = sema.resolveValue(field_init).?; |
| ... | @@ -21113,7 +21112,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData | ... | @@ -21113,7 +21112,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 21113 | else => unreachable, | 21112 | else => unreachable, |
| 21114 | }; | 21113 | }; |
| 21115 | 21114 | ||
| 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)) { |
| 21117 | return sema.fail(block, src, "'error.{f}' not a member of error set '{f}'", .{ | 21116 | return sema.fail(block, src, "'error.{f}' not a member of error set '{f}'", .{ |
| 21118 | err_name.fmt(ip), dest_err_ty.fmt(pt), | 21117 | err_name.fmt(ip), dest_err_ty.fmt(pt), |
| 21119 | }); | 21118 | }); |
| ... | @@ -25186,9 +25185,18 @@ pub fn explainWhyTypeIsNotExtern( | ... | @@ -25186,9 +25185,18 @@ pub fn explainWhyTypeIsNotExtern( |
| 25186 | else => |cc| try sema.errNote(src_loc, msg, "{t} function cannot be extern", .{cc}), | 25185 | else => |cc| try sema.errNote(src_loc, msg, "{t} function cannot be extern", .{cc}), |
| 25187 | }, | 25186 | }, |
| 25188 | .@"enum" => { | 25187 | .@"enum" => { |
| 25189 | const tag_ty = ty.intTagType(zcu); | 25188 | const enum_obj = zcu.intern_pool.loadEnumType(ty.toIntern()); |
| 25190 | try sema.errNote(src_loc, msg, "enum tag type '{f}' is not extern compatible", .{tag_ty.fmt(pt)}); | 25189 | switch (enum_obj.int_tag_mode) { |
| 25191 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position); | 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 | } | ||
| 25192 | }, | 25200 | }, |
| 25193 | .@"struct" => { | 25201 | .@"struct" => { |
| 25194 | const struct_obj = zcu.intern_pool.loadStructType(ty.toIntern()); | 25202 | 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 { | ... | @@ -895,7 +895,7 @@ pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value { |
| 895 | // Avoid hitting gpa for accesses to small packed structs | 895 | // Avoid hitting gpa for accesses to small packed structs |
| 896 | var sfba_state = std.heap.stackFallback(128, zcu.comp.gpa); | 896 | var sfba_state = std.heap.stackFallback(128, zcu.comp.gpa); |
| 897 | const sfba = sfba_state.get(); | 897 | 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)); |
| 899 | defer sfba.free(buf); | 899 | defer sfba.free(buf); |
| 900 | int_val.writeToPackedMemory(pt, buf, 0) catch |err| switch (err) { | 900 | int_val.writeToPackedMemory(pt, buf, 0) catch |err| switch (err) { |
| 901 | error.ReinterpretDeclRef => unreachable, // it's an integer | 901 | error.ReinterpretDeclRef => unreachable, // it's an integer |
| ... | @@ -2419,7 +2419,7 @@ pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory | ... | @@ -2419,7 +2419,7 @@ pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory |
| 2419 | } | 2419 | } |
| 2420 | for (field_vals, 0..) |*field_val, field_idx| { | 2420 | for (field_vals, 0..) |*field_val, field_idx| { |
| 2421 | if (field_val.* == .none) { | 2421 | 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]; |
| 2423 | if (default_init == .none) return error.TypeMismatch; | 2423 | if (default_init == .none) return error.TypeMismatch; |
| 2424 | field_val.* = default_init; | 2424 | field_val.* = default_init; |
| 2425 | } | 2425 | } |
src/Zcu.zig+6-1| ... | @@ -3686,6 +3686,11 @@ pub const ImportResult = struct { | ... | @@ -3686,6 +3686,11 @@ pub const ImportResult = struct { |
| 3686 | pub fn resetUnit(zcu: *Zcu, unit: AnalUnit) void { | 3686 | pub fn resetUnit(zcu: *Zcu, unit: AnalUnit) void { |
| 3687 | const gpa = zcu.comp.gpa; | 3687 | const gpa = zcu.comp.gpa; |
| 3688 | 3688 | ||
| 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 | |||
| 3689 | // Compile errors | 3694 | // Compile errors |
| 3690 | if (zcu.failed_analysis.fetchSwapRemove(unit)) |kv| { | 3695 | if (zcu.failed_analysis.fetchSwapRemove(unit)) |kv| { |
| 3691 | kv.value.destroy(gpa); | 3696 | kv.value.destroy(gpa); |
| ... | @@ -4309,7 +4314,7 @@ fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.AutoArrayHashMapUnmanag | ... | @@ -4309,7 +4314,7 @@ fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.AutoArrayHashMapUnmanag |
| 4309 | }); | 4314 | }); |
| 4310 | const gop = try units.getOrPut(gpa, other); | 4315 | const gop = try units.getOrPut(gpa, other); |
| 4311 | if (gop.found_existing) break :queue_paired; | 4316 | 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 |
| 4313 | } | 4318 | } |
| 4314 | 4319 | ||
| 4315 | refs_log.debug("handle unit '{f}'", .{zcu.fmtAnalUnit(unit)}); | 4320 | refs_log.debug("handle unit '{f}'", .{zcu.fmtAnalUnit(unit)}); |
src/Zcu/PerThread.zig+54-26| ... | @@ -1075,7 +1075,6 @@ pub fn ensureMemoizedStateUpToDate( | ... | @@ -1075,7 +1075,6 @@ pub fn ensureMemoizedStateUpToDate( |
| 1075 | const prev_failed = zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit); | 1075 | const prev_failed = zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit); |
| 1076 | 1076 | ||
| 1077 | if (was_outdated) { | 1077 | if (was_outdated) { |
| 1078 | dev.check(.incremental); | ||
| 1079 | zcu.resetUnit(unit); | 1078 | zcu.resetUnit(unit); |
| 1080 | } else { | 1079 | } else { |
| 1081 | if (prev_failed) return error.AnalysisFail; | 1080 | if (prev_failed) return error.AnalysisFail; |
| ... | @@ -1193,10 +1192,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU | ... | @@ -1193,10 +1192,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU |
| 1193 | const was_outdated = zcu.clearOutdatedState(anal_unit); | 1192 | const was_outdated = zcu.clearOutdatedState(anal_unit); |
| 1194 | 1193 | ||
| 1195 | if (was_outdated) { | 1194 | if (was_outdated) { |
| 1196 | // `was_outdated` can be true in the initial update for comptime units, so this isn't a `dev.check`. | 1195 | zcu.resetUnit(anal_unit); |
| 1197 | if (dev.env.supports(.incremental)) { | ||
| 1198 | zcu.resetUnit(anal_unit); | ||
| 1199 | } | ||
| 1200 | } else { | 1196 | } else { |
| 1201 | // We can trust the current information about this unit. | 1197 | // We can trust the current information about this unit. |
| 1202 | if (zcu.failed_analysis.contains(anal_unit)) return error.AnalysisFail; | 1198 | if (zcu.failed_analysis.contains(anal_unit)) return error.AnalysisFail; |
| ... | @@ -1366,10 +1362,7 @@ pub fn ensureTypeLayoutUpToDate( | ... | @@ -1366,10 +1362,7 @@ pub fn ensureTypeLayoutUpToDate( |
| 1366 | }; | 1362 | }; |
| 1367 | 1363 | ||
| 1368 | if (was_outdated) { | 1364 | if (was_outdated) { |
| 1369 | // `was_outdated` is true in the initial update, so this isn't a `dev.check`. | 1365 | zcu.resetUnit(anal_unit); |
| 1370 | if (dev.env.supports(.incremental)) { | ||
| 1371 | zcu.resetUnit(anal_unit); | ||
| 1372 | } | ||
| 1373 | // For types, we already know that we have to invalidate all dependees. | 1366 | // For types, we already know that we have to invalidate all dependees. |
| 1374 | // TODO: we actually *could* detect whether everything was the same. should we bother? | 1367 | // TODO: we actually *could* detect whether everything was the same. should we bother? |
| 1375 | try zcu.markDependeeOutdated(.marked_po, .{ .type_layout = ty.toIntern() }); | 1368 | try zcu.markDependeeOutdated(.marked_po, .{ .type_layout = ty.toIntern() }); |
| ... | @@ -1492,10 +1485,7 @@ pub fn ensureStructDefaultsUpToDate( | ... | @@ -1492,10 +1485,7 @@ pub fn ensureStructDefaultsUpToDate( |
| 1492 | }; | 1485 | }; |
| 1493 | 1486 | ||
| 1494 | if (was_outdated) { | 1487 | if (was_outdated) { |
| 1495 | // `was_outdated` is true in the initial update, so this isn't a `dev.check`. | 1488 | zcu.resetUnit(anal_unit); |
| 1496 | if (dev.env.supports(.incremental)) { | ||
| 1497 | zcu.resetUnit(anal_unit); | ||
| 1498 | } | ||
| 1499 | // For types, we already know that we have to invalidate all dependees. | 1489 | // For types, we already know that we have to invalidate all dependees. |
| 1500 | // TODO: we actually *could* detect whether everything was the same. should we bother? | 1490 | // TODO: we actually *could* detect whether everything was the same. should we bother? |
| 1501 | try zcu.markDependeeOutdated(.marked_po, .{ .struct_defaults = ty.toIntern() }); | 1491 | try zcu.markDependeeOutdated(.marked_po, .{ .struct_defaults = ty.toIntern() }); |
| ... | @@ -1609,7 +1599,6 @@ pub fn ensureNavValUpToDate( | ... | @@ -1609,7 +1599,6 @@ pub fn ensureNavValUpToDate( |
| 1609 | zcu.transitive_failed_analysis.contains(anal_unit); | 1599 | zcu.transitive_failed_analysis.contains(anal_unit); |
| 1610 | 1600 | ||
| 1611 | if (was_outdated) { | 1601 | if (was_outdated) { |
| 1612 | dev.check(.incremental); | ||
| 1613 | zcu.resetUnit(anal_unit); | 1602 | zcu.resetUnit(anal_unit); |
| 1614 | } else { | 1603 | } else { |
| 1615 | // We can trust the current information about this unit. | 1604 | // We can trust the current information about this unit. |
| ... | @@ -1893,6 +1882,30 @@ fn analyzeNavVal( | ... | @@ -1893,6 +1882,30 @@ fn analyzeNavVal( |
| 1893 | } | 1882 | } |
| 1894 | } | 1883 | } |
| 1895 | 1884 | ||
| 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 | } | ||
| 1896 | ip.resolveNavValue(io, nav_id, .{ | 1909 | ip.resolveNavValue(io, nav_id, .{ |
| 1897 | .val = nav_val.toIntern(), | 1910 | .val = nav_val.toIntern(), |
| 1898 | .is_const = is_const, | 1911 | .is_const = is_const, |
| ... | @@ -1930,10 +1943,10 @@ fn analyzeNavVal( | ... | @@ -1930,10 +1943,10 @@ fn analyzeNavVal( |
| 1930 | try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern()); | 1943 | try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern()); |
| 1931 | } | 1944 | } |
| 1932 | 1945 | ||
| 1933 | switch (old_nav.status) { | 1946 | return switch (old_nav.status) { |
| 1934 | .unresolved, .type_resolved => return .{ .val_changed = true }, | 1947 | .unresolved, .type_resolved => .{ .val_changed = true }, |
| 1935 | .fully_resolved => |old| return .{ .val_changed = old.val != nav_val.toIntern() }, | 1948 | .fully_resolved => |old| .{ .val_changed = old.val != nav_val.toIntern() }, |
| 1936 | } | 1949 | }; |
| 1937 | } | 1950 | } |
| 1938 | 1951 | ||
| 1939 | pub fn ensureNavTypeUpToDate( | 1952 | pub fn ensureNavTypeUpToDate( |
| ... | @@ -1973,7 +1986,6 @@ pub fn ensureNavTypeUpToDate( | ... | @@ -1973,7 +1986,6 @@ pub fn ensureNavTypeUpToDate( |
| 1973 | zcu.transitive_failed_analysis.contains(anal_unit); | 1986 | zcu.transitive_failed_analysis.contains(anal_unit); |
| 1974 | 1987 | ||
| 1975 | if (was_outdated) { | 1988 | if (was_outdated) { |
| 1976 | dev.check(.incremental); | ||
| 1977 | zcu.resetUnit(anal_unit); | 1989 | zcu.resetUnit(anal_unit); |
| 1978 | } else { | 1990 | } else { |
| 1979 | // We can trust the current information about this unit. | 1991 | // We can trust the current information about this unit. |
| ... | @@ -2107,12 +2119,29 @@ fn analyzeNavType( | ... | @@ -2107,12 +2119,29 @@ fn analyzeNavType( |
| 2107 | 2119 | ||
| 2108 | const type_body = zir_decl.type_body orelse { | 2120 | const type_body = zir_decl.type_body orelse { |
| 2109 | // There is no type annotation, so we just need to use the declaration's value. | 2121 | // 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. | ||
| 2110 | try sema.ensureNavResolved(&block, init_src, nav_id, .fully); | 2126 | 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 | 2127 | const new = ip.getNav(nav_id).status.fully_resolved; |
| 2112 | // have to assume we were outdated. This isn't too bad, because assuming there was also no | 2128 | const new_is_extern_decl = ip.indexToKey(new.val) == .@"extern"; |
| 2113 | // type annotation last update, we should only be re-analyzed if the value changes (it's our | 2129 | const changed = switch (old_nav.status) { |
| 2114 | // only dependency), or if there was a dependency loop. | 2130 | .unresolved => true, |
| 2115 | return .{ .type_changed = 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 }; | ||
| 2116 | }; | 2145 | }; |
| 2117 | 2146 | ||
| 2118 | block.comptime_reason = .{ .reason = .{ | 2147 | block.comptime_reason = .{ .reason = .{ |
| ... | @@ -2210,7 +2239,6 @@ pub fn ensureFuncBodyUpToDate( | ... | @@ -2210,7 +2239,6 @@ pub fn ensureFuncBodyUpToDate( |
| 2210 | const prev_failed = zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit); | 2239 | const prev_failed = zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit); |
| 2211 | 2240 | ||
| 2212 | if (was_outdated) { | 2241 | if (was_outdated) { |
| 2213 | dev.check(.incremental); | ||
| 2214 | zcu.resetUnit(anal_unit); | 2242 | zcu.resetUnit(anal_unit); |
| 2215 | } else { | 2243 | } else { |
| 2216 | // We can trust the current information about this function. | 2244 | // We can trust the current information about this function. |
| ... | @@ -2292,7 +2320,7 @@ fn analyzeFuncBody( | ... | @@ -2292,7 +2320,7 @@ fn analyzeFuncBody( |
| 2292 | 2320 | ||
| 2293 | var air = try pt.analyzeFuncBodyInner(func_index, reason); | 2321 | var air = try pt.analyzeFuncBodyInner(func_index, reason); |
| 2294 | var air_owned = true; | 2322 | var air_owned = true; |
| 2295 | errdefer if (air_owned) air.deinit(gpa); | 2323 | defer if (air_owned) air.deinit(gpa); |
| 2296 | 2324 | ||
| 2297 | const ies_outdated = !func.analysisUnordered(ip).inferred_error_set or | 2325 | const ies_outdated = !func.analysisUnordered(ip).inferred_error_set or |
| 2298 | func.resolvedErrorSetUnordered(ip) != old_resolved_ies; | 2326 | 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 | ... | @@ -7132,9 +7132,9 @@ fn formatIntLiteral(data: FormatIntLiteralContext, w: *Writer) Writer.Error!void |
| 7132 | var limb_buf: [std.math.big.int.calcTwosCompLimbCount(65535)]std.math.big.Limb = undefined; | 7132 | var limb_buf: [std.math.big.int.calcTwosCompLimbCount(65535)]std.math.big.Limb = undefined; |
| 7133 | for (0..big.limbs_len) |limb_index| { | 7133 | for (0..big.limbs_len) |limb_index| { |
| 7134 | if (limb_index != 0) try w.writeAll(", "); | 7134 | if (limb_index != 0) try w.writeAll(", "); |
| 7135 | const limb_bit_offset: u64 = switch (target.cpu.arch.endian()) { | 7135 | const limb_bit_offset: u16 = switch (target.cpu.arch.endian()) { |
| 7136 | .little => limb_index * big.limb_size.bits(), | 7136 | .little => @intCast(limb_index * big.limb_size.bits()), |
| 7137 | .big => (big.limbs_len - limb_index - 1) * big.limb_size.bits(), | 7137 | .big => @intCast((big.limbs_len - limb_index - 1) * big.limb_size.bits()), |
| 7138 | }; | 7138 | }; |
| 7139 | var limb_bigint: std.math.big.int.Mutable = .{ | 7139 | var limb_bigint: std.math.big.int.Mutable = .{ |
| 7140 | .limbs = &limb_buf, | 7140 | .limbs = &limb_buf, |
src/codegen/llvm.zig+1-1| ... | @@ -2432,7 +2432,7 @@ pub const Object = struct { | ... | @@ -2432,7 +2432,7 @@ pub const Object = struct { |
| 2432 | const debug_payload_type = try o.builder.debugUnionType( | 2432 | const debug_payload_type = try o.builder.debugUnionType( |
| 2433 | payload_name: { | 2433 | payload_name: { |
| 2434 | if (layout.tag_size == 0) break :payload_name name; | 2434 | 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)}); |
| 2436 | }, | 2436 | }, |
| 2437 | file, | 2437 | file, |
| 2438 | scope, | 2438 | scope, |
src/link.zig+4-1| ... | @@ -1557,7 +1557,10 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void | ... | @@ -1557,7 +1557,10 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void |
| 1557 | .link_func => |codegen_task| nav: { | 1557 | .link_func => |codegen_task| nav: { |
| 1558 | timer.pause(io); | 1558 | timer.pause(io); |
| 1559 | const func, var mir = codegen_task.wait(&zcu.codegen_task_pool, io) catch |err| switch (err) { | 1559 | 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 | }, | ||
| 1561 | }; | 1564 | }; |
| 1562 | defer mir.deinit(zcu); | 1565 | defer mir.deinit(zcu); |
| 1563 | timer.@"resume"(io); | 1566 | timer.@"resume"(io); |
src/link/Dwarf.zig+101-9| ... | @@ -3344,6 +3344,7 @@ pub fn updateConstIncomplete(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index | ... | @@ -3344,6 +3344,7 @@ pub fn updateConstIncomplete(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index |
| 3344 | } | 3344 | } |
| 3345 | fn updateConstIncompleteInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.ConstPool.Index, value_index: InternPool.Index) !void { | 3345 | fn updateConstIncompleteInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.ConstPool.Index, value_index: InternPool.Index) !void { |
| 3346 | const zcu = pt.zcu; | 3346 | const zcu = pt.zcu; |
| 3347 | const ip = &zcu.intern_pool; | ||
| 3347 | 3348 | ||
| 3348 | const val: Value = .fromInterned(value_index); | 3349 | const val: Value = .fromInterned(value_index); |
| 3349 | 3350 | ||
| ... | @@ -3383,20 +3384,109 @@ fn updateConstIncompleteInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_inde | ... | @@ -3383,20 +3384,109 @@ fn updateConstIncompleteInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_inde |
| 3383 | .debug_loclists = .init(dwarf.gpa), | 3384 | .debug_loclists = .init(dwarf.gpa), |
| 3384 | }; | 3385 | }; |
| 3385 | defer wip_nav.deinit(); | 3386 | defer wip_nav.deinit(); |
| 3386 | switch (val.typeOf(zcu).toIntern()) { | 3387 | |
| 3387 | .type_type => { | 3388 | switch (ip.indexToKey(value_index)) { |
| 3388 | try wip_nav.abbrevCode(.generated_empty_struct_type); | 3389 | // Container types still need to be valid namespaces. |
| 3389 | try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)}); | 3390 | .struct_type => { |
| 3390 | try wip_nav.debug_info.writer.writeByte(@intFromBool(true)); | 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 | } | ||
| 3391 | }, | 3410 | }, |
| 3392 | else => |ty| { | 3411 | .union_type => { |
| 3393 | try wip_nav.abbrevCode(.undefined_comptime_value); | 3412 | const loaded_union = ip.loadUnionType(value_index); |
| 3394 | try wip_nav.refType(.fromInterned(ty)); | 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 | }, | ||
| 3395 | }, | 3456 | }, |
| 3396 | } | 3457 | } |
| 3397 | try dwarf.debug_info.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_info.written()); | 3458 | try dwarf.debug_info.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_info.written()); |
| 3398 | try dwarf.debug_loclists.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_loclists.written()); | 3459 | try dwarf.debug_loclists.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_loclists.written()); |
| 3399 | } | 3460 | } |
| 3461 | fn 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 | } | ||
| 3400 | /// Should only be called by the `link.ConstPool` implementation. | 3490 | /// Should only be called by the `link.ConstPool` implementation. |
| 3401 | /// | 3491 | /// |
| 3402 | /// Emits a DIE for the given comptime-only value (which may be a type). | 3492 | /// 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 | ... | @@ -3418,6 +3508,8 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3418 | val.typeOf(zcu).assertHasLayout(zcu); | 3508 | val.typeOf(zcu).assertHasLayout(zcu); |
| 3419 | } | 3509 | } |
| 3420 | 3510 | ||
| 3511 | if (value_index == .anyerror_type) return; // handled in `flush` instead | ||
| 3512 | |||
| 3421 | const value_ip_key = ip.indexToKey(value_index); | 3513 | const value_ip_key = ip.indexToKey(value_index); |
| 3422 | switch (value_ip_key) { | 3514 | switch (value_ip_key) { |
| 3423 | .func => return, // populated by the Nav instead (`updateComptimeNav` or `initWipNav`) | 3515 | .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 | ... | @@ -3746,7 +3838,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3746 | try wip_nav.abbrevCode(.void_type); | 3838 | try wip_nav.abbrevCode(.void_type); |
| 3747 | try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)}); | 3839 | try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)}); |
| 3748 | }, | 3840 | }, |
| 3749 | .anyerror => return, // delay until flush | 3841 | .anyerror => unreachable, // already did early return above |
| 3750 | .adhoc_inferred_error_set => unreachable, | 3842 | .adhoc_inferred_error_set => unreachable, |
| 3751 | }, | 3843 | }, |
| 3752 | .tuple_type => |tuple_type| if (tuple_type.types.len == 0) { | 3844 | .tuple_type => |tuple_type| if (tuple_type.types.len == 0) { |
tools/incr-check.zig+8-8| ... | @@ -311,12 +311,12 @@ const Eval = struct { | ... | @@ -311,12 +311,12 @@ const Eval = struct { |
| 311 | .error_bundle => { | 311 | .error_bundle => { |
| 312 | const result_error_bundle = try std.zig.Server.allocErrorBundle(arena, body); | 312 | const result_error_bundle = try std.zig.Server.allocErrorBundle(arena, body); |
| 313 | if (stderr.bufferedLen() > 0) { | 313 | if (stderr.bufferedLen() > 0) { |
| 314 | const stderr_data = try mr.toOwnedSlice(1); | ||
| 315 | if (eval.allow_stderr) { | 314 | 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()}); |
| 317 | } else { | 316 | } else { |
| 318 | eval.fatal("error_bundle unexpected stderr:\n{s}", .{stderr_data}); | 317 | eval.fatal("error_bundle unexpected stderr:\n{s}", .{stderr.buffered()}); |
| 319 | } | 318 | } |
| 319 | stderr.tossBuffered(); | ||
| 320 | } | 320 | } |
| 321 | if (result_error_bundle.errorMessageCount() != 0) { | 321 | if (result_error_bundle.errorMessageCount() != 0) { |
| 322 | try eval.checkErrorOutcome(update, result_error_bundle); | 322 | try eval.checkErrorOutcome(update, result_error_bundle); |
| ... | @@ -327,15 +327,15 @@ const Eval = struct { | ... | @@ -327,15 +327,15 @@ const Eval = struct { |
| 327 | .emit_digest => { | 327 | .emit_digest => { |
| 328 | var r: std.Io.Reader = .fixed(body); | 328 | var r: std.Io.Reader = .fixed(body); |
| 329 | _ = r.takeStruct(std.zig.Server.Message.EmitDigest, .little) catch unreachable; | 329 | _ = r.takeStruct(std.zig.Server.Message.EmitDigest, .little) catch unreachable; |
| 330 | |||
| 330 | if (stderr.bufferedLen() > 0) { | 331 | if (stderr.bufferedLen() > 0) { |
| 331 | const stderr_data = try mr.toOwnedSlice(1); | ||
| 332 | if (eval.allow_stderr) { | 332 | 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()}); |
| 334 | } else { | 334 | } else { |
| 335 | eval.fatal("emit_digest unexpected stderr:\n{s}", .{stderr_data}); | 335 | eval.fatal("emit_digest unexpected stderr:\n{s}", .{stderr.buffered()}); |
| 336 | } | 336 | } |
| 337 | stderr.tossBuffered(); | ||
| 337 | } | 338 | } |
| 338 | |||
| 339 | if (eval.target.backend == .sema) { | 339 | if (eval.target.backend == .sema) { |
| 340 | try eval.checkSuccessOutcome(update, null, prog_node); | 340 | try eval.checkSuccessOutcome(update, null, prog_node); |
| 341 | continue; | 341 | continue; |
| ... | @@ -369,7 +369,7 @@ const Eval = struct { | ... | @@ -369,7 +369,7 @@ const Eval = struct { |
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | waitChild(eval.child, eval); | 371 | 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", .{}); |
| 373 | } | 373 | } |
| 374 | 374 | ||
| 375 | fn checkErrorOutcome(eval: *Eval, update: Case.Update, error_bundle: std.zig.ErrorBundle) !void { | 375 | fn checkErrorOutcome(eval: *Eval, update: Case.Update, error_bundle: std.zig.ErrorBundle) !void { |