authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-26 05:51:34+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-26 13:48:07+00:00
log2a245e3b78890e5d1b65492e51d9fe509ec35b3c
tree00e839ff9a0ae4a871d282b4e86fbd9baeab701a
parenta61def10c66abc871f92c84d9cef85b6b7752cbf
signaturelock-open Commit is signed but in an unrecognized format.

compiler: eliminate TypedValue

The only logic which remained in this file was the Value printing logic. This has been moved into a new `print_value.zig`.

10 files changed, 386 insertions(+), 438 deletions(-)

CMakeLists.txt+2-1
......@@ -526,7 +526,6 @@ set(ZIG_STAGE2_SOURCES
526526 "${CMAKE_SOURCE_DIR}/src/Package/Fetch.zig"
527527 "${CMAKE_SOURCE_DIR}/src/RangeSet.zig"
528528 "${CMAKE_SOURCE_DIR}/src/Sema.zig"
529 "${CMAKE_SOURCE_DIR}/src/TypedValue.zig"
530529 "${CMAKE_SOURCE_DIR}/src/Value.zig"
531530 "${CMAKE_SOURCE_DIR}/src/arch/aarch64/CodeGen.zig"
532531 "${CMAKE_SOURCE_DIR}/src/arch/aarch64/Emit.zig"
......@@ -634,9 +633,11 @@ set(ZIG_STAGE2_SOURCES
634633 "${CMAKE_SOURCE_DIR}/src/main.zig"
635634 "${CMAKE_SOURCE_DIR}/src/mingw.zig"
636635 "${CMAKE_SOURCE_DIR}/src/musl.zig"
636 "${CMAKE_SOURCE_DIR}/src/mutable_value.zig"
637637 "${CMAKE_SOURCE_DIR}/src/print_air.zig"
638638 "${CMAKE_SOURCE_DIR}/src/print_env.zig"
639639 "${CMAKE_SOURCE_DIR}/src/print_targets.zig"
640 "${CMAKE_SOURCE_DIR}/src/print_value.zig"
640641 "${CMAKE_SOURCE_DIR}/src/print_zir.zig"
641642 "${CMAKE_SOURCE_DIR}/src/register_manager.zig"
642643 "${CMAKE_SOURCE_DIR}/src/target.zig"
src/Sema.zig+52-54
......@@ -2272,7 +2272,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty:
22722272 if (int_ty.zigTypeTag(mod) == .Vector) {
22732273 const msg = msg: {
22742274 const msg = try sema.errMsg(block, src, "overflow of vector type '{}' with value '{}'", .{
2275 int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod),
2275 int_ty.fmt(sema.mod), val.fmtValue(sema.mod),
22762276 });
22772277 errdefer msg.destroy(sema.gpa);
22782278 try sema.errNote(block, src, msg, "when computing vector element at index '{d}'", .{vector_index});
......@@ -2281,7 +2281,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty:
22812281 return sema.failWithOwnedErrorMsg(block, msg);
22822282 }
22832283 return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{
2284 int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod),
2284 int_ty.fmt(sema.mod), val.fmtValue(sema.mod),
22852285 });
22862286}
22872287
......@@ -2914,7 +2914,7 @@ fn createAnonymousDeclTypeNamed(
29142914 return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null);
29152915
29162916 if (arg_i != 0) try writer.writeByte(',');
2917 try writer.print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)});
2917 try writer.print("{}", .{arg_val.fmtValue(sema.mod)});
29182918
29192919 arg_i += 1;
29202920 continue;
......@@ -3186,7 +3186,7 @@ fn zirEnumDecl(
31863186 }).lazy;
31873187 const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy;
31883188 const msg = msg: {
3189 const msg = try sema.errMsg(block, value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(int_tag_ty, sema.mod)});
3189 const msg = try sema.errMsg(block, value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod)});
31903190 errdefer msg.destroy(gpa);
31913191 try sema.errNote(block, other_field_src, msg, "other occurrence here", .{});
31923192 break :msg msg;
......@@ -3206,7 +3206,7 @@ fn zirEnumDecl(
32063206 const field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = field_i }).lazy;
32073207 const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy;
32083208 const msg = msg: {
3209 const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(int_tag_ty, sema.mod)});
3209 const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod)});
32103210 errdefer msg.destroy(gpa);
32113211 try sema.errNote(block, other_field_src, msg, "other occurrence here", .{});
32123212 break :msg msg;
......@@ -3228,7 +3228,7 @@ fn zirEnumDecl(
32283228 .range = if (has_tag_value) .value else .name,
32293229 }).lazy;
32303230 const msg = try sema.errMsg(block, value_src, "enumeration value '{}' too large for type '{}'", .{
3231 last_tag_val.?.fmtValue(int_tag_ty, mod), int_tag_ty.fmt(mod),
3231 last_tag_val.?.fmtValue(mod), int_tag_ty.fmt(mod),
32323232 });
32333233 return sema.failWithOwnedErrorMsg(block, msg);
32343234 }
......@@ -4381,10 +4381,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
43814381 .input_index = len_idx,
43824382 } };
43834383 try sema.errNote(block, a_src, msg, "length {} here", .{
4384 v.fmtValue(Type.usize, sema.mod),
4384 v.fmtValue(sema.mod),
43854385 });
43864386 try sema.errNote(block, arg_src, msg, "length {} here", .{
4387 arg_val.fmtValue(Type.usize, sema.mod),
4387 arg_val.fmtValue(sema.mod),
43884388 });
43894389 break :msg msg;
43904390 };
......@@ -5794,7 +5794,7 @@ fn zirCompileLog(
57945794 const arg_ty = sema.typeOf(arg);
57955795 if (try sema.resolveValueResolveLazy(arg)) |val| {
57965796 try writer.print("@as({}, {})", .{
5797 arg_ty.fmt(mod), val.fmtValue(arg_ty, mod),
5797 arg_ty.fmt(mod), val.fmtValue(mod),
57985798 });
57995799 } else {
58005800 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(mod)});
......@@ -8880,7 +8880,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
88808880 return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());
88818881 }
88828882 return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{
8883 int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod),
8883 int_val.fmtValue(mod), dest_ty.fmt(mod),
88848884 });
88858885 }
88868886 if (int_val.isUndef(mod)) {
......@@ -8888,7 +8888,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
88888888 }
88898889 if (!(try sema.enumHasInt(dest_ty, int_val))) {
88908890 return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{
8891 dest_ty.fmt(mod), int_val.fmtValue(sema.typeOf(operand), mod),
8891 dest_ty.fmt(mod), int_val.fmtValue(mod),
88928892 });
88938893 }
88948894 return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());
......@@ -13934,7 +13934,7 @@ fn zirShl(
1393413934 const rhs_elem = try rhs_val.elemValue(mod, i);
1393513935 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {
1393613936 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
13937 rhs_elem.fmtValue(scalar_ty, mod),
13937 rhs_elem.fmtValue(mod),
1393813938 i,
1393913939 scalar_ty.fmt(mod),
1394013940 });
......@@ -13942,7 +13942,7 @@ fn zirShl(
1394213942 }
1394313943 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {
1394413944 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
13945 rhs_val.fmtValue(scalar_ty, mod),
13945 rhs_val.fmtValue(mod),
1394613946 scalar_ty.fmt(mod),
1394713947 });
1394813948 }
......@@ -13953,14 +13953,14 @@ fn zirShl(
1395313953 const rhs_elem = try rhs_val.elemValue(mod, i);
1395413954 if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) {
1395513955 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
13956 rhs_elem.fmtValue(scalar_ty, mod),
13956 rhs_elem.fmtValue(mod),
1395713957 i,
1395813958 });
1395913959 }
1396013960 }
1396113961 } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {
1396213962 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
13963 rhs_val.fmtValue(scalar_ty, mod),
13963 rhs_val.fmtValue(mod),
1396413964 });
1396513965 }
1396613966 }
......@@ -14099,7 +14099,7 @@ fn zirShr(
1409914099 const rhs_elem = try rhs_val.elemValue(mod, i);
1410014100 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {
1410114101 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
14102 rhs_elem.fmtValue(scalar_ty, mod),
14102 rhs_elem.fmtValue(mod),
1410314103 i,
1410414104 scalar_ty.fmt(mod),
1410514105 });
......@@ -14107,7 +14107,7 @@ fn zirShr(
1410714107 }
1410814108 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {
1410914109 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
14110 rhs_val.fmtValue(scalar_ty, mod),
14110 rhs_val.fmtValue(mod),
1411114111 scalar_ty.fmt(mod),
1411214112 });
1411314113 }
......@@ -14118,14 +14118,14 @@ fn zirShr(
1411814118 const rhs_elem = try rhs_val.elemValue(mod, i);
1411914119 if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) {
1412014120 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
14121 rhs_elem.fmtValue(scalar_ty, mod),
14121 rhs_elem.fmtValue(mod),
1412214122 i,
1412314123 });
1412414124 }
1412514125 }
1412614126 } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {
1412714127 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
14128 rhs_val.fmtValue(scalar_ty, mod),
14128 rhs_val.fmtValue(mod),
1412914129 });
1413014130 }
1413114131 if (maybe_lhs_val) |lhs_val| {
......@@ -15046,7 +15046,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1504615046 block,
1504715047 src,
1504815048 "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'",
15049 .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(resolved_type, mod) },
15049 .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(mod) },
1505015050 );
1505115051 }
1505215052 }
......@@ -21094,7 +21094,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2109421094 const enum_decl = mod.declPtr(enum_decl_index);
2109521095 const msg = msg: {
2109621096 const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{}'", .{
21097 val.fmtValue(enum_ty, sema.mod), enum_decl.name.fmt(ip),
21097 val.fmtValue(sema.mod), enum_decl.name.fmt(ip),
2109821098 });
2109921099 errdefer msg.destroy(sema.gpa);
2110021100 try mod.errNoteNonLazy(enum_decl.srcLoc(mod), msg, "declared here", .{});
......@@ -21729,7 +21729,7 @@ fn reifyEnum(
2172921729 // TODO: better source location
2173021730 return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{
2173121731 field_name.fmt(ip),
21732 field_value_val.fmtValue(Type.comptime_int, mod),
21732 field_value_val.fmtValue(mod),
2173321733 tag_ty.fmt(mod),
2173421734 });
2173521735 }
......@@ -21745,7 +21745,7 @@ fn reifyEnum(
2174521745 break :msg msg;
2174621746 },
2174721747 .value => msg: {
21748 const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{field_value_val.fmtValue(Type.comptime_int, mod)});
21748 const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{field_value_val.fmtValue(mod)});
2174921749 errdefer msg.destroy(gpa);
2175021750 _ = conflict.prev_field_idx; // TODO: this note is incorrect
2175121751 try sema.errNote(block, src, msg, "other enum tag value here", .{});
......@@ -22883,12 +22883,12 @@ fn ptrCastFull(
2288322883 return sema.failWithOwnedErrorMsg(block, msg: {
2288422884 const msg = if (src_info.sentinel == .none) blk: {
2288522885 break :blk try sema.errMsg(block, src, "destination pointer requires '{}' sentinel", .{
22886 Value.fromInterned(dest_info.sentinel).fmtValue(Type.fromInterned(dest_info.child), mod),
22886 Value.fromInterned(dest_info.sentinel).fmtValue(mod),
2288722887 });
2288822888 } else blk: {
2288922889 break :blk try sema.errMsg(block, src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{
22890 Value.fromInterned(src_info.sentinel).fmtValue(Type.fromInterned(src_info.child), mod),
22891 Value.fromInterned(dest_info.sentinel).fmtValue(Type.fromInterned(dest_info.child), mod),
22890 Value.fromInterned(src_info.sentinel).fmtValue(mod),
22891 Value.fromInterned(dest_info.sentinel).fmtValue(mod),
2289222892 });
2289322893 };
2289422894 errdefer msg.destroy(sema.gpa);
......@@ -25285,10 +25285,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2528525285 const msg = try sema.errMsg(block, src, "non-matching @memcpy lengths", .{});
2528625286 errdefer msg.destroy(sema.gpa);
2528725287 try sema.errNote(block, dest_src, msg, "length {} here", .{
25288 dest_len_val.fmtValue(Type.usize, sema.mod),
25288 dest_len_val.fmtValue(sema.mod),
2528925289 });
2529025290 try sema.errNote(block, src_src, msg, "length {} here", .{
25291 src_len_val.fmtValue(Type.usize, sema.mod),
25291 src_len_val.fmtValue(sema.mod),
2529225292 });
2529325293 break :msg msg;
2529425294 };
......@@ -29162,7 +29162,7 @@ fn coerceExtra(
2916229162 // comptime-known integer to other number
2916329163 if (!(try sema.intFitsInType(val, dest_ty, null))) {
2916429164 if (!opts.report_err) return error.NotCoercible;
29165 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) });
29165 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(mod) });
2916629166 }
2916729167 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
2916829168 .undef => try mod.undefRef(dest_ty),
......@@ -29207,7 +29207,7 @@ fn coerceExtra(
2920729207 block,
2920829208 inst_src,
2920929209 "type '{}' cannot represent float value '{}'",
29210 .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) },
29210 .{ dest_ty.fmt(mod), val.fmtValue(mod) },
2921129211 );
2921229212 }
2921329213 return Air.internedToRef(result_val.toIntern());
......@@ -29578,11 +29578,11 @@ const InMemoryCoercionResult = union(enum) {
2957829578 .array_sentinel => |sentinel| {
2957929579 if (sentinel.actual.toIntern() != .unreachable_value) {
2958029580 try sema.errNote(block, src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{
29581 sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod),
29581 sentinel.actual.fmtValue(mod), sentinel.wanted.fmtValue(mod),
2958229582 });
2958329583 } else {
2958429584 try sema.errNote(block, src, msg, "destination array requires '{}' sentinel", .{
29585 sentinel.wanted.fmtValue(sentinel.ty, mod),
29585 sentinel.wanted.fmtValue(mod),
2958629586 });
2958729587 }
2958829588 break;
......@@ -29704,11 +29704,11 @@ const InMemoryCoercionResult = union(enum) {
2970429704 .ptr_sentinel => |sentinel| {
2970529705 if (sentinel.actual.toIntern() != .unreachable_value) {
2970629706 try sema.errNote(block, src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{
29707 sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod),
29707 sentinel.actual.fmtValue(mod), sentinel.wanted.fmtValue(mod),
2970829708 });
2970929709 } else {
2971029710 try sema.errNote(block, src, msg, "destination pointer requires '{}' sentinel", .{
29711 sentinel.wanted.fmtValue(sentinel.ty, mod),
29711 sentinel.wanted.fmtValue(mod),
2971229712 });
2971329713 }
2971429714 break;
......@@ -31708,7 +31708,7 @@ fn coerceEnumToUnion(
3170831708 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
3170931709 const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse {
3171031710 return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{
31711 union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod),
31711 union_ty.fmt(sema.mod), val.fmtValue(sema.mod),
3171231712 });
3171331713 };
3171431714
......@@ -32928,8 +32928,8 @@ fn analyzeSlice(
3292832928 msg,
3292932929 "expected '{}', found '{}'",
3293032930 .{
32931 Value.zero_comptime_int.fmtValue(Type.comptime_int, mod),
32932 start_value.fmtValue(Type.comptime_int, mod),
32931 Value.zero_comptime_int.fmtValue(mod),
32932 start_value.fmtValue(mod),
3293332933 },
3293432934 );
3293532935 break :msg msg;
......@@ -32945,8 +32945,8 @@ fn analyzeSlice(
3294532945 msg,
3294632946 "expected '{}', found '{}'",
3294732947 .{
32948 Value.one_comptime_int.fmtValue(Type.comptime_int, mod),
32949 end_value.fmtValue(Type.comptime_int, mod),
32948 Value.one_comptime_int.fmtValue(mod),
32949 end_value.fmtValue(mod),
3295032950 },
3295132951 );
3295232952 break :msg msg;
......@@ -32959,7 +32959,7 @@ fn analyzeSlice(
3295932959 block,
3296032960 end_src,
3296132961 "end index {} out of bounds for slice of single-item pointer",
32962 .{end_value.fmtValue(Type.comptime_int, mod)},
32962 .{end_value.fmtValue(mod)},
3296332963 );
3296432964 }
3296532965 }
......@@ -33054,8 +33054,8 @@ fn analyzeSlice(
3305433054 end_src,
3305533055 "end index {} out of bounds for array of length {}{s}",
3305633056 .{
33057 end_val.fmtValue(Type.usize, mod),
33058 len_val.fmtValue(Type.usize, mod),
33057 end_val.fmtValue(mod),
33058 len_val.fmtValue(mod),
3305933059 sentinel_label,
3306033060 },
3306133061 );
......@@ -33099,7 +33099,7 @@ fn analyzeSlice(
3309933099 end_src,
3310033100 "end index {} out of bounds for slice of length {d}{s}",
3310133101 .{
33102 end_val.fmtValue(Type.usize, mod),
33102 end_val.fmtValue(mod),
3310333103 try slice_val.sliceLen(sema),
3310433104 sentinel_label,
3310533105 },
......@@ -33159,8 +33159,8 @@ fn analyzeSlice(
3315933159 start_src,
3316033160 "start index {} is larger than end index {}",
3316133161 .{
33162 start_val.fmtValue(Type.usize, mod),
33163 end_val.fmtValue(Type.usize, mod),
33162 start_val.fmtValue(mod),
33163 end_val.fmtValue(mod),
3316433164 },
3316533165 );
3316633166 }
......@@ -33198,8 +33198,8 @@ fn analyzeSlice(
3319833198 const msg = try sema.errMsg(block, src, "value in memory does not match slice sentinel", .{});
3319933199 errdefer msg.destroy(sema.gpa);
3320033200 try sema.errNote(block, src, msg, "expected '{}', found '{}'", .{
33201 expected_sentinel.fmtValue(elem_ty, mod),
33202 actual_sentinel.fmtValue(elem_ty, mod),
33201 expected_sentinel.fmtValue(mod),
33202 actual_sentinel.fmtValue(mod),
3320333203 });
3320433204
3320533205 break :msg msg;
......@@ -37213,7 +37213,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
3721337213 const field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = field_i }).lazy;
3721437214 const other_field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = gop.index }).lazy;
3721537215 const msg = msg: {
37216 const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(int_tag_ty, mod)});
37216 const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(mod)});
3721737217 errdefer msg.destroy(gpa);
3721837218 try sema.errNote(&block_scope, other_field_src, msg, "other occurrence here", .{});
3721937219 break :msg msg;
......@@ -38566,18 +38566,17 @@ fn intFromFloat(
3856638566) CompileError!Value {
3856738567 const mod = sema.mod;
3856838568 if (float_ty.zigTypeTag(mod) == .Vector) {
38569 const elem_ty = float_ty.scalarType(mod);
3857038569 const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod));
3857138570 for (result_data, 0..) |*scalar, i| {
3857238571 const elem_val = try val.elemValue(sema.mod, i);
38573 scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, elem_ty, int_ty.scalarType(mod), mode)).toIntern();
38572 scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(mod), mode)).toIntern();
3857438573 }
3857538574 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
3857638575 .ty = int_ty.toIntern(),
3857738576 .storage = .{ .elems = result_data },
3857838577 } })));
3857938578 }
38580 return sema.intFromFloatScalar(block, src, val, float_ty, int_ty, mode);
38579 return sema.intFromFloatScalar(block, src, val, int_ty, mode);
3858138580}
3858238581
3858338582// float is expected to be finite and non-NaN
......@@ -38610,7 +38609,6 @@ fn intFromFloatScalar(
3861038609 block: *Block,
3861138610 src: LazySrcLoc,
3861238611 val: Value,
38613 float_ty: Type,
3861438612 int_ty: Type,
3861538613 mode: IntFromFloatMode,
3861638614) CompileError!Value {
......@@ -38622,7 +38620,7 @@ fn intFromFloatScalar(
3862238620 block,
3862338621 src,
3862438622 "fractional component prevents float value '{}' from coercion to type '{}'",
38625 .{ val.fmtValue(float_ty, mod), int_ty.fmt(mod) },
38623 .{ val.fmtValue(mod), int_ty.fmt(mod) },
3862638624 );
3862738625
3862838626 const float = val.toFloat(f128, mod);
......@@ -38644,7 +38642,7 @@ fn intFromFloatScalar(
3864438642
3864538643 if (!(try sema.intFitsInType(cti_result, int_ty, null))) {
3864638644 return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{
38647 val.fmtValue(float_ty, sema.mod), int_ty.fmt(sema.mod),
38645 val.fmtValue(sema.mod), int_ty.fmt(sema.mod),
3864838646 });
3864938647 }
3865038648 return mod.getCoerced(cti_result, int_ty);
src/TypedValue.zig deleted-363
......@@ -1,363 +0,0 @@
1//! This type exists only for legacy purposes, and will be removed in the future.
2//! It is a thin wrapper around a `Value` which also, redundantly, stores its `Type`.
3
4const std = @import("std");
5const Type = @import("type.zig").Type;
6const Value = @import("Value.zig");
7const Zcu = @import("Module.zig");
8const Module = Zcu;
9const Sema = @import("Sema.zig");
10const InternPool = @import("InternPool.zig");
11const Allocator = std.mem.Allocator;
12const TypedValue = @This();
13const Target = std.Target;
14
15ty: Type,
16val: Value,
17
18const max_aggregate_items = 100;
19const max_string_len = 256;
20
21const FormatContext = struct {
22 tv: TypedValue,
23 mod: *Module,
24};
25
26pub fn format(
27 ctx: FormatContext,
28 comptime fmt: []const u8,
29 options: std.fmt.FormatOptions,
30 writer: anytype,
31) !void {
32 _ = options;
33 comptime std.debug.assert(fmt.len == 0);
34 return ctx.tv.print(writer, 3, ctx.mod, null) catch |err| switch (err) {
35 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
36 error.ComptimeBreak, error.ComptimeReturn => unreachable,
37 error.AnalysisFail, error.NeededSourceLocation => unreachable, // TODO: re-evaluate when we actually pass `opt_sema`
38 else => |e| return e,
39 };
40}
41
42pub fn print(
43 tv: TypedValue,
44 writer: anytype,
45 level: u8,
46 mod: *Module,
47 /// If this `Sema` is provided, we will recurse through pointers where possible to provide friendly output.
48 opt_sema: ?*Sema,
49) (@TypeOf(writer).Error || Module.CompileError)!void {
50 const ip = &mod.intern_pool;
51 const val = tv.val;
52 switch (ip.indexToKey(val.toIntern())) {
53 .int_type,
54 .ptr_type,
55 .array_type,
56 .vector_type,
57 .opt_type,
58 .anyframe_type,
59 .error_union_type,
60 .simple_type,
61 .struct_type,
62 .anon_struct_type,
63 .union_type,
64 .opaque_type,
65 .enum_type,
66 .func_type,
67 .error_set_type,
68 .inferred_error_set_type,
69 => try Type.print(val.toType(), writer, mod),
70 .undef => try writer.writeAll("undefined"),
71 .simple_value => |simple_value| switch (simple_value) {
72 .void => try writer.writeAll("{}"),
73 .empty_struct => try writer.writeAll(".{}"),
74 .generic_poison => try writer.writeAll("(generic poison)"),
75 else => try writer.writeAll(@tagName(simple_value)),
76 },
77 .variable => try writer.writeAll("(variable)"),
78 .extern_func => |extern_func| try writer.print("(extern function '{}')", .{
79 mod.declPtr(extern_func.decl).name.fmt(ip),
80 }),
81 .func => |func| try writer.print("(function '{}')", .{
82 mod.declPtr(func.owner_decl).name.fmt(ip),
83 }),
84 .int => |int| switch (int.storage) {
85 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),
86 .lazy_align => |ty| if (opt_sema) |sema| {
87 const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar;
88 try writer.print("{}", .{a.toByteUnits(0)});
89 } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(mod)}),
90 .lazy_size => |ty| if (opt_sema) |sema| {
91 const s = (try Type.fromInterned(ty).abiSizeAdvanced(mod, .{ .sema = sema })).scalar;
92 try writer.print("{}", .{s});
93 } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(mod)}),
94 },
95 .err => |err| try writer.print("error.{}", .{
96 err.name.fmt(ip),
97 }),
98 .error_union => |error_union| switch (error_union.val) {
99 .err_name => |err_name| try writer.print("error.{}", .{
100 err_name.fmt(ip),
101 }),
102 .payload => |payload| try print(.{
103 .ty = tv.ty.errorUnionPayload(mod),
104 .val = Value.fromInterned(payload),
105 }, writer, level, mod, opt_sema),
106 },
107 .enum_literal => |enum_literal| try writer.print(".{}", .{
108 enum_literal.fmt(ip),
109 }),
110 .enum_tag => |enum_tag| {
111 const enum_type = ip.loadEnumType(val.typeOf(mod).toIntern());
112 if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {
113 try writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
114 return;
115 }
116 if (level == 0) {
117 try writer.writeAll("@enumFromInt(...)");
118 }
119 try writer.writeAll("@enumFromInt(");
120 try print(.{
121 .ty = Type.fromInterned(ip.typeOf(enum_tag.int)),
122 .val = Value.fromInterned(enum_tag.int),
123 }, writer, level - 1, mod, opt_sema);
124 try writer.writeAll(")");
125 },
126 .empty_enum_value => try writer.writeAll("(empty enum value)"),
127 .float => |float| switch (float.storage) {
128 inline else => |x| try writer.print("{d}", .{@as(f64, @floatCast(x))}),
129 },
130 .slice => |slice| {
131 const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) {
132 .field, .elem, .eu_payload, .opt_payload => unreachable,
133 .anon_decl, .comptime_alloc, .comptime_field => true,
134 .decl, .int => false,
135 };
136 if (print_contents) {
137 // TODO: eventually we want to load the slice as an array with `opt_sema`, but that's
138 // currently not possible without e.g. triggering compile errors.
139 }
140 try printPtr(slice.ptr, writer, false, false, 0, level, mod, opt_sema);
141 try writer.writeAll("[0..");
142 try print(.{
143 .ty = Type.usize,
144 .val = Value.fromInterned(slice.len),
145 }, writer, level - 1, mod, opt_sema);
146 try writer.writeAll("]");
147 },
148 .ptr => {
149 const print_contents = switch (ip.getBackingAddrTag(val.toIntern()).?) {
150 .field, .elem, .eu_payload, .opt_payload => unreachable,
151 .anon_decl, .comptime_alloc, .comptime_field => true,
152 .decl, .int => false,
153 };
154 if (print_contents) {
155 // TODO: eventually we want to load the pointer with `opt_sema`, but that's
156 // currently not possible without e.g. triggering compile errors.
157 }
158 try printPtr(val.toIntern(), writer, false, false, 0, level, mod, opt_sema);
159 },
160 .opt => |opt| switch (opt.val) {
161 .none => try writer.writeAll("null"),
162 else => |payload| try print(.{
163 .ty = tv.ty.childType(mod),
164 .val = Value.fromInterned(payload),
165 }, writer, level, mod, opt_sema),
166 },
167 .aggregate => |aggregate| try printAggregate(val, aggregate, writer, level, mod, opt_sema),
168 .un => |un| {
169 if (level == 0) {
170 try writer.writeAll(".{ ... }");
171 return;
172 }
173 if (un.tag == .none) {
174 const backing_ty = try tv.ty.unionBackingType(mod);
175 try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(mod)});
176 try print(.{
177 .ty = backing_ty,
178 .val = Value.fromInterned(un.val),
179 }, writer, level - 1, mod, opt_sema);
180 try writer.writeAll("))");
181 } else {
182 try writer.writeAll(".{ ");
183 try print(.{
184 .ty = tv.ty.unionTagTypeHypothetical(mod),
185 .val = Value.fromInterned(un.tag),
186 }, writer, level - 1, mod, opt_sema);
187 try writer.writeAll(" = ");
188 const field_ty = tv.ty.unionFieldType(Value.fromInterned(un.tag), mod).?;
189 try print(.{
190 .ty = field_ty,
191 .val = Value.fromInterned(un.val),
192 }, writer, level - 1, mod, opt_sema);
193 try writer.writeAll(" }");
194 }
195 },
196 .memoized_call => unreachable,
197 }
198}
199
200fn printAggregate(
201 val: Value,
202 aggregate: InternPool.Key.Aggregate,
203 writer: anytype,
204 level: u8,
205 zcu: *Zcu,
206 opt_sema: ?*Sema,
207) (@TypeOf(writer).Error || Module.CompileError)!void {
208 if (level == 0) {
209 return writer.writeAll(".{ ... }");
210 }
211 const ip = &zcu.intern_pool;
212 const ty = Type.fromInterned(aggregate.ty);
213 switch (ty.zigTypeTag(zcu)) {
214 .Struct => if (!ty.isTuple(zcu)) {
215 if (ty.structFieldCount(zcu) == 0) {
216 return writer.writeAll(".{}");
217 }
218 try writer.writeAll(".{ ");
219 const max_len = @min(ty.structFieldCount(zcu), max_aggregate_items);
220 for (0..max_len) |i| {
221 if (i != 0) try writer.writeAll(", ");
222 const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?;
223 try writer.print(".{i} = ", .{field_name.fmt(ip)});
224 try print(.{
225 .ty = ty.structFieldType(i, zcu),
226 .val = try val.fieldValue(zcu, i),
227 }, writer, level - 1, zcu, opt_sema);
228 }
229 try writer.writeAll(" }");
230 return;
231 },
232 .Array => if (aggregate.storage == .bytes) {
233 return writer.print("\"{}\".*", .{std.zig.fmtEscapes(aggregate.storage.bytes)});
234 } else if (ty.arrayLen(zcu) == 0) {
235 return writer.writeAll(".{}");
236 },
237 .Vector => if (ty.arrayLen(zcu) == 0) {
238 return writer.writeAll(".{}");
239 },
240 else => unreachable,
241 }
242
243 const elem_ty = ty.childType(zcu);
244 const len = ty.arrayLen(zcu);
245
246 try writer.writeAll(".{ ");
247
248 const max_len = @min(len, max_aggregate_items);
249 for (0..max_len) |i| {
250 if (i != 0) try writer.writeAll(", ");
251 try print(.{
252 .ty = elem_ty,
253 .val = try val.fieldValue(zcu, i),
254 }, writer, level - 1, zcu, opt_sema);
255 }
256 if (len > max_aggregate_items) {
257 try writer.writeAll(", ...");
258 }
259 return writer.writeAll(" }");
260}
261
262fn printPtr(
263 ptr_val: InternPool.Index,
264 writer: anytype,
265 force_type: bool,
266 force_addrof: bool,
267 leading_parens: u32,
268 level: u8,
269 zcu: *Zcu,
270 opt_sema: ?*Sema,
271) (@TypeOf(writer).Error || Module.CompileError)!void {
272 const ip = &zcu.intern_pool;
273 const ptr = switch (ip.indexToKey(ptr_val)) {
274 .undef => |ptr_ty| {
275 if (force_addrof) try writer.writeAll("&");
276 try writer.writeByteNTimes('(', leading_parens);
277 try writer.print("@as({}, undefined)", .{Type.fromInterned(ptr_ty).fmt(zcu)});
278 return;
279 },
280 .ptr => |ptr| ptr,
281 else => unreachable,
282 };
283 switch (ptr.addr) {
284 .int => |int| {
285 if (force_addrof) try writer.writeAll("&");
286 try writer.writeByteNTimes('(', leading_parens);
287 if (force_type) {
288 try writer.print("@as({}, @ptrFromInt(", .{Type.fromInterned(ptr.ty).fmt(zcu)});
289 try print(.{
290 .ty = Type.usize,
291 .val = Value.fromInterned(int),
292 }, writer, level - 1, zcu, opt_sema);
293 try writer.writeAll("))");
294 } else {
295 try writer.writeAll("@ptrFromInt(");
296 try print(.{
297 .ty = Type.usize,
298 .val = Value.fromInterned(int),
299 }, writer, level - 1, zcu, opt_sema);
300 try writer.writeAll(")");
301 }
302 },
303 .decl => |index| {
304 try writer.writeAll("&");
305 try zcu.declPtr(index).renderFullyQualifiedName(zcu, writer);
306 },
307 .comptime_alloc => try writer.writeAll("&(comptime alloc)"),
308 .anon_decl => |anon| {
309 const ty = Type.fromInterned(ip.typeOf(anon.val));
310 try writer.print("&@as({}, ", .{ty.fmt(zcu)});
311 try print(.{
312 .ty = ty,
313 .val = Value.fromInterned(anon.val),
314 }, writer, level - 1, zcu, opt_sema);
315 try writer.writeAll(")");
316 },
317 .comptime_field => |val| {
318 const ty = Type.fromInterned(ip.typeOf(val));
319 try writer.print("&@as({}, ", .{ty.fmt(zcu)});
320 try print(.{
321 .ty = ty,
322 .val = Value.fromInterned(val),
323 }, writer, level - 1, zcu, opt_sema);
324 try writer.writeAll(")");
325 },
326 .eu_payload => |base| {
327 try printPtr(base, writer, true, true, leading_parens, level, zcu, opt_sema);
328 try writer.writeAll(".?");
329 },
330 .opt_payload => |base| {
331 try writer.writeAll("(");
332 try printPtr(base, writer, true, true, leading_parens + 1, level, zcu, opt_sema);
333 try writer.writeAll(" catch unreachable");
334 },
335 .elem => |elem| {
336 try printPtr(elem.base, writer, true, true, leading_parens, level, zcu, opt_sema);
337 try writer.print("[{d}]", .{elem.index});
338 },
339 .field => |field| {
340 try printPtr(field.base, writer, true, true, leading_parens, level, zcu, opt_sema);
341 const base_ty = Type.fromInterned(ip.typeOf(field.base)).childType(zcu);
342 switch (base_ty.zigTypeTag(zcu)) {
343 .Struct => if (base_ty.isTuple(zcu)) {
344 try writer.print("[{d}]", .{field.index});
345 } else {
346 const field_name = base_ty.structFieldName(@intCast(field.index), zcu).unwrap().?;
347 try writer.print(".{i}", .{field_name.fmt(ip)});
348 },
349 .Union => {
350 const tag_ty = base_ty.unionTagTypeHypothetical(zcu);
351 const field_name = tag_ty.enumFieldName(@intCast(field.index), zcu);
352 try writer.print(".{i}", .{field_name.fmt(ip)});
353 },
354 .Pointer => switch (field.index) {
355 Value.slice_ptr_index => try writer.writeAll(".ptr"),
356 Value.slice_len_index => try writer.writeAll(".len"),
357 else => unreachable,
358 },
359 else => unreachable,
360 }
361 },
362 }
363}
src/Value.zig+3-3
......@@ -8,9 +8,9 @@ const Target = std.Target;
88const Allocator = std.mem.Allocator;
99const Zcu = @import("Module.zig");
1010const Module = Zcu;
11const TypedValue = @import("TypedValue.zig");
1211const Sema = @import("Sema.zig");
1312const InternPool = @import("InternPool.zig");
13const print_value = @import("print_value.zig");
1414const Value = @This();
1515
1616ip_index: InternPool.Index,
......@@ -39,9 +39,9 @@ pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) {
3939 return .{ .data = val };
4040}
4141
42pub fn fmtValue(val: Value, ty: Type, mod: *Module) std.fmt.Formatter(TypedValue.format) {
42pub fn fmtValue(val: Value, mod: *Module) std.fmt.Formatter(print_value.format) {
4343 return .{ .data = .{
44 .tv = .{ .ty = ty, .val = val },
44 .val = val,
4545 .mod = mod,
4646 } };
4747}
src/arch/x86_64/CodeGen.zig+2-5
......@@ -17876,11 +17876,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
1787617876
1787717877 break :result null;
1787817878 }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{
17879 lhs_ty.fmt(mod), rhs_ty.fmt(mod), dst_ty.fmt(mod),
17880 Value.fromInterned(extra.mask).fmtValue(
17881 Type.fromInterned(mod.intern_pool.typeOf(extra.mask)),
17882 mod,
17883 ),
17879 lhs_ty.fmt(mod), rhs_ty.fmt(mod), dst_ty.fmt(mod),
17880 Value.fromInterned(extra.mask).fmtValue(mod),
1788417881 });
1788517882 return self.finishAir(inst, result, .{ extra.a, extra.b, .none });
1788617883}
src/codegen.zig+4-6
......@@ -185,9 +185,7 @@ pub fn generateSymbol(
185185 const target = mod.getTarget();
186186 const endian = target.cpu.arch.endian();
187187
188 log.debug("generateSymbol: val = {}", .{
189 val.fmtValue(ty, mod),
190 });
188 log.debug("generateSymbol: val = {}", .{val.fmtValue(mod)});
191189
192190 if (val.isUndefDeep(mod)) {
193191 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow;
......@@ -862,7 +860,7 @@ fn genDeclRef(
862860) CodeGenError!GenResult {
863861 const zcu = lf.comp.module.?;
864862 const ty = val.typeOf(zcu);
865 log.debug("genDeclRef: val = {}", .{val.fmtValue(ty, zcu)});
863 log.debug("genDeclRef: val = {}", .{val.fmtValue(zcu)});
866864
867865 const ptr_decl = zcu.declPtr(ptr_decl_index);
868866 const namespace = zcu.namespacePtr(ptr_decl.src_namespace);
......@@ -976,7 +974,7 @@ fn genUnnamedConst(
976974) CodeGenError!GenResult {
977975 const zcu = lf.comp.module.?;
978976 const gpa = lf.comp.gpa;
979 log.debug("genUnnamedConst: val = {}", .{val.fmtValue(val.typeOf(zcu), zcu)});
977 log.debug("genUnnamedConst: val = {}", .{val.fmtValue(zcu)});
980978
981979 const local_sym_index = lf.lowerUnnamedConst(val, owner_decl_index) catch |err| {
982980 return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)});
......@@ -1016,7 +1014,7 @@ pub fn genTypedValue(
10161014 const zcu = lf.comp.module.?;
10171015 const ty = val.typeOf(zcu);
10181016
1019 log.debug("genTypedValue: val = {}", .{val.fmtValue(ty, zcu)});
1017 log.debug("genTypedValue: val = {}", .{val.fmtValue(zcu)});
10201018
10211019 if (val.isUndef(zcu))
10221020 return GenResult.mcv(.undef);
src/codegen/spirv.zig+1-1
......@@ -860,7 +860,7 @@ const DeclGen = struct {
860860
861861 const val = arg_val;
862862
863 log.debug("constant: ty = {}, val = {}", .{ ty.fmt(mod), val.fmtValue(ty, mod) });
863 log.debug("constant: ty = {}, val = {}", .{ ty.fmt(mod), val.fmtValue(mod) });
864864 if (val.isUndefDeep(mod)) {
865865 return self.spv.constUndef(result_ty_ref);
866866 }
src/print_air.zig+1-1
......@@ -951,7 +951,7 @@ const Writer = struct {
951951 const ty = Type.fromInterned(mod.intern_pool.indexToKey(ip_index).typeOf());
952952 try s.print("<{}, {}>", .{
953953 ty.fmt(mod),
954 Value.fromInterned(ip_index).fmtValue(ty, mod),
954 Value.fromInterned(ip_index).fmtValue(mod),
955955 });
956956 } else {
957957 return w.writeInstIndex(s, operand.toIndex().?, dies);
src/print_value.zig created+317
......@@ -0,0 +1,317 @@
1//! This type exists only for legacy purposes, and will be removed in the future.
2//! It is a thin wrapper around a `Value` which also, redundantly, stores its `Type`.
3
4const std = @import("std");
5const Type = @import("type.zig").Type;
6const Value = @import("Value.zig");
7const Zcu = @import("Module.zig");
8const Module = Zcu;
9const Sema = @import("Sema.zig");
10const InternPool = @import("InternPool.zig");
11const Allocator = std.mem.Allocator;
12const Target = std.Target;
13
14const max_aggregate_items = 100;
15const max_string_len = 256;
16
17const FormatContext = struct {
18 val: Value,
19 mod: *Module,
20};
21
22pub fn format(
23 ctx: FormatContext,
24 comptime fmt: []const u8,
25 options: std.fmt.FormatOptions,
26 writer: anytype,
27) !void {
28 _ = options;
29 comptime std.debug.assert(fmt.len == 0);
30 return print(ctx.val, writer, 3, ctx.mod, null) catch |err| switch (err) {
31 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
32 error.ComptimeBreak, error.ComptimeReturn => unreachable,
33 error.AnalysisFail, error.NeededSourceLocation => unreachable, // TODO: re-evaluate when we actually pass `opt_sema`
34 else => |e| return e,
35 };
36}
37
38pub fn print(
39 val: Value,
40 writer: anytype,
41 level: u8,
42 mod: *Module,
43 /// If this `Sema` is provided, we will recurse through pointers where possible to provide friendly output.
44 opt_sema: ?*Sema,
45) (@TypeOf(writer).Error || Module.CompileError)!void {
46 const ip = &mod.intern_pool;
47 switch (ip.indexToKey(val.toIntern())) {
48 .int_type,
49 .ptr_type,
50 .array_type,
51 .vector_type,
52 .opt_type,
53 .anyframe_type,
54 .error_union_type,
55 .simple_type,
56 .struct_type,
57 .anon_struct_type,
58 .union_type,
59 .opaque_type,
60 .enum_type,
61 .func_type,
62 .error_set_type,
63 .inferred_error_set_type,
64 => try Type.print(val.toType(), writer, mod),
65 .undef => try writer.writeAll("undefined"),
66 .simple_value => |simple_value| switch (simple_value) {
67 .void => try writer.writeAll("{}"),
68 .empty_struct => try writer.writeAll(".{}"),
69 .generic_poison => try writer.writeAll("(generic poison)"),
70 else => try writer.writeAll(@tagName(simple_value)),
71 },
72 .variable => try writer.writeAll("(variable)"),
73 .extern_func => |extern_func| try writer.print("(extern function '{}')", .{
74 mod.declPtr(extern_func.decl).name.fmt(ip),
75 }),
76 .func => |func| try writer.print("(function '{}')", .{
77 mod.declPtr(func.owner_decl).name.fmt(ip),
78 }),
79 .int => |int| switch (int.storage) {
80 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),
81 .lazy_align => |ty| if (opt_sema) |sema| {
82 const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar;
83 try writer.print("{}", .{a.toByteUnits(0)});
84 } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(mod)}),
85 .lazy_size => |ty| if (opt_sema) |sema| {
86 const s = (try Type.fromInterned(ty).abiSizeAdvanced(mod, .{ .sema = sema })).scalar;
87 try writer.print("{}", .{s});
88 } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(mod)}),
89 },
90 .err => |err| try writer.print("error.{}", .{
91 err.name.fmt(ip),
92 }),
93 .error_union => |error_union| switch (error_union.val) {
94 .err_name => |err_name| try writer.print("error.{}", .{
95 err_name.fmt(ip),
96 }),
97 .payload => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema),
98 },
99 .enum_literal => |enum_literal| try writer.print(".{}", .{
100 enum_literal.fmt(ip),
101 }),
102 .enum_tag => |enum_tag| {
103 const enum_type = ip.loadEnumType(val.typeOf(mod).toIntern());
104 if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {
105 try writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
106 return;
107 }
108 if (level == 0) {
109 try writer.writeAll("@enumFromInt(...)");
110 }
111 try writer.writeAll("@enumFromInt(");
112 try print(Value.fromInterned(enum_tag.int), writer, level - 1, mod, opt_sema);
113 try writer.writeAll(")");
114 },
115 .empty_enum_value => try writer.writeAll("(empty enum value)"),
116 .float => |float| switch (float.storage) {
117 inline else => |x| try writer.print("{d}", .{@as(f64, @floatCast(x))}),
118 },
119 .slice => |slice| {
120 const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) {
121 .field, .elem, .eu_payload, .opt_payload => unreachable,
122 .anon_decl, .comptime_alloc, .comptime_field => true,
123 .decl, .int => false,
124 };
125 if (print_contents) {
126 // TODO: eventually we want to load the slice as an array with `opt_sema`, but that's
127 // currently not possible without e.g. triggering compile errors.
128 }
129 try printPtr(slice.ptr, writer, false, false, 0, level, mod, opt_sema);
130 try writer.writeAll("[0..");
131 try print(Value.fromInterned(slice.len), writer, level - 1, mod, opt_sema);
132 try writer.writeAll("]");
133 },
134 .ptr => {
135 const print_contents = switch (ip.getBackingAddrTag(val.toIntern()).?) {
136 .field, .elem, .eu_payload, .opt_payload => unreachable,
137 .anon_decl, .comptime_alloc, .comptime_field => true,
138 .decl, .int => false,
139 };
140 if (print_contents) {
141 // TODO: eventually we want to load the pointer with `opt_sema`, but that's
142 // currently not possible without e.g. triggering compile errors.
143 }
144 try printPtr(val.toIntern(), writer, false, false, 0, level, mod, opt_sema);
145 },
146 .opt => |opt| switch (opt.val) {
147 .none => try writer.writeAll("null"),
148 else => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema),
149 },
150 .aggregate => |aggregate| try printAggregate(val, aggregate, writer, level, mod, opt_sema),
151 .un => |un| {
152 if (level == 0) {
153 try writer.writeAll(".{ ... }");
154 return;
155 }
156 if (un.tag == .none) {
157 const backing_ty = try val.typeOf(mod).unionBackingType(mod);
158 try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(mod)});
159 try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema);
160 try writer.writeAll("))");
161 } else {
162 try writer.writeAll(".{ ");
163 try print(Value.fromInterned(un.tag), writer, level - 1, mod, opt_sema);
164 try writer.writeAll(" = ");
165 try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema);
166 try writer.writeAll(" }");
167 }
168 },
169 .memoized_call => unreachable,
170 }
171}
172
173fn printAggregate(
174 val: Value,
175 aggregate: InternPool.Key.Aggregate,
176 writer: anytype,
177 level: u8,
178 zcu: *Zcu,
179 opt_sema: ?*Sema,
180) (@TypeOf(writer).Error || Module.CompileError)!void {
181 if (level == 0) {
182 return writer.writeAll(".{ ... }");
183 }
184 const ip = &zcu.intern_pool;
185 const ty = Type.fromInterned(aggregate.ty);
186 switch (ty.zigTypeTag(zcu)) {
187 .Struct => if (!ty.isTuple(zcu)) {
188 if (ty.structFieldCount(zcu) == 0) {
189 return writer.writeAll(".{}");
190 }
191 try writer.writeAll(".{ ");
192 const max_len = @min(ty.structFieldCount(zcu), max_aggregate_items);
193 for (0..max_len) |i| {
194 if (i != 0) try writer.writeAll(", ");
195 const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?;
196 try writer.print(".{i} = ", .{field_name.fmt(ip)});
197 try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema);
198 }
199 try writer.writeAll(" }");
200 return;
201 },
202 .Array => if (aggregate.storage == .bytes) {
203 return writer.print("\"{}\".*", .{std.zig.fmtEscapes(aggregate.storage.bytes)});
204 } else if (ty.arrayLen(zcu) == 0) {
205 return writer.writeAll(".{}");
206 },
207 .Vector => if (ty.arrayLen(zcu) == 0) {
208 return writer.writeAll(".{}");
209 },
210 else => unreachable,
211 }
212
213 const len = ty.arrayLen(zcu);
214
215 try writer.writeAll(".{ ");
216
217 const max_len = @min(len, max_aggregate_items);
218 for (0..max_len) |i| {
219 if (i != 0) try writer.writeAll(", ");
220 try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema);
221 }
222 if (len > max_aggregate_items) {
223 try writer.writeAll(", ...");
224 }
225 return writer.writeAll(" }");
226}
227
228fn printPtr(
229 ptr_val: InternPool.Index,
230 writer: anytype,
231 force_type: bool,
232 force_addrof: bool,
233 leading_parens: u32,
234 level: u8,
235 zcu: *Zcu,
236 opt_sema: ?*Sema,
237) (@TypeOf(writer).Error || Module.CompileError)!void {
238 const ip = &zcu.intern_pool;
239 const ptr = switch (ip.indexToKey(ptr_val)) {
240 .undef => |ptr_ty| {
241 if (force_addrof) try writer.writeAll("&");
242 try writer.writeByteNTimes('(', leading_parens);
243 try writer.print("@as({}, undefined)", .{Type.fromInterned(ptr_ty).fmt(zcu)});
244 return;
245 },
246 .ptr => |ptr| ptr,
247 else => unreachable,
248 };
249 switch (ptr.addr) {
250 .int => |int| {
251 if (force_addrof) try writer.writeAll("&");
252 try writer.writeByteNTimes('(', leading_parens);
253 if (force_type) {
254 try writer.print("@as({}, @ptrFromInt(", .{Type.fromInterned(ptr.ty).fmt(zcu)});
255 try print(Value.fromInterned(int), writer, level - 1, zcu, opt_sema);
256 try writer.writeAll("))");
257 } else {
258 try writer.writeAll("@ptrFromInt(");
259 try print(Value.fromInterned(int), writer, level - 1, zcu, opt_sema);
260 try writer.writeAll(")");
261 }
262 },
263 .decl => |index| {
264 try writer.writeAll("&");
265 try zcu.declPtr(index).renderFullyQualifiedName(zcu, writer);
266 },
267 .comptime_alloc => try writer.writeAll("&(comptime alloc)"),
268 .anon_decl => |anon| {
269 const ty = Type.fromInterned(ip.typeOf(anon.val));
270 try writer.print("&@as({}, ", .{ty.fmt(zcu)});
271 try print(Value.fromInterned(anon.val), writer, level - 1, zcu, opt_sema);
272 try writer.writeAll(")");
273 },
274 .comptime_field => |val| {
275 const ty = Type.fromInterned(ip.typeOf(val));
276 try writer.print("&@as({}, ", .{ty.fmt(zcu)});
277 try print(Value.fromInterned(val), writer, level - 1, zcu, opt_sema);
278 try writer.writeAll(")");
279 },
280 .eu_payload => |base| {
281 try printPtr(base, writer, true, true, leading_parens, level, zcu, opt_sema);
282 try writer.writeAll(".?");
283 },
284 .opt_payload => |base| {
285 try writer.writeAll("(");
286 try printPtr(base, writer, true, true, leading_parens + 1, level, zcu, opt_sema);
287 try writer.writeAll(" catch unreachable");
288 },
289 .elem => |elem| {
290 try printPtr(elem.base, writer, true, true, leading_parens, level, zcu, opt_sema);
291 try writer.print("[{d}]", .{elem.index});
292 },
293 .field => |field| {
294 try printPtr(field.base, writer, true, true, leading_parens, level, zcu, opt_sema);
295 const base_ty = Type.fromInterned(ip.typeOf(field.base)).childType(zcu);
296 switch (base_ty.zigTypeTag(zcu)) {
297 .Struct => if (base_ty.isTuple(zcu)) {
298 try writer.print("[{d}]", .{field.index});
299 } else {
300 const field_name = base_ty.structFieldName(@intCast(field.index), zcu).unwrap().?;
301 try writer.print(".{i}", .{field_name.fmt(ip)});
302 },
303 .Union => {
304 const tag_ty = base_ty.unionTagTypeHypothetical(zcu);
305 const field_name = tag_ty.enumFieldName(@intCast(field.index), zcu);
306 try writer.print(".{i}", .{field_name.fmt(ip)});
307 },
308 .Pointer => switch (field.index) {
309 Value.slice_ptr_index => try writer.writeAll(".ptr"),
310 Value.slice_len_index => try writer.writeAll(".len"),
311 else => unreachable,
312 },
313 else => unreachable,
314 }
315 },
316 }
317}
src/type.zig+4-4
......@@ -187,8 +187,8 @@ pub const Type = struct {
187187
188188 if (info.sentinel != .none) switch (info.flags.size) {
189189 .One, .C => unreachable,
190 .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(Type.fromInterned(info.child), mod)}),
191 .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(Type.fromInterned(info.child), mod)}),
190 .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod)}),
191 .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod)}),
192192 } else switch (info.flags.size) {
193193 .One => try writer.writeAll("*"),
194194 .Many => try writer.writeAll("[*]"),
......@@ -234,7 +234,7 @@ pub const Type = struct {
234234 } else {
235235 try writer.print("[{d}:{}]", .{
236236 array_type.len,
237 Value.fromInterned(array_type.sentinel).fmtValue(Type.fromInterned(array_type.child), mod),
237 Value.fromInterned(array_type.sentinel).fmtValue(mod),
238238 });
239239 try print(Type.fromInterned(array_type.child), writer, mod);
240240 }
......@@ -352,7 +352,7 @@ pub const Type = struct {
352352 try print(Type.fromInterned(field_ty), writer, mod);
353353
354354 if (val != .none) {
355 try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(Type.fromInterned(field_ty), mod)});
355 try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(mod)});
356356 }
357357 }
358358 try writer.writeAll("}");