authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-26 00:42:32-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-27 02:09:59-04:00
log26d4fd5276eaaa939cf21a516265101c551b62f2
treef0adbe73252a37aebf70063287288094d7699307
parent8c3f6c72c07e853e28cf7226a3f76da2fd5a9c6e

Zcu: avoid trying to link failed container types and contained navs


3 files changed, 24 insertions(+), 8 deletions(-)

src/Air.zig+4-1
...@@ -13,6 +13,7 @@ const Value = @import("Value.zig");...@@ -13,6 +13,7 @@ const Value = @import("Value.zig");
13const Type = @import("Type.zig");13const Type = @import("Type.zig");
14const InternPool = @import("InternPool.zig");14const InternPool = @import("InternPool.zig");
15const Zcu = @import("Zcu.zig");15const Zcu = @import("Zcu.zig");
16const types_resolved = @import("Air/types_resolved.zig");
1617
17instructions: std.MultiArrayList(Inst).Slice,18instructions: std.MultiArrayList(Inst).Slice,
18/// The meaning of this data is determined by `Inst.Tag` value.19/// 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 {...@@ -1899,4 +1900,6 @@ pub fn unwrapSwitch(air: *const Air, switch_inst: Inst.Index) UnwrappedSwitch {
1899 };1900 };
1900}1901}
19011902
1902pub const typesFullyResolved = @import("Air/types_resolved.zig").typesFullyResolved;1903pub const typesFullyResolved = types_resolved.typesFullyResolved;
1904pub const typeFullyResolved = types_resolved.checkType;
1905pub const valFullyResolved = types_resolved.checkVal;
src/Air/types_resolved.zig+8-4
...@@ -432,8 +432,10 @@ fn checkRef(ref: Air.Inst.Ref, zcu: *Zcu) bool {...@@ -432,8 +432,10 @@ fn checkRef(ref: Air.Inst.Ref, zcu: *Zcu) bool {
432 return checkVal(Value.fromInterned(ip_index), zcu);432 return checkVal(Value.fromInterned(ip_index), zcu);
433}433}
434434
435fn checkVal(val: Value, zcu: *Zcu) bool {435pub fn checkVal(val: Value, zcu: *Zcu) bool {
436 if (!checkType(val.typeOf(zcu), zcu)) return false;436 const ty = val.typeOf(zcu);
437 if (!checkType(ty, zcu)) return false;
438 if (ty.toIntern() == .type_type and !checkType(val.toType(), zcu)) return false;
437 // Check for lazy values439 // Check for lazy values
438 switch (zcu.intern_pool.indexToKey(val.toIntern())) {440 switch (zcu.intern_pool.indexToKey(val.toIntern())) {
439 .int => |int| switch (int.storage) {441 .int => |int| switch (int.storage) {
...@@ -446,9 +448,11 @@ fn checkVal(val: Value, zcu: *Zcu) bool {...@@ -446,9 +448,11 @@ fn checkVal(val: Value, zcu: *Zcu) bool {
446 }448 }
447}449}
448450
449fn checkType(ty: Type, zcu: *Zcu) bool {451pub fn checkType(ty: Type, zcu: *Zcu) bool {
450 const ip = &zcu.intern_pool;452 const ip = &zcu.intern_pool;
451 return switch (ty.zigTypeTag(zcu)) {453 return switch (ty.zigTypeTagOrPoison(zcu) catch |err| switch (err) {
454 error.GenericPoison => return true,
455 }) {
452 .Type,456 .Type,
453 .Void,457 .Void,
454 .Bool,458 .Bool,
src/Zcu/PerThread.zig+12-3
...@@ -2560,12 +2560,17 @@ pub fn populateTestFunctions(...@@ -2560,12 +2560,17 @@ pub fn populateTestFunctions(
2560pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {2560pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
2561 const zcu = pt.zcu;2561 const zcu = pt.zcu;
2562 const comp = zcu.comp;2562 const comp = zcu.comp;
2563 const ip = &zcu.intern_pool;
25632564
2564 const nav = zcu.intern_pool.getNav(nav_index);2565 const nav = zcu.intern_pool.getNav(nav_index);
2565 const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(&zcu.intern_pool), 0);2566 const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(ip), 0);
2566 defer codegen_prog_node.end();2567 defer codegen_prog_node.end();
25672568
2568 if (comp.bin_file) |lf| {2569 if (!Air.valFullyResolved(zcu.navValue(nav_index), zcu)) {
2570 // The value of this nav failed to resolve. This is a transitive failure.
2571 // TODO: do we need to mark this failure anywhere? I don't think so, since compilation
2572 // will fail due to the type error anyway.
2573 } else if (comp.bin_file) |lf| {
2569 lf.updateNav(pt, nav_index) catch |err| switch (err) {2574 lf.updateNav(pt, nav_index) catch |err| switch (err) {
2570 error.OutOfMemory => return error.OutOfMemory,2575 error.OutOfMemory => return error.OutOfMemory,
2571 error.AnalysisFail => {2576 error.AnalysisFail => {
...@@ -2605,7 +2610,11 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) !void...@@ -2605,7 +2610,11 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) !void
2605 const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0);2610 const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0);
2606 defer codegen_prog_node.end();2611 defer codegen_prog_node.end();
26072612
2608 if (comp.bin_file) |lf| {2613 if (!Air.typeFullyResolved(Type.fromInterned(ty), zcu)) {
2614 // This type failed to resolve. This is a transitive failure.
2615 // TODO: do we need to mark this failure anywhere? I don't think so, since compilation
2616 // will fail due to the type error anyway.
2617 } else if (comp.bin_file) |lf| {
2609 lf.updateContainerType(pt, ty) catch |err| switch (err) {2618 lf.updateContainerType(pt, ty) catch |err| switch (err) {
2610 error.OutOfMemory => return error.OutOfMemory,2619 error.OutOfMemory => return error.OutOfMemory,
2611 else => |e| log.err("codegen type failed: {s}", .{@errorName(e)}),2620 else => |e| log.err("codegen type failed: {s}", .{@errorName(e)}),