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`.
This commit is contained in:
mlugg 2024-03-26 05:51:34 +00:00
parent a61def10c6
commit 2a245e3b78
No known key found for this signature in database
GPG Key ID: 58978E823BDE3EF9
9 changed files with 86 additions and 138 deletions

View File

@ -526,7 +526,6 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/src/Package/Fetch.zig" "${CMAKE_SOURCE_DIR}/src/Package/Fetch.zig"
"${CMAKE_SOURCE_DIR}/src/RangeSet.zig" "${CMAKE_SOURCE_DIR}/src/RangeSet.zig"
"${CMAKE_SOURCE_DIR}/src/Sema.zig" "${CMAKE_SOURCE_DIR}/src/Sema.zig"
"${CMAKE_SOURCE_DIR}/src/TypedValue.zig"
"${CMAKE_SOURCE_DIR}/src/Value.zig" "${CMAKE_SOURCE_DIR}/src/Value.zig"
"${CMAKE_SOURCE_DIR}/src/arch/aarch64/CodeGen.zig" "${CMAKE_SOURCE_DIR}/src/arch/aarch64/CodeGen.zig"
"${CMAKE_SOURCE_DIR}/src/arch/aarch64/Emit.zig" "${CMAKE_SOURCE_DIR}/src/arch/aarch64/Emit.zig"
@ -634,9 +633,11 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/src/main.zig" "${CMAKE_SOURCE_DIR}/src/main.zig"
"${CMAKE_SOURCE_DIR}/src/mingw.zig" "${CMAKE_SOURCE_DIR}/src/mingw.zig"
"${CMAKE_SOURCE_DIR}/src/musl.zig" "${CMAKE_SOURCE_DIR}/src/musl.zig"
"${CMAKE_SOURCE_DIR}/src/mutable_value.zig"
"${CMAKE_SOURCE_DIR}/src/print_air.zig" "${CMAKE_SOURCE_DIR}/src/print_air.zig"
"${CMAKE_SOURCE_DIR}/src/print_env.zig" "${CMAKE_SOURCE_DIR}/src/print_env.zig"
"${CMAKE_SOURCE_DIR}/src/print_targets.zig" "${CMAKE_SOURCE_DIR}/src/print_targets.zig"
"${CMAKE_SOURCE_DIR}/src/print_value.zig"
"${CMAKE_SOURCE_DIR}/src/print_zir.zig" "${CMAKE_SOURCE_DIR}/src/print_zir.zig"
"${CMAKE_SOURCE_DIR}/src/register_manager.zig" "${CMAKE_SOURCE_DIR}/src/register_manager.zig"
"${CMAKE_SOURCE_DIR}/src/target.zig" "${CMAKE_SOURCE_DIR}/src/target.zig"

View File

@ -2272,7 +2272,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty:
if (int_ty.zigTypeTag(mod) == .Vector) { if (int_ty.zigTypeTag(mod) == .Vector) {
const msg = msg: { const msg = msg: {
const msg = try sema.errMsg(block, src, "overflow of vector type '{}' with value '{}'", .{ const msg = try sema.errMsg(block, src, "overflow of vector type '{}' with value '{}'", .{
int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod), int_ty.fmt(sema.mod), val.fmtValue(sema.mod),
}); });
errdefer msg.destroy(sema.gpa); errdefer msg.destroy(sema.gpa);
try sema.errNote(block, src, msg, "when computing vector element at index '{d}'", .{vector_index}); 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:
return sema.failWithOwnedErrorMsg(block, msg); return sema.failWithOwnedErrorMsg(block, msg);
} }
return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{ return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{
int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod), int_ty.fmt(sema.mod), val.fmtValue(sema.mod),
}); });
} }
@ -2914,7 +2914,7 @@ fn createAnonymousDeclTypeNamed(
return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null); return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null);
if (arg_i != 0) try writer.writeByte(','); if (arg_i != 0) try writer.writeByte(',');
try writer.print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)}); try writer.print("{}", .{arg_val.fmtValue(sema.mod)});
arg_i += 1; arg_i += 1;
continue; continue;
@ -3186,7 +3186,7 @@ fn zirEnumDecl(
}).lazy; }).lazy;
const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy; const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy;
const msg = msg: { const msg = msg: {
const msg = try sema.errMsg(block, value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(int_tag_ty, sema.mod)}); const msg = try sema.errMsg(block, value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod)});
errdefer msg.destroy(gpa); errdefer msg.destroy(gpa);
try sema.errNote(block, other_field_src, msg, "other occurrence here", .{}); try sema.errNote(block, other_field_src, msg, "other occurrence here", .{});
break :msg msg; break :msg msg;
@ -3206,7 +3206,7 @@ fn zirEnumDecl(
const field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = field_i }).lazy; const field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = field_i }).lazy;
const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy; const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy;
const msg = msg: { const msg = msg: {
const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(int_tag_ty, sema.mod)}); const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod)});
errdefer msg.destroy(gpa); errdefer msg.destroy(gpa);
try sema.errNote(block, other_field_src, msg, "other occurrence here", .{}); try sema.errNote(block, other_field_src, msg, "other occurrence here", .{});
break :msg msg; break :msg msg;
@ -3228,7 +3228,7 @@ fn zirEnumDecl(
.range = if (has_tag_value) .value else .name, .range = if (has_tag_value) .value else .name,
}).lazy; }).lazy;
const msg = try sema.errMsg(block, value_src, "enumeration value '{}' too large for type '{}'", .{ const msg = try sema.errMsg(block, value_src, "enumeration value '{}' too large for type '{}'", .{
last_tag_val.?.fmtValue(int_tag_ty, mod), int_tag_ty.fmt(mod), last_tag_val.?.fmtValue(mod), int_tag_ty.fmt(mod),
}); });
return sema.failWithOwnedErrorMsg(block, msg); return sema.failWithOwnedErrorMsg(block, msg);
} }
@ -4381,10 +4381,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
.input_index = len_idx, .input_index = len_idx,
} }; } };
try sema.errNote(block, a_src, msg, "length {} here", .{ try sema.errNote(block, a_src, msg, "length {} here", .{
v.fmtValue(Type.usize, sema.mod), v.fmtValue(sema.mod),
}); });
try sema.errNote(block, arg_src, msg, "length {} here", .{ try sema.errNote(block, arg_src, msg, "length {} here", .{
arg_val.fmtValue(Type.usize, sema.mod), arg_val.fmtValue(sema.mod),
}); });
break :msg msg; break :msg msg;
}; };
@ -5794,7 +5794,7 @@ fn zirCompileLog(
const arg_ty = sema.typeOf(arg); const arg_ty = sema.typeOf(arg);
if (try sema.resolveValueResolveLazy(arg)) |val| { if (try sema.resolveValueResolveLazy(arg)) |val| {
try writer.print("@as({}, {})", .{ try writer.print("@as({}, {})", .{
arg_ty.fmt(mod), val.fmtValue(arg_ty, mod), arg_ty.fmt(mod), val.fmtValue(mod),
}); });
} else { } else {
try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(mod)}); 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
return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern()); return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());
} }
return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{ return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{
int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod), int_val.fmtValue(mod), dest_ty.fmt(mod),
}); });
} }
if (int_val.isUndef(mod)) { if (int_val.isUndef(mod)) {
@ -8888,7 +8888,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
} }
if (!(try sema.enumHasInt(dest_ty, int_val))) { if (!(try sema.enumHasInt(dest_ty, int_val))) {
return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{ return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{
dest_ty.fmt(mod), int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod), int_val.fmtValue(mod),
}); });
} }
return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern()); return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());
@ -13934,7 +13934,7 @@ fn zirShl(
const rhs_elem = try rhs_val.elemValue(mod, i); const rhs_elem = try rhs_val.elemValue(mod, i);
if (rhs_elem.compareHetero(.gte, bit_value, mod)) { if (rhs_elem.compareHetero(.gte, bit_value, mod)) {
return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
rhs_elem.fmtValue(scalar_ty, mod), rhs_elem.fmtValue(mod),
i, i,
scalar_ty.fmt(mod), scalar_ty.fmt(mod),
}); });
@ -13942,7 +13942,7 @@ fn zirShl(
} }
} else if (rhs_val.compareHetero(.gte, bit_value, mod)) { } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {
return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
rhs_val.fmtValue(scalar_ty, mod), rhs_val.fmtValue(mod),
scalar_ty.fmt(mod), scalar_ty.fmt(mod),
}); });
} }
@ -13953,14 +13953,14 @@ fn zirShl(
const rhs_elem = try rhs_val.elemValue(mod, i); const rhs_elem = try rhs_val.elemValue(mod, i);
if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) { if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) {
return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
rhs_elem.fmtValue(scalar_ty, mod), rhs_elem.fmtValue(mod),
i, i,
}); });
} }
} }
} else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {
return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
rhs_val.fmtValue(scalar_ty, mod), rhs_val.fmtValue(mod),
}); });
} }
} }
@ -14099,7 +14099,7 @@ fn zirShr(
const rhs_elem = try rhs_val.elemValue(mod, i); const rhs_elem = try rhs_val.elemValue(mod, i);
if (rhs_elem.compareHetero(.gte, bit_value, mod)) { if (rhs_elem.compareHetero(.gte, bit_value, mod)) {
return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
rhs_elem.fmtValue(scalar_ty, mod), rhs_elem.fmtValue(mod),
i, i,
scalar_ty.fmt(mod), scalar_ty.fmt(mod),
}); });
@ -14107,7 +14107,7 @@ fn zirShr(
} }
} else if (rhs_val.compareHetero(.gte, bit_value, mod)) { } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {
return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
rhs_val.fmtValue(scalar_ty, mod), rhs_val.fmtValue(mod),
scalar_ty.fmt(mod), scalar_ty.fmt(mod),
}); });
} }
@ -14118,14 +14118,14 @@ fn zirShr(
const rhs_elem = try rhs_val.elemValue(mod, i); const rhs_elem = try rhs_val.elemValue(mod, i);
if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) { if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) {
return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
rhs_elem.fmtValue(scalar_ty, mod), rhs_elem.fmtValue(mod),
i, i,
}); });
} }
} }
} else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {
return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
rhs_val.fmtValue(scalar_ty, mod), rhs_val.fmtValue(mod),
}); });
} }
if (maybe_lhs_val) |lhs_val| { if (maybe_lhs_val) |lhs_val| {
@ -15046,7 +15046,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
block, block,
src, src,
"ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'", "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'",
.{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(resolved_type, mod) }, .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(mod) },
); );
} }
} }
@ -21094,7 +21094,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const enum_decl = mod.declPtr(enum_decl_index); const enum_decl = mod.declPtr(enum_decl_index);
const msg = msg: { const msg = msg: {
const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{}'", .{ const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{}'", .{
val.fmtValue(enum_ty, sema.mod), enum_decl.name.fmt(ip), val.fmtValue(sema.mod), enum_decl.name.fmt(ip),
}); });
errdefer msg.destroy(sema.gpa); errdefer msg.destroy(sema.gpa);
try mod.errNoteNonLazy(enum_decl.srcLoc(mod), msg, "declared here", .{}); try mod.errNoteNonLazy(enum_decl.srcLoc(mod), msg, "declared here", .{});
@ -21729,7 +21729,7 @@ fn reifyEnum(
// TODO: better source location // TODO: better source location
return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{ return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{
field_name.fmt(ip), field_name.fmt(ip),
field_value_val.fmtValue(Type.comptime_int, mod), field_value_val.fmtValue(mod),
tag_ty.fmt(mod), tag_ty.fmt(mod),
}); });
} }
@ -21745,7 +21745,7 @@ fn reifyEnum(
break :msg msg; break :msg msg;
}, },
.value => msg: { .value => msg: {
const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{field_value_val.fmtValue(Type.comptime_int, mod)}); const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{field_value_val.fmtValue(mod)});
errdefer msg.destroy(gpa); errdefer msg.destroy(gpa);
_ = conflict.prev_field_idx; // TODO: this note is incorrect _ = conflict.prev_field_idx; // TODO: this note is incorrect
try sema.errNote(block, src, msg, "other enum tag value here", .{}); try sema.errNote(block, src, msg, "other enum tag value here", .{});
@ -22883,12 +22883,12 @@ fn ptrCastFull(
return sema.failWithOwnedErrorMsg(block, msg: { return sema.failWithOwnedErrorMsg(block, msg: {
const msg = if (src_info.sentinel == .none) blk: { const msg = if (src_info.sentinel == .none) blk: {
break :blk try sema.errMsg(block, src, "destination pointer requires '{}' sentinel", .{ break :blk try sema.errMsg(block, src, "destination pointer requires '{}' sentinel", .{
Value.fromInterned(dest_info.sentinel).fmtValue(Type.fromInterned(dest_info.child), mod), Value.fromInterned(dest_info.sentinel).fmtValue(mod),
}); });
} else blk: { } else blk: {
break :blk try sema.errMsg(block, src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{ break :blk try sema.errMsg(block, src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{
Value.fromInterned(src_info.sentinel).fmtValue(Type.fromInterned(src_info.child), mod), Value.fromInterned(src_info.sentinel).fmtValue(mod),
Value.fromInterned(dest_info.sentinel).fmtValue(Type.fromInterned(dest_info.child), mod), Value.fromInterned(dest_info.sentinel).fmtValue(mod),
}); });
}; };
errdefer msg.destroy(sema.gpa); errdefer msg.destroy(sema.gpa);
@ -25285,10 +25285,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
const msg = try sema.errMsg(block, src, "non-matching @memcpy lengths", .{}); const msg = try sema.errMsg(block, src, "non-matching @memcpy lengths", .{});
errdefer msg.destroy(sema.gpa); errdefer msg.destroy(sema.gpa);
try sema.errNote(block, dest_src, msg, "length {} here", .{ try sema.errNote(block, dest_src, msg, "length {} here", .{
dest_len_val.fmtValue(Type.usize, sema.mod), dest_len_val.fmtValue(sema.mod),
}); });
try sema.errNote(block, src_src, msg, "length {} here", .{ try sema.errNote(block, src_src, msg, "length {} here", .{
src_len_val.fmtValue(Type.usize, sema.mod), src_len_val.fmtValue(sema.mod),
}); });
break :msg msg; break :msg msg;
}; };
@ -29162,7 +29162,7 @@ fn coerceExtra(
// comptime-known integer to other number // comptime-known integer to other number
if (!(try sema.intFitsInType(val, dest_ty, null))) { if (!(try sema.intFitsInType(val, dest_ty, null))) {
if (!opts.report_err) return error.NotCoercible; if (!opts.report_err) return error.NotCoercible;
return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) }); return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(mod) });
} }
return switch (mod.intern_pool.indexToKey(val.toIntern())) { return switch (mod.intern_pool.indexToKey(val.toIntern())) {
.undef => try mod.undefRef(dest_ty), .undef => try mod.undefRef(dest_ty),
@ -29207,7 +29207,7 @@ fn coerceExtra(
block, block,
inst_src, inst_src,
"type '{}' cannot represent float value '{}'", "type '{}' cannot represent float value '{}'",
.{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) }, .{ dest_ty.fmt(mod), val.fmtValue(mod) },
); );
} }
return Air.internedToRef(result_val.toIntern()); return Air.internedToRef(result_val.toIntern());
@ -29578,11 +29578,11 @@ const InMemoryCoercionResult = union(enum) {
.array_sentinel => |sentinel| { .array_sentinel => |sentinel| {
if (sentinel.actual.toIntern() != .unreachable_value) { if (sentinel.actual.toIntern() != .unreachable_value) {
try sema.errNote(block, src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{ try sema.errNote(block, src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{
sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod), sentinel.actual.fmtValue(mod), sentinel.wanted.fmtValue(mod),
}); });
} else { } else {
try sema.errNote(block, src, msg, "destination array requires '{}' sentinel", .{ try sema.errNote(block, src, msg, "destination array requires '{}' sentinel", .{
sentinel.wanted.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(mod),
}); });
} }
break; break;
@ -29704,11 +29704,11 @@ const InMemoryCoercionResult = union(enum) {
.ptr_sentinel => |sentinel| { .ptr_sentinel => |sentinel| {
if (sentinel.actual.toIntern() != .unreachable_value) { if (sentinel.actual.toIntern() != .unreachable_value) {
try sema.errNote(block, src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{ try sema.errNote(block, src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{
sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod), sentinel.actual.fmtValue(mod), sentinel.wanted.fmtValue(mod),
}); });
} else { } else {
try sema.errNote(block, src, msg, "destination pointer requires '{}' sentinel", .{ try sema.errNote(block, src, msg, "destination pointer requires '{}' sentinel", .{
sentinel.wanted.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(mod),
}); });
} }
break; break;
@ -31708,7 +31708,7 @@ fn coerceEnumToUnion(
if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse { const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse {
return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{ return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{
union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod), union_ty.fmt(sema.mod), val.fmtValue(sema.mod),
}); });
}; };
@ -32928,8 +32928,8 @@ fn analyzeSlice(
msg, msg,
"expected '{}', found '{}'", "expected '{}', found '{}'",
.{ .{
Value.zero_comptime_int.fmtValue(Type.comptime_int, mod), Value.zero_comptime_int.fmtValue(mod),
start_value.fmtValue(Type.comptime_int, mod), start_value.fmtValue(mod),
}, },
); );
break :msg msg; break :msg msg;
@ -32945,8 +32945,8 @@ fn analyzeSlice(
msg, msg,
"expected '{}', found '{}'", "expected '{}', found '{}'",
.{ .{
Value.one_comptime_int.fmtValue(Type.comptime_int, mod), Value.one_comptime_int.fmtValue(mod),
end_value.fmtValue(Type.comptime_int, mod), end_value.fmtValue(mod),
}, },
); );
break :msg msg; break :msg msg;
@ -32959,7 +32959,7 @@ fn analyzeSlice(
block, block,
end_src, end_src,
"end index {} out of bounds for slice of single-item pointer", "end index {} out of bounds for slice of single-item pointer",
.{end_value.fmtValue(Type.comptime_int, mod)}, .{end_value.fmtValue(mod)},
); );
} }
} }
@ -33054,8 +33054,8 @@ fn analyzeSlice(
end_src, end_src,
"end index {} out of bounds for array of length {}{s}", "end index {} out of bounds for array of length {}{s}",
.{ .{
end_val.fmtValue(Type.usize, mod), end_val.fmtValue(mod),
len_val.fmtValue(Type.usize, mod), len_val.fmtValue(mod),
sentinel_label, sentinel_label,
}, },
); );
@ -33099,7 +33099,7 @@ fn analyzeSlice(
end_src, end_src,
"end index {} out of bounds for slice of length {d}{s}", "end index {} out of bounds for slice of length {d}{s}",
.{ .{
end_val.fmtValue(Type.usize, mod), end_val.fmtValue(mod),
try slice_val.sliceLen(sema), try slice_val.sliceLen(sema),
sentinel_label, sentinel_label,
}, },
@ -33159,8 +33159,8 @@ fn analyzeSlice(
start_src, start_src,
"start index {} is larger than end index {}", "start index {} is larger than end index {}",
.{ .{
start_val.fmtValue(Type.usize, mod), start_val.fmtValue(mod),
end_val.fmtValue(Type.usize, mod), end_val.fmtValue(mod),
}, },
); );
} }
@ -33198,8 +33198,8 @@ fn analyzeSlice(
const msg = try sema.errMsg(block, src, "value in memory does not match slice sentinel", .{}); const msg = try sema.errMsg(block, src, "value in memory does not match slice sentinel", .{});
errdefer msg.destroy(sema.gpa); errdefer msg.destroy(sema.gpa);
try sema.errNote(block, src, msg, "expected '{}', found '{}'", .{ try sema.errNote(block, src, msg, "expected '{}', found '{}'", .{
expected_sentinel.fmtValue(elem_ty, mod), expected_sentinel.fmtValue(mod),
actual_sentinel.fmtValue(elem_ty, mod), actual_sentinel.fmtValue(mod),
}); });
break :msg msg; break :msg msg;
@ -37213,7 +37213,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
const field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = field_i }).lazy; const field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = field_i }).lazy;
const other_field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = gop.index }).lazy; const other_field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = gop.index }).lazy;
const msg = msg: { const msg = msg: {
const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(int_tag_ty, mod)}); const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(mod)});
errdefer msg.destroy(gpa); errdefer msg.destroy(gpa);
try sema.errNote(&block_scope, other_field_src, msg, "other occurrence here", .{}); try sema.errNote(&block_scope, other_field_src, msg, "other occurrence here", .{});
break :msg msg; break :msg msg;
@ -38566,18 +38566,17 @@ fn intFromFloat(
) CompileError!Value { ) CompileError!Value {
const mod = sema.mod; const mod = sema.mod;
if (float_ty.zigTypeTag(mod) == .Vector) { if (float_ty.zigTypeTag(mod) == .Vector) {
const elem_ty = float_ty.scalarType(mod);
const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod)); const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod));
for (result_data, 0..) |*scalar, i| { for (result_data, 0..) |*scalar, i| {
const elem_val = try val.elemValue(sema.mod, i); const elem_val = try val.elemValue(sema.mod, i);
scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, elem_ty, int_ty.scalarType(mod), mode)).toIntern(); scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(mod), mode)).toIntern();
} }
return Value.fromInterned((try mod.intern(.{ .aggregate = .{ return Value.fromInterned((try mod.intern(.{ .aggregate = .{
.ty = int_ty.toIntern(), .ty = int_ty.toIntern(),
.storage = .{ .elems = result_data }, .storage = .{ .elems = result_data },
} }))); } })));
} }
return sema.intFromFloatScalar(block, src, val, float_ty, int_ty, mode); return sema.intFromFloatScalar(block, src, val, int_ty, mode);
} }
// float is expected to be finite and non-NaN // float is expected to be finite and non-NaN
@ -38610,7 +38609,6 @@ fn intFromFloatScalar(
block: *Block, block: *Block,
src: LazySrcLoc, src: LazySrcLoc,
val: Value, val: Value,
float_ty: Type,
int_ty: Type, int_ty: Type,
mode: IntFromFloatMode, mode: IntFromFloatMode,
) CompileError!Value { ) CompileError!Value {
@ -38622,7 +38620,7 @@ fn intFromFloatScalar(
block, block,
src, src,
"fractional component prevents float value '{}' from coercion to type '{}'", "fractional component prevents float value '{}' from coercion to type '{}'",
.{ val.fmtValue(float_ty, mod), int_ty.fmt(mod) }, .{ val.fmtValue(mod), int_ty.fmt(mod) },
); );
const float = val.toFloat(f128, mod); const float = val.toFloat(f128, mod);
@ -38644,7 +38642,7 @@ fn intFromFloatScalar(
if (!(try sema.intFitsInType(cti_result, int_ty, null))) { if (!(try sema.intFitsInType(cti_result, int_ty, null))) {
return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{
val.fmtValue(float_ty, sema.mod), int_ty.fmt(sema.mod), val.fmtValue(sema.mod), int_ty.fmt(sema.mod),
}); });
} }
return mod.getCoerced(cti_result, int_ty); return mod.getCoerced(cti_result, int_ty);

View File

@ -8,9 +8,9 @@ const Target = std.Target;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const Zcu = @import("Module.zig"); const Zcu = @import("Module.zig");
const Module = Zcu; const Module = Zcu;
const TypedValue = @import("TypedValue.zig");
const Sema = @import("Sema.zig"); const Sema = @import("Sema.zig");
const InternPool = @import("InternPool.zig"); const InternPool = @import("InternPool.zig");
const print_value = @import("print_value.zig");
const Value = @This(); const Value = @This();
ip_index: InternPool.Index, ip_index: InternPool.Index,
@ -39,9 +39,9 @@ pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) {
return .{ .data = val }; return .{ .data = val };
} }
pub fn fmtValue(val: Value, ty: Type, mod: *Module) std.fmt.Formatter(TypedValue.format) { pub fn fmtValue(val: Value, mod: *Module) std.fmt.Formatter(print_value.format) {
return .{ .data = .{ return .{ .data = .{
.tv = .{ .ty = ty, .val = val }, .val = val,
.mod = mod, .mod = mod,
} }; } };
} }

View File

@ -17877,10 +17877,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
break :result null; break :result null;
}) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{ }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{
lhs_ty.fmt(mod), rhs_ty.fmt(mod), dst_ty.fmt(mod), lhs_ty.fmt(mod), rhs_ty.fmt(mod), dst_ty.fmt(mod),
Value.fromInterned(extra.mask).fmtValue( Value.fromInterned(extra.mask).fmtValue(mod),
Type.fromInterned(mod.intern_pool.typeOf(extra.mask)),
mod,
),
}); });
return self.finishAir(inst, result, .{ extra.a, extra.b, .none }); return self.finishAir(inst, result, .{ extra.a, extra.b, .none });
} }

View File

@ -185,9 +185,7 @@ pub fn generateSymbol(
const target = mod.getTarget(); const target = mod.getTarget();
const endian = target.cpu.arch.endian(); const endian = target.cpu.arch.endian();
log.debug("generateSymbol: val = {}", .{ log.debug("generateSymbol: val = {}", .{val.fmtValue(mod)});
val.fmtValue(ty, mod),
});
if (val.isUndefDeep(mod)) { if (val.isUndefDeep(mod)) {
const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow; const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow;
@ -862,7 +860,7 @@ fn genDeclRef(
) CodeGenError!GenResult { ) CodeGenError!GenResult {
const zcu = lf.comp.module.?; const zcu = lf.comp.module.?;
const ty = val.typeOf(zcu); const ty = val.typeOf(zcu);
log.debug("genDeclRef: val = {}", .{val.fmtValue(ty, zcu)}); log.debug("genDeclRef: val = {}", .{val.fmtValue(zcu)});
const ptr_decl = zcu.declPtr(ptr_decl_index); const ptr_decl = zcu.declPtr(ptr_decl_index);
const namespace = zcu.namespacePtr(ptr_decl.src_namespace); const namespace = zcu.namespacePtr(ptr_decl.src_namespace);
@ -976,7 +974,7 @@ fn genUnnamedConst(
) CodeGenError!GenResult { ) CodeGenError!GenResult {
const zcu = lf.comp.module.?; const zcu = lf.comp.module.?;
const gpa = lf.comp.gpa; const gpa = lf.comp.gpa;
log.debug("genUnnamedConst: val = {}", .{val.fmtValue(val.typeOf(zcu), zcu)}); log.debug("genUnnamedConst: val = {}", .{val.fmtValue(zcu)});
const local_sym_index = lf.lowerUnnamedConst(val, owner_decl_index) catch |err| { const local_sym_index = lf.lowerUnnamedConst(val, owner_decl_index) catch |err| {
return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)}); return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)});
@ -1016,7 +1014,7 @@ pub fn genTypedValue(
const zcu = lf.comp.module.?; const zcu = lf.comp.module.?;
const ty = val.typeOf(zcu); const ty = val.typeOf(zcu);
log.debug("genTypedValue: val = {}", .{val.fmtValue(ty, zcu)}); log.debug("genTypedValue: val = {}", .{val.fmtValue(zcu)});
if (val.isUndef(zcu)) if (val.isUndef(zcu))
return GenResult.mcv(.undef); return GenResult.mcv(.undef);

View File

@ -860,7 +860,7 @@ const DeclGen = struct {
const val = arg_val; const val = arg_val;
log.debug("constant: ty = {}, val = {}", .{ ty.fmt(mod), val.fmtValue(ty, mod) }); log.debug("constant: ty = {}, val = {}", .{ ty.fmt(mod), val.fmtValue(mod) });
if (val.isUndefDeep(mod)) { if (val.isUndefDeep(mod)) {
return self.spv.constUndef(result_ty_ref); return self.spv.constUndef(result_ty_ref);
} }

View File

@ -951,7 +951,7 @@ const Writer = struct {
const ty = Type.fromInterned(mod.intern_pool.indexToKey(ip_index).typeOf()); const ty = Type.fromInterned(mod.intern_pool.indexToKey(ip_index).typeOf());
try s.print("<{}, {}>", .{ try s.print("<{}, {}>", .{
ty.fmt(mod), ty.fmt(mod),
Value.fromInterned(ip_index).fmtValue(ty, mod), Value.fromInterned(ip_index).fmtValue(mod),
}); });
} else { } else {
return w.writeInstIndex(s, operand.toIndex().?, dies); return w.writeInstIndex(s, operand.toIndex().?, dies);

View File

@ -9,17 +9,13 @@ const Module = Zcu;
const Sema = @import("Sema.zig"); const Sema = @import("Sema.zig");
const InternPool = @import("InternPool.zig"); const InternPool = @import("InternPool.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const TypedValue = @This();
const Target = std.Target; const Target = std.Target;
ty: Type,
val: Value,
const max_aggregate_items = 100; const max_aggregate_items = 100;
const max_string_len = 256; const max_string_len = 256;
const FormatContext = struct { const FormatContext = struct {
tv: TypedValue, val: Value,
mod: *Module, mod: *Module,
}; };
@ -31,7 +27,7 @@ pub fn format(
) !void { ) !void {
_ = options; _ = options;
comptime std.debug.assert(fmt.len == 0); comptime std.debug.assert(fmt.len == 0);
return ctx.tv.print(writer, 3, ctx.mod, null) catch |err| switch (err) { return print(ctx.val, writer, 3, ctx.mod, null) catch |err| switch (err) {
error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
error.ComptimeBreak, error.ComptimeReturn => unreachable, error.ComptimeBreak, error.ComptimeReturn => unreachable,
error.AnalysisFail, error.NeededSourceLocation => unreachable, // TODO: re-evaluate when we actually pass `opt_sema` error.AnalysisFail, error.NeededSourceLocation => unreachable, // TODO: re-evaluate when we actually pass `opt_sema`
@ -40,7 +36,7 @@ pub fn format(
} }
pub fn print( pub fn print(
tv: TypedValue, val: Value,
writer: anytype, writer: anytype,
level: u8, level: u8,
mod: *Module, mod: *Module,
@ -48,7 +44,6 @@ pub fn print(
opt_sema: ?*Sema, opt_sema: ?*Sema,
) (@TypeOf(writer).Error || Module.CompileError)!void { ) (@TypeOf(writer).Error || Module.CompileError)!void {
const ip = &mod.intern_pool; const ip = &mod.intern_pool;
const val = tv.val;
switch (ip.indexToKey(val.toIntern())) { switch (ip.indexToKey(val.toIntern())) {
.int_type, .int_type,
.ptr_type, .ptr_type,
@ -99,10 +94,7 @@ pub fn print(
.err_name => |err_name| try writer.print("error.{}", .{ .err_name => |err_name| try writer.print("error.{}", .{
err_name.fmt(ip), err_name.fmt(ip),
}), }),
.payload => |payload| try print(.{ .payload => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema),
.ty = tv.ty.errorUnionPayload(mod),
.val = Value.fromInterned(payload),
}, writer, level, mod, opt_sema),
}, },
.enum_literal => |enum_literal| try writer.print(".{}", .{ .enum_literal => |enum_literal| try writer.print(".{}", .{
enum_literal.fmt(ip), enum_literal.fmt(ip),
@ -117,10 +109,7 @@ pub fn print(
try writer.writeAll("@enumFromInt(...)"); try writer.writeAll("@enumFromInt(...)");
} }
try writer.writeAll("@enumFromInt("); try writer.writeAll("@enumFromInt(");
try print(.{ try print(Value.fromInterned(enum_tag.int), writer, level - 1, mod, opt_sema);
.ty = Type.fromInterned(ip.typeOf(enum_tag.int)),
.val = Value.fromInterned(enum_tag.int),
}, writer, level - 1, mod, opt_sema);
try writer.writeAll(")"); try writer.writeAll(")");
}, },
.empty_enum_value => try writer.writeAll("(empty enum value)"), .empty_enum_value => try writer.writeAll("(empty enum value)"),
@ -139,10 +128,7 @@ pub fn print(
} }
try printPtr(slice.ptr, writer, false, false, 0, level, mod, opt_sema); try printPtr(slice.ptr, writer, false, false, 0, level, mod, opt_sema);
try writer.writeAll("[0.."); try writer.writeAll("[0..");
try print(.{ try print(Value.fromInterned(slice.len), writer, level - 1, mod, opt_sema);
.ty = Type.usize,
.val = Value.fromInterned(slice.len),
}, writer, level - 1, mod, opt_sema);
try writer.writeAll("]"); try writer.writeAll("]");
}, },
.ptr => { .ptr => {
@ -159,10 +145,7 @@ pub fn print(
}, },
.opt => |opt| switch (opt.val) { .opt => |opt| switch (opt.val) {
.none => try writer.writeAll("null"), .none => try writer.writeAll("null"),
else => |payload| try print(.{ else => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema),
.ty = tv.ty.childType(mod),
.val = Value.fromInterned(payload),
}, writer, level, mod, opt_sema),
}, },
.aggregate => |aggregate| try printAggregate(val, aggregate, writer, level, mod, opt_sema), .aggregate => |aggregate| try printAggregate(val, aggregate, writer, level, mod, opt_sema),
.un => |un| { .un => |un| {
@ -171,25 +154,15 @@ pub fn print(
return; return;
} }
if (un.tag == .none) { if (un.tag == .none) {
const backing_ty = try tv.ty.unionBackingType(mod); const backing_ty = try val.typeOf(mod).unionBackingType(mod);
try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(mod)}); try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(mod)});
try print(.{ try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema);
.ty = backing_ty,
.val = Value.fromInterned(un.val),
}, writer, level - 1, mod, opt_sema);
try writer.writeAll("))"); try writer.writeAll("))");
} else { } else {
try writer.writeAll(".{ "); try writer.writeAll(".{ ");
try print(.{ try print(Value.fromInterned(un.tag), writer, level - 1, mod, opt_sema);
.ty = tv.ty.unionTagTypeHypothetical(mod),
.val = Value.fromInterned(un.tag),
}, writer, level - 1, mod, opt_sema);
try writer.writeAll(" = "); try writer.writeAll(" = ");
const field_ty = tv.ty.unionFieldType(Value.fromInterned(un.tag), mod).?; try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema);
try print(.{
.ty = field_ty,
.val = Value.fromInterned(un.val),
}, writer, level - 1, mod, opt_sema);
try writer.writeAll(" }"); try writer.writeAll(" }");
} }
}, },
@ -221,10 +194,7 @@ fn printAggregate(
if (i != 0) try writer.writeAll(", "); if (i != 0) try writer.writeAll(", ");
const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?; const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?;
try writer.print(".{i} = ", .{field_name.fmt(ip)}); try writer.print(".{i} = ", .{field_name.fmt(ip)});
try print(.{ try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema);
.ty = ty.structFieldType(i, zcu),
.val = try val.fieldValue(zcu, i),
}, writer, level - 1, zcu, opt_sema);
} }
try writer.writeAll(" }"); try writer.writeAll(" }");
return; return;
@ -240,7 +210,6 @@ fn printAggregate(
else => unreachable, else => unreachable,
} }
const elem_ty = ty.childType(zcu);
const len = ty.arrayLen(zcu); const len = ty.arrayLen(zcu);
try writer.writeAll(".{ "); try writer.writeAll(".{ ");
@ -248,10 +217,7 @@ fn printAggregate(
const max_len = @min(len, max_aggregate_items); const max_len = @min(len, max_aggregate_items);
for (0..max_len) |i| { for (0..max_len) |i| {
if (i != 0) try writer.writeAll(", "); if (i != 0) try writer.writeAll(", ");
try print(.{ try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema);
.ty = elem_ty,
.val = try val.fieldValue(zcu, i),
}, writer, level - 1, zcu, opt_sema);
} }
if (len > max_aggregate_items) { if (len > max_aggregate_items) {
try writer.writeAll(", ..."); try writer.writeAll(", ...");
@ -286,17 +252,11 @@ fn printPtr(
try writer.writeByteNTimes('(', leading_parens); try writer.writeByteNTimes('(', leading_parens);
if (force_type) { if (force_type) {
try writer.print("@as({}, @ptrFromInt(", .{Type.fromInterned(ptr.ty).fmt(zcu)}); try writer.print("@as({}, @ptrFromInt(", .{Type.fromInterned(ptr.ty).fmt(zcu)});
try print(.{ try print(Value.fromInterned(int), writer, level - 1, zcu, opt_sema);
.ty = Type.usize,
.val = Value.fromInterned(int),
}, writer, level - 1, zcu, opt_sema);
try writer.writeAll("))"); try writer.writeAll("))");
} else { } else {
try writer.writeAll("@ptrFromInt("); try writer.writeAll("@ptrFromInt(");
try print(.{ try print(Value.fromInterned(int), writer, level - 1, zcu, opt_sema);
.ty = Type.usize,
.val = Value.fromInterned(int),
}, writer, level - 1, zcu, opt_sema);
try writer.writeAll(")"); try writer.writeAll(")");
} }
}, },
@ -308,19 +268,13 @@ fn printPtr(
.anon_decl => |anon| { .anon_decl => |anon| {
const ty = Type.fromInterned(ip.typeOf(anon.val)); const ty = Type.fromInterned(ip.typeOf(anon.val));
try writer.print("&@as({}, ", .{ty.fmt(zcu)}); try writer.print("&@as({}, ", .{ty.fmt(zcu)});
try print(.{ try print(Value.fromInterned(anon.val), writer, level - 1, zcu, opt_sema);
.ty = ty,
.val = Value.fromInterned(anon.val),
}, writer, level - 1, zcu, opt_sema);
try writer.writeAll(")"); try writer.writeAll(")");
}, },
.comptime_field => |val| { .comptime_field => |val| {
const ty = Type.fromInterned(ip.typeOf(val)); const ty = Type.fromInterned(ip.typeOf(val));
try writer.print("&@as({}, ", .{ty.fmt(zcu)}); try writer.print("&@as({}, ", .{ty.fmt(zcu)});
try print(.{ try print(Value.fromInterned(val), writer, level - 1, zcu, opt_sema);
.ty = ty,
.val = Value.fromInterned(val),
}, writer, level - 1, zcu, opt_sema);
try writer.writeAll(")"); try writer.writeAll(")");
}, },
.eu_payload => |base| { .eu_payload => |base| {

View File

@ -187,8 +187,8 @@ pub const Type = struct {
if (info.sentinel != .none) switch (info.flags.size) { if (info.sentinel != .none) switch (info.flags.size) {
.One, .C => unreachable, .One, .C => unreachable,
.Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(Type.fromInterned(info.child), mod)}), .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod)}),
.Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(Type.fromInterned(info.child), mod)}), .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod)}),
} else switch (info.flags.size) { } else switch (info.flags.size) {
.One => try writer.writeAll("*"), .One => try writer.writeAll("*"),
.Many => try writer.writeAll("[*]"), .Many => try writer.writeAll("[*]"),
@ -234,7 +234,7 @@ pub const Type = struct {
} else { } else {
try writer.print("[{d}:{}]", .{ try writer.print("[{d}:{}]", .{
array_type.len, array_type.len,
Value.fromInterned(array_type.sentinel).fmtValue(Type.fromInterned(array_type.child), mod), Value.fromInterned(array_type.sentinel).fmtValue(mod),
}); });
try print(Type.fromInterned(array_type.child), writer, mod); try print(Type.fromInterned(array_type.child), writer, mod);
} }
@ -352,7 +352,7 @@ pub const Type = struct {
try print(Type.fromInterned(field_ty), writer, mod); try print(Type.fromInterned(field_ty), writer, mod);
if (val != .none) { if (val != .none) {
try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(Type.fromInterned(field_ty), mod)}); try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(mod)});
} }
} }
try writer.writeAll("}"); try writer.writeAll("}");