From 26d4fd5276eaaa939cf21a516265101c551b62f2 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 26 Aug 2024 00:42:32 -0400 Subject: [PATCH] Zcu: avoid trying to link failed container types and contained navs --- src/Air.zig | 5 ++++- src/Air/types_resolved.zig | 12 ++++++++---- src/Zcu/PerThread.zig | 15 ++++++++++++--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/Air.zig b/src/Air.zig index 2e45024919ed62a8b6142fcde5eb1d56e3a0c6b6..5bbde222519e3550f0c5b0dbd06a3ddd7c091913 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -13,6 +13,7 @@ const Value = @import("Value.zig"); const Type = @import("Type.zig"); const InternPool = @import("InternPool.zig"); const Zcu = @import("Zcu.zig"); +const types_resolved = @import("Air/types_resolved.zig"); instructions: std.MultiArrayList(Inst).Slice, /// The meaning of this data is determined by `Inst.Tag` value. @@ -1899,4 +1900,6 @@ pub fn unwrapSwitch(air: *const Air, switch_inst: Inst.Index) UnwrappedSwitch { }; } -pub const typesFullyResolved = @import("Air/types_resolved.zig").typesFullyResolved; +pub const typesFullyResolved = types_resolved.typesFullyResolved; +pub const typeFullyResolved = types_resolved.checkType; +pub const valFullyResolved = types_resolved.checkVal; diff --git a/src/Air/types_resolved.zig b/src/Air/types_resolved.zig index f51e4c2aea552bc779a9c03e64eb9b60f255a728..06258f9130d352ed718edeb7da1a8e8fb0d6acac 100644 --- a/src/Air/types_resolved.zig +++ b/src/Air/types_resolved.zig @@ -432,8 +432,10 @@ fn checkRef(ref: Air.Inst.Ref, zcu: *Zcu) bool { return checkVal(Value.fromInterned(ip_index), zcu); } -fn checkVal(val: Value, zcu: *Zcu) bool { - if (!checkType(val.typeOf(zcu), zcu)) return false; +pub fn checkVal(val: Value, zcu: *Zcu) bool { + const ty = val.typeOf(zcu); + if (!checkType(ty, zcu)) return false; + if (ty.toIntern() == .type_type and !checkType(val.toType(), zcu)) return false; // Check for lazy values switch (zcu.intern_pool.indexToKey(val.toIntern())) { .int => |int| switch (int.storage) { @@ -446,9 +448,11 @@ fn checkVal(val: Value, zcu: *Zcu) bool { } } -fn checkType(ty: Type, zcu: *Zcu) bool { +pub fn checkType(ty: Type, zcu: *Zcu) bool { const ip = &zcu.intern_pool; - return switch (ty.zigTypeTag(zcu)) { + return switch (ty.zigTypeTagOrPoison(zcu) catch |err| switch (err) { + error.GenericPoison => return true, + }) { .Type, .Void, .Bool, diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index b5038ff04575f8fbaafe4e31bc5f7a259b630fb8..67e0e9ee8b110f30a165ddf03432134e757ba7db 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -2560,12 +2560,17 @@ pub fn populateTestFunctions( pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { const zcu = pt.zcu; const comp = zcu.comp; + const ip = &zcu.intern_pool; const nav = zcu.intern_pool.getNav(nav_index); - const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(&zcu.intern_pool), 0); + const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(ip), 0); defer codegen_prog_node.end(); - if (comp.bin_file) |lf| { + if (!Air.valFullyResolved(zcu.navValue(nav_index), zcu)) { + // The value of this nav failed to resolve. This is a transitive failure. + // TODO: do we need to mark this failure anywhere? I don't think so, since compilation + // will fail due to the type error anyway. + } else if (comp.bin_file) |lf| { lf.updateNav(pt, nav_index) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, error.AnalysisFail => { @@ -2605,7 +2610,11 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) !void const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0); defer codegen_prog_node.end(); - if (comp.bin_file) |lf| { + if (!Air.typeFullyResolved(Type.fromInterned(ty), zcu)) { + // This type failed to resolve. This is a transitive failure. + // TODO: do we need to mark this failure anywhere? I don't think so, since compilation + // will fail due to the type error anyway. + } else if (comp.bin_file) |lf| { lf.updateContainerType(pt, ty) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, else => |e| log.err("codegen type failed: {s}", .{@errorName(e)}), -- 2.54.0