Skip to content

Commit 26d4fd5

Browse files
committed
Zcu: avoid trying to link failed container types and contained navs
1 parent 8c3f6c7 commit 26d4fd5

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

src/Air.zig

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const Value = @import("Value.zig");
1313
const Type = @import("Type.zig");
1414
const InternPool = @import("InternPool.zig");
1515
const Zcu = @import("Zcu.zig");
16+
const types_resolved = @import("Air/types_resolved.zig");
1617

1718
instructions: std.MultiArrayList(Inst).Slice,
1819
/// 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 {
18991900
};
19001901
}
19011902

1902-
pub const typesFullyResolved = @import("Air/types_resolved.zig").typesFullyResolved;
1903+
pub const typesFullyResolved = types_resolved.typesFullyResolved;
1904+
pub const typeFullyResolved = types_resolved.checkType;
1905+
pub const valFullyResolved = types_resolved.checkVal;

src/Air/types_resolved.zig

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,10 @@ fn checkRef(ref: Air.Inst.Ref, zcu: *Zcu) bool {
432432
return checkVal(Value.fromInterned(ip_index), zcu);
433433
}
434434

435-
fn checkVal(val: Value, zcu: *Zcu) bool {
436-
if (!checkType(val.typeOf(zcu), zcu)) return false;
435+
pub fn checkVal(val: Value, zcu: *Zcu) bool {
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;
437439
// Check for lazy values
438440
switch (zcu.intern_pool.indexToKey(val.toIntern())) {
439441
.int => |int| switch (int.storage) {
@@ -446,9 +448,11 @@ fn checkVal(val: Value, zcu: *Zcu) bool {
446448
}
447449
}
448450

449-
fn checkType(ty: Type, zcu: *Zcu) bool {
451+
pub fn checkType(ty: Type, zcu: *Zcu) bool {
450452
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+
}) {
452456
.Type,
453457
.Void,
454458
.Bool,

src/Zcu/PerThread.zig

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2560,12 +2560,17 @@ pub fn populateTestFunctions(
25602560
pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
25612561
const zcu = pt.zcu;
25622562
const comp = zcu.comp;
2563+
const ip = &zcu.intern_pool;
25632564

25642565
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);
25662567
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| {
25692574
lf.updateNav(pt, nav_index) catch |err| switch (err) {
25702575
error.OutOfMemory => return error.OutOfMemory,
25712576
error.AnalysisFail => {
@@ -2605,7 +2610,11 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) !void
26052610
const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0);
26062611
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| {
26092618
lf.updateContainerType(pt, ty) catch |err| switch (err) {
26102619
error.OutOfMemory => return error.OutOfMemory,
26112620
else => |e| log.err("codegen type failed: {s}", .{@errorName(e)}),

0 commit comments

Comments
 (0)