| author | |
| committer | |
| log | 26d4fd5276eaaa939cf21a516265101c551b62f2 |
| tree | f0adbe73252a37aebf70063287288094d7699307 |
| parent | 8c3f6c72c07e853e28cf7226a3f76da2fd5a9c6e |
3 files changed, 24 insertions(+), 8 deletions(-)
src/Air.zig+4-1| ... | ... | @@ -13,6 +13,7 @@ const Value = @import("Value.zig"); |
| 13 | 13 | const Type = @import("Type.zig"); |
| 14 | 14 | const InternPool = @import("InternPool.zig"); |
| 15 | 15 | const Zcu = @import("Zcu.zig"); |
| 16 | const types_resolved = @import("Air/types_resolved.zig"); | |
| 16 | 17 | |
| 17 | 18 | instructions: std.MultiArrayList(Inst).Slice, |
| 18 | 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 | 1900 | }; |
| 1900 | 1901 | } |
| 1901 | 1902 | |
| 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+8-4| ... | ... | @@ -432,8 +432,10 @@ fn checkRef(ref: Air.Inst.Ref, zcu: *Zcu) bool { |
| 432 | 432 | return checkVal(Value.fromInterned(ip_index), zcu); |
| 433 | 433 | } |
| 434 | 434 | |
| 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; | |
| 437 | 439 | // Check for lazy values |
| 438 | 440 | switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 439 | 441 | .int => |int| switch (int.storage) { |
| ... | ... | @@ -446,9 +448,11 @@ fn checkVal(val: Value, zcu: *Zcu) bool { |
| 446 | 448 | } |
| 447 | 449 | } |
| 448 | 450 | |
| 449 | fn checkType(ty: Type, zcu: *Zcu) bool { | |
| 451 | pub fn checkType(ty: Type, zcu: *Zcu) bool { | |
| 450 | 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 | 456 | .Type, |
| 453 | 457 | .Void, |
| 454 | 458 | .Bool, |
src/Zcu/PerThread.zig+12-3| ... | ... | @@ -2560,12 +2560,17 @@ pub fn populateTestFunctions( |
| 2560 | 2560 | pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { |
| 2561 | 2561 | const zcu = pt.zcu; |
| 2562 | 2562 | const comp = zcu.comp; |
| 2563 | const ip = &zcu.intern_pool; | |
| 2563 | 2564 | |
| 2564 | 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 | 2567 | defer codegen_prog_node.end(); |
| 2567 | 2568 | |
| 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 | 2574 | lf.updateNav(pt, nav_index) catch |err| switch (err) { |
| 2570 | 2575 | error.OutOfMemory => return error.OutOfMemory, |
| 2571 | 2576 | error.AnalysisFail => { |
| ... | ... | @@ -2605,7 +2610,11 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) !void |
| 2605 | 2610 | const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0); |
| 2606 | 2611 | defer codegen_prog_node.end(); |
| 2607 | 2612 | |
| 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 | 2618 | lf.updateContainerType(pt, ty) catch |err| switch (err) { |
| 2610 | 2619 | error.OutOfMemory => return error.OutOfMemory, |
| 2611 | 2620 | else => |e| log.err("codegen type failed: {s}", .{@errorName(e)}), |