mirror of
https://github.com/ziglang/zig.git
synced 2026-01-10 01:15:14 +00:00
Merge pull request #11253 from Vexu/pretty-print-values
stage2: print values with types
This commit is contained in:
commit
18a43b61f9
16
src/Sema.zig
16
src/Sema.zig
@ -1867,7 +1867,7 @@ fn createTypeName(
|
||||
const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg) catch unreachable;
|
||||
|
||||
if (arg_i != 0) try buf.appendSlice(",");
|
||||
try buf.writer().print("{}", .{arg_val});
|
||||
try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg))});
|
||||
|
||||
arg_i += 1;
|
||||
continue;
|
||||
@ -3673,7 +3673,7 @@ fn zirCompileLog(
|
||||
const arg = sema.resolveInst(arg_ref);
|
||||
const arg_ty = sema.typeOf(arg);
|
||||
if (try sema.resolveMaybeUndefVal(block, src, arg)) |val| {
|
||||
try writer.print("@as({}, {})", .{ arg_ty, val });
|
||||
try writer.print("@as({}, {})", .{ arg_ty, val.fmtValue(arg_ty) });
|
||||
} else {
|
||||
try writer.print("@as({}, [runtime value])", .{arg_ty});
|
||||
}
|
||||
@ -5670,7 +5670,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
|
||||
block,
|
||||
src,
|
||||
"enum '{}' has no tag with value {}",
|
||||
.{ dest_ty, int_val },
|
||||
.{ dest_ty, int_val.fmtValue(sema.typeOf(operand)) },
|
||||
);
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
try sema.mod.errNoteNonLazy(
|
||||
@ -7900,7 +7900,7 @@ fn validateSwitchItemEnum(
|
||||
block,
|
||||
src,
|
||||
"enum '{}' has no tag with value '{}'",
|
||||
.{ item_tv.ty, item_tv.val },
|
||||
.{ item_tv.ty, item_tv.val.fmtValue(item_tv.ty) },
|
||||
);
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
try sema.mod.errNoteNonLazy(
|
||||
@ -17507,7 +17507,7 @@ fn coerce(
|
||||
const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :float;
|
||||
|
||||
if (val.floatHasFraction()) {
|
||||
return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val, dest_ty });
|
||||
return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val.fmtValue(inst_ty), dest_ty });
|
||||
}
|
||||
const result_val = val.floatToInt(sema.arena, dest_ty, target) catch |err| switch (err) {
|
||||
error.FloatCannotFit => {
|
||||
@ -17521,7 +17521,7 @@ fn coerce(
|
||||
if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
|
||||
// comptime known integer to other number
|
||||
if (!val.intFitsInType(dest_ty, target)) {
|
||||
return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty, val });
|
||||
return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty, val.fmtValue(inst_ty) });
|
||||
}
|
||||
return try sema.addConstant(dest_ty, val);
|
||||
}
|
||||
@ -17556,7 +17556,7 @@ fn coerce(
|
||||
block,
|
||||
inst_src,
|
||||
"type {} cannot represent float value {}",
|
||||
.{ dest_ty, val },
|
||||
.{ dest_ty, val.fmtValue(inst_ty) },
|
||||
);
|
||||
}
|
||||
return try sema.addConstant(dest_ty, result_val);
|
||||
@ -18850,7 +18850,7 @@ fn coerceEnumToUnion(
|
||||
const field_index = union_obj.tag_ty.enumTagFieldIndex(val) orelse {
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(block, inst_src, "union {} has no tag with value {}", .{
|
||||
union_ty, val,
|
||||
union_ty, val.fmtValue(tag_ty),
|
||||
});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
try sema.addDeclaredHereNote(msg, union_ty);
|
||||
|
||||
@ -42,3 +42,284 @@ pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash) void {
|
||||
pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {
|
||||
return tv.val.enumToInt(tv.ty, buffer);
|
||||
}
|
||||
|
||||
const max_aggregate_items = 100;
|
||||
|
||||
pub fn format(
|
||||
tv: TypedValue,
|
||||
comptime fmt: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) !void {
|
||||
comptime std.debug.assert(fmt.len == 0);
|
||||
return tv.print(options, writer, 3);
|
||||
}
|
||||
|
||||
pub fn print(
|
||||
tv: TypedValue,
|
||||
options: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
level: u8,
|
||||
) @TypeOf(writer).Error!void {
|
||||
var val = tv.val;
|
||||
var ty = tv.ty;
|
||||
while (true) switch (val.tag()) {
|
||||
.u1_type => return writer.writeAll("u1"),
|
||||
.u8_type => return writer.writeAll("u8"),
|
||||
.i8_type => return writer.writeAll("i8"),
|
||||
.u16_type => return writer.writeAll("u16"),
|
||||
.i16_type => return writer.writeAll("i16"),
|
||||
.u32_type => return writer.writeAll("u32"),
|
||||
.i32_type => return writer.writeAll("i32"),
|
||||
.u64_type => return writer.writeAll("u64"),
|
||||
.i64_type => return writer.writeAll("i64"),
|
||||
.u128_type => return writer.writeAll("u128"),
|
||||
.i128_type => return writer.writeAll("i128"),
|
||||
.isize_type => return writer.writeAll("isize"),
|
||||
.usize_type => return writer.writeAll("usize"),
|
||||
.c_short_type => return writer.writeAll("c_short"),
|
||||
.c_ushort_type => return writer.writeAll("c_ushort"),
|
||||
.c_int_type => return writer.writeAll("c_int"),
|
||||
.c_uint_type => return writer.writeAll("c_uint"),
|
||||
.c_long_type => return writer.writeAll("c_long"),
|
||||
.c_ulong_type => return writer.writeAll("c_ulong"),
|
||||
.c_longlong_type => return writer.writeAll("c_longlong"),
|
||||
.c_ulonglong_type => return writer.writeAll("c_ulonglong"),
|
||||
.c_longdouble_type => return writer.writeAll("c_longdouble"),
|
||||
.f16_type => return writer.writeAll("f16"),
|
||||
.f32_type => return writer.writeAll("f32"),
|
||||
.f64_type => return writer.writeAll("f64"),
|
||||
.f80_type => return writer.writeAll("f80"),
|
||||
.f128_type => return writer.writeAll("f128"),
|
||||
.anyopaque_type => return writer.writeAll("anyopaque"),
|
||||
.bool_type => return writer.writeAll("bool"),
|
||||
.void_type => return writer.writeAll("void"),
|
||||
.type_type => return writer.writeAll("type"),
|
||||
.anyerror_type => return writer.writeAll("anyerror"),
|
||||
.comptime_int_type => return writer.writeAll("comptime_int"),
|
||||
.comptime_float_type => return writer.writeAll("comptime_float"),
|
||||
.noreturn_type => return writer.writeAll("noreturn"),
|
||||
.null_type => return writer.writeAll("@Type(.Null)"),
|
||||
.undefined_type => return writer.writeAll("@Type(.Undefined)"),
|
||||
.fn_noreturn_no_args_type => return writer.writeAll("fn() noreturn"),
|
||||
.fn_void_no_args_type => return writer.writeAll("fn() void"),
|
||||
.fn_naked_noreturn_no_args_type => return writer.writeAll("fn() callconv(.Naked) noreturn"),
|
||||
.fn_ccc_void_no_args_type => return writer.writeAll("fn() callconv(.C) void"),
|
||||
.single_const_pointer_to_comptime_int_type => return writer.writeAll("*const comptime_int"),
|
||||
.anyframe_type => return writer.writeAll("anyframe"),
|
||||
.const_slice_u8_type => return writer.writeAll("[]const u8"),
|
||||
.const_slice_u8_sentinel_0_type => return writer.writeAll("[:0]const u8"),
|
||||
.anyerror_void_error_union_type => return writer.writeAll("anyerror!void"),
|
||||
|
||||
.enum_literal_type => return writer.writeAll("@Type(.EnumLiteral)"),
|
||||
.manyptr_u8_type => return writer.writeAll("[*]u8"),
|
||||
.manyptr_const_u8_type => return writer.writeAll("[*]const u8"),
|
||||
.manyptr_const_u8_sentinel_0_type => return writer.writeAll("[*:0]const u8"),
|
||||
.atomic_order_type => return writer.writeAll("std.builtin.AtomicOrder"),
|
||||
.atomic_rmw_op_type => return writer.writeAll("std.builtin.AtomicRmwOp"),
|
||||
.calling_convention_type => return writer.writeAll("std.builtin.CallingConvention"),
|
||||
.address_space_type => return writer.writeAll("std.builtin.AddressSpace"),
|
||||
.float_mode_type => return writer.writeAll("std.builtin.FloatMode"),
|
||||
.reduce_op_type => return writer.writeAll("std.builtin.ReduceOp"),
|
||||
.call_options_type => return writer.writeAll("std.builtin.CallOptions"),
|
||||
.prefetch_options_type => return writer.writeAll("std.builtin.PrefetchOptions"),
|
||||
.export_options_type => return writer.writeAll("std.builtin.ExportOptions"),
|
||||
.extern_options_type => return writer.writeAll("std.builtin.ExternOptions"),
|
||||
.type_info_type => return writer.writeAll("std.builtin.Type"),
|
||||
|
||||
.empty_struct_value => return writer.writeAll(".{}"),
|
||||
.aggregate => {
|
||||
if (level == 0) {
|
||||
return writer.writeAll(".{ ... }");
|
||||
}
|
||||
const vals = val.castTag(.aggregate).?.data;
|
||||
if (ty.zigTypeTag() == .Struct) {
|
||||
try writer.writeAll(".{ ");
|
||||
const struct_fields = ty.structFields();
|
||||
const max_len = std.math.min(struct_fields.count(), max_aggregate_items);
|
||||
|
||||
const field_names = struct_fields.keys();
|
||||
const fields = struct_fields.values();
|
||||
|
||||
var i: u32 = 0;
|
||||
while (i < max_len) : (i += 1) {
|
||||
if (i != 0) try writer.writeAll(", ");
|
||||
try writer.print(".{s} = ", .{field_names[i]});
|
||||
try print(.{
|
||||
.ty = fields[i].ty,
|
||||
.val = vals[i],
|
||||
}, options, writer, level - 1);
|
||||
}
|
||||
return writer.writeAll(" }");
|
||||
} else {
|
||||
try writer.writeAll(".{ ");
|
||||
const elem_ty = ty.elemType2();
|
||||
const max_len = std.math.min(ty.arrayLen(), max_aggregate_items);
|
||||
|
||||
var i: u32 = 0;
|
||||
while (i < max_len) : (i += 1) {
|
||||
if (i != 0) try writer.writeAll(", ");
|
||||
try print(.{
|
||||
.ty = elem_ty,
|
||||
.val = vals[i],
|
||||
}, options, writer, level - 1);
|
||||
}
|
||||
return writer.writeAll(" }");
|
||||
}
|
||||
},
|
||||
.@"union" => {
|
||||
if (level == 0) {
|
||||
return writer.writeAll(".{ ... }");
|
||||
}
|
||||
const union_val = val.castTag(.@"union").?.data;
|
||||
try writer.writeAll(".{ ");
|
||||
|
||||
try print(.{
|
||||
.ty = ty.unionTagType().?,
|
||||
.val = union_val.tag,
|
||||
}, options, writer, level - 1);
|
||||
try writer.writeAll(" = ");
|
||||
try print(.{
|
||||
.ty = ty.unionFieldType(union_val.tag),
|
||||
.val = union_val.val,
|
||||
}, options, writer, level - 1);
|
||||
|
||||
return writer.writeAll(" }");
|
||||
},
|
||||
.null_value => return writer.writeAll("null"),
|
||||
.undef => return writer.writeAll("undefined"),
|
||||
.zero => return writer.writeAll("0"),
|
||||
.one => return writer.writeAll("1"),
|
||||
.void_value => return writer.writeAll("{}"),
|
||||
.unreachable_value => return writer.writeAll("unreachable"),
|
||||
.the_only_possible_value => {
|
||||
val = ty.onePossibleValue().?;
|
||||
},
|
||||
.bool_true => return writer.writeAll("true"),
|
||||
.bool_false => return writer.writeAll("false"),
|
||||
.ty => return val.castTag(.ty).?.data.format("", options, writer),
|
||||
.int_type => {
|
||||
const int_type = val.castTag(.int_type).?.data;
|
||||
return writer.print("{s}{d}", .{
|
||||
if (int_type.signed) "s" else "u",
|
||||
int_type.bits,
|
||||
});
|
||||
},
|
||||
.int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", options, writer),
|
||||
.int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, writer),
|
||||
.int_big_positive => return writer.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
|
||||
.int_big_negative => return writer.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),
|
||||
.function => return writer.print("(function '{s}')", .{val.castTag(.function).?.data.owner_decl.name}),
|
||||
.extern_fn => return writer.writeAll("(extern function)"),
|
||||
.variable => return writer.writeAll("(variable)"),
|
||||
.decl_ref_mut => {
|
||||
const decl = val.castTag(.decl_ref_mut).?.data.decl;
|
||||
if (level == 0) {
|
||||
return writer.print("(decl ref mut '{s}')", .{decl.name});
|
||||
}
|
||||
return print(.{
|
||||
.ty = decl.ty,
|
||||
.val = decl.val,
|
||||
}, options, writer, level - 1);
|
||||
},
|
||||
.decl_ref => {
|
||||
const decl = val.castTag(.decl_ref).?.data;
|
||||
if (level == 0) {
|
||||
return writer.print("(decl ref '{s}')", .{decl.name});
|
||||
}
|
||||
return print(.{
|
||||
.ty = decl.ty,
|
||||
.val = decl.val,
|
||||
}, options, writer, level - 1);
|
||||
},
|
||||
.elem_ptr => {
|
||||
const elem_ptr = val.castTag(.elem_ptr).?.data;
|
||||
try writer.writeAll("&");
|
||||
try print(.{
|
||||
.ty = elem_ptr.elem_ty,
|
||||
.val = elem_ptr.array_ptr,
|
||||
}, options, writer, level - 1);
|
||||
return writer.print("[{}]", .{elem_ptr.index});
|
||||
},
|
||||
.field_ptr => {
|
||||
const field_ptr = val.castTag(.field_ptr).?.data;
|
||||
try writer.writeAll("&");
|
||||
try print(.{
|
||||
.ty = field_ptr.container_ty,
|
||||
.val = field_ptr.container_ptr,
|
||||
}, options, writer, level - 1);
|
||||
|
||||
if (field_ptr.container_ty.zigTypeTag() == .Struct) {
|
||||
const field_name = field_ptr.container_ty.structFields().keys()[field_ptr.field_index];
|
||||
return writer.print(".{s}", .{field_name});
|
||||
} else if (field_ptr.container_ty.zigTypeTag() == .Union) {
|
||||
const field_name = field_ptr.container_ty.unionFields().keys()[field_ptr.field_index];
|
||||
return writer.print(".{s}", .{field_name});
|
||||
} else unreachable;
|
||||
},
|
||||
.empty_array => return writer.writeAll(".{}"),
|
||||
.enum_literal => return writer.print(".{}", .{std.zig.fmtId(val.castTag(.enum_literal).?.data)}),
|
||||
.enum_field_index => {
|
||||
return writer.print(".{s}", .{ty.enumFieldName(val.castTag(.enum_field_index).?.data)});
|
||||
},
|
||||
.bytes => return writer.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}),
|
||||
.repeated => {
|
||||
if (level == 0) {
|
||||
return writer.writeAll(".{ ... }");
|
||||
}
|
||||
var i: u32 = 0;
|
||||
try writer.writeAll(".{ ");
|
||||
const elem_tv = TypedValue{
|
||||
.ty = ty.elemType2(),
|
||||
.val = val.castTag(.repeated).?.data,
|
||||
};
|
||||
while (i < max_aggregate_items) : (i += 1) {
|
||||
if (i != 0) try writer.writeAll(", ");
|
||||
try print(elem_tv, options, writer, level - 1);
|
||||
}
|
||||
return writer.writeAll(" }");
|
||||
},
|
||||
.empty_array_sentinel => {
|
||||
if (level == 0) {
|
||||
return writer.writeAll(".{ (sentinel) }");
|
||||
}
|
||||
try writer.writeAll(".{ ");
|
||||
try print(.{
|
||||
.ty = ty.elemType2(),
|
||||
.val = ty.sentinel().?,
|
||||
}, options, writer, level - 1);
|
||||
return writer.writeAll(" }");
|
||||
},
|
||||
.slice => return writer.writeAll("(slice)"),
|
||||
.float_16 => return writer.print("{}", .{val.castTag(.float_16).?.data}),
|
||||
.float_32 => return writer.print("{}", .{val.castTag(.float_32).?.data}),
|
||||
.float_64 => return writer.print("{}", .{val.castTag(.float_64).?.data}),
|
||||
.float_80 => return writer.print("{}", .{val.castTag(.float_80).?.data}),
|
||||
.float_128 => return writer.print("{}", .{val.castTag(.float_128).?.data}),
|
||||
.@"error" => return writer.print("error.{s}", .{val.castTag(.@"error").?.data.name}),
|
||||
.eu_payload => {
|
||||
val = val.castTag(.eu_payload).?.data;
|
||||
},
|
||||
.opt_payload => {
|
||||
val = val.castTag(.opt_payload).?.data;
|
||||
},
|
||||
.eu_payload_ptr => {
|
||||
try writer.writeAll("&");
|
||||
val = val.castTag(.eu_payload_ptr).?.data.container_ptr;
|
||||
},
|
||||
.opt_payload_ptr => {
|
||||
try writer.writeAll("&");
|
||||
val = val.castTag(.opt_payload_ptr).?.data.container_ptr;
|
||||
},
|
||||
|
||||
// TODO these should not appear in this function
|
||||
.inferred_alloc => return writer.writeAll("(inferred allocation value)"),
|
||||
.inferred_alloc_comptime => return writer.writeAll("(inferred comptime allocation value)"),
|
||||
.bound_fn => {
|
||||
const bound_func = val.castTag(.bound_fn).?.data;
|
||||
return writer.print("(bound_fn %{}(%{})", .{ bound_func.func_inst, bound_func.arg0_inst });
|
||||
},
|
||||
.generic_poison_type => return writer.writeAll("(generic poison type)"),
|
||||
.generic_poison => return writer.writeAll("(generic poison)"),
|
||||
};
|
||||
}
|
||||
|
||||
@ -3873,7 +3873,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
|
||||
}
|
||||
|
||||
fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
|
||||
log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty, tv.val });
|
||||
log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty, tv.val.fmtDebug() });
|
||||
const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {
|
||||
return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
|
||||
};
|
||||
|
||||
@ -5735,7 +5735,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
|
||||
}
|
||||
|
||||
fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
|
||||
log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty, tv.val });
|
||||
log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty, tv.val.fmtDebug() });
|
||||
const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {
|
||||
return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
|
||||
};
|
||||
|
||||
@ -165,7 +165,7 @@ pub fn generateSymbol(
|
||||
const target = bin_file.options.target;
|
||||
const endian = target.cpu.arch.endian();
|
||||
|
||||
log.debug("generateSymbol: ty = {}, val = {}", .{ typed_value.ty, typed_value.val });
|
||||
log.debug("generateSymbol: ty = {}, val = {}", .{ typed_value.ty, typed_value.val.fmtDebug() });
|
||||
|
||||
if (typed_value.val.isUndefDeep()) {
|
||||
const abi_size = try math.cast(usize, typed_value.ty.abiSize(target));
|
||||
|
||||
@ -1676,7 +1676,7 @@ pub const DeclGen = struct {
|
||||
const decl = dg.decl;
|
||||
assert(decl.has_tv);
|
||||
|
||||
log.debug("gen: {s} type: {}, value: {}", .{ decl.name, decl.ty, decl.val });
|
||||
log.debug("gen: {s} type: {}, value: {}", .{ decl.name, decl.ty, decl.val.fmtDebug() });
|
||||
|
||||
if (decl.val.castTag(.function)) |func_payload| {
|
||||
_ = func_payload;
|
||||
|
||||
@ -491,7 +491,7 @@ const Writer = struct {
|
||||
fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
|
||||
const val = w.air.values[ty_pl.payload];
|
||||
try s.print("{}, {}", .{ w.air.getRefType(ty_pl.ty), val });
|
||||
try s.print("{}, {}", .{ w.air.getRefType(ty_pl.ty), val.fmtDebug() });
|
||||
}
|
||||
|
||||
fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
|
||||
12
src/type.zig
12
src/type.zig
@ -1633,7 +1633,7 @@ pub const Type = extern union {
|
||||
},
|
||||
.array_sentinel => {
|
||||
const payload = ty.castTag(.array_sentinel).?.data;
|
||||
try writer.print("[{d}:{}]", .{ payload.len, payload.sentinel });
|
||||
try writer.print("[{d}:{}]", .{ payload.len, payload.sentinel.fmtValue(payload.elem_type) });
|
||||
ty = payload.elem_type;
|
||||
continue;
|
||||
},
|
||||
@ -1648,8 +1648,7 @@ pub const Type = extern union {
|
||||
}
|
||||
try field_ty.format("", .{}, writer);
|
||||
if (val.tag() != .unreachable_value) {
|
||||
try writer.writeAll(" = ");
|
||||
try val.format("", .{}, writer);
|
||||
try writer.print(" = {}", .{val.fmtValue(field_ty)});
|
||||
}
|
||||
}
|
||||
try writer.writeAll("}");
|
||||
@ -1668,8 +1667,7 @@ pub const Type = extern union {
|
||||
try writer.writeAll(": ");
|
||||
try field_ty.format("", .{}, writer);
|
||||
if (val.tag() != .unreachable_value) {
|
||||
try writer.writeAll(" = ");
|
||||
try val.format("", .{}, writer);
|
||||
try writer.print(" = {}", .{val.fmtValue(field_ty)});
|
||||
}
|
||||
}
|
||||
try writer.writeAll("}");
|
||||
@ -1754,8 +1752,8 @@ pub const Type = extern union {
|
||||
const payload = ty.castTag(.pointer).?.data;
|
||||
if (payload.sentinel) |some| switch (payload.size) {
|
||||
.One, .C => unreachable,
|
||||
.Many => try writer.print("[*:{}]", .{some}),
|
||||
.Slice => try writer.print("[:{}]", .{some}),
|
||||
.Many => try writer.print("[*:{}]", .{some.fmtValue(payload.pointee_type)}),
|
||||
.Slice => try writer.print("[:{}]", .{some.fmtValue(payload.pointee_type)}),
|
||||
} else switch (payload.size) {
|
||||
.One => try writer.writeAll("*"),
|
||||
.Many => try writer.writeAll("[*]"),
|
||||
|
||||
@ -600,9 +600,17 @@ pub const Value = extern union {
|
||||
return Value{ .ptr_otherwise = &new_payload.base };
|
||||
}
|
||||
|
||||
pub fn format(val: Value, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
_ = val;
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
_ = writer;
|
||||
@compileError("do not use format values directly; use either fmtDebug or fmtValue");
|
||||
}
|
||||
|
||||
/// TODO this should become a debug dump() function. In order to print values in a meaningful way
|
||||
/// we also need access to the type.
|
||||
pub fn format(
|
||||
pub fn dump(
|
||||
start_val: Value,
|
||||
comptime fmt: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
@ -766,6 +774,16 @@ pub const Value = extern union {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) {
|
||||
return .{ .data = val };
|
||||
}
|
||||
|
||||
const TypedValue = @import("TypedValue.zig");
|
||||
|
||||
pub fn fmtValue(val: Value, ty: Type) std.fmt.Formatter(TypedValue.format) {
|
||||
return .{ .data = .{ .ty = ty, .val = val } };
|
||||
}
|
||||
|
||||
/// Asserts that the value is representable as an array of bytes.
|
||||
/// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
|
||||
pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator) ![]u8 {
|
||||
|
||||
@ -5,10 +5,8 @@ const ptr_size = @sizeOf(usize);
|
||||
|
||||
test "type pun signed and unsigned as single pointer" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend != .stage1) {
|
||||
// TODO https://github.com/ziglang/zig/issues/9646
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime {
|
||||
var x: u32 = 0;
|
||||
@ -20,10 +18,7 @@ test "type pun signed and unsigned as single pointer" {
|
||||
|
||||
test "type pun signed and unsigned as many pointer" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend != .stage1) {
|
||||
// TODO https://github.com/ziglang/zig/issues/9646
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime {
|
||||
var x: u32 = 0;
|
||||
@ -35,10 +30,7 @@ test "type pun signed and unsigned as many pointer" {
|
||||
|
||||
test "type pun signed and unsigned as array pointer" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend != .stage1) {
|
||||
// TODO https://github.com/ziglang/zig/issues/9646
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime {
|
||||
var x: u32 = 0;
|
||||
@ -82,10 +74,7 @@ test "type pun signed and unsigned as array pointer" {
|
||||
|
||||
test "type pun value and struct" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend != .stage1) {
|
||||
// TODO https://github.com/ziglang/zig/issues/9646
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime {
|
||||
const StructOfU32 = extern struct { x: u32 };
|
||||
@ -102,10 +91,8 @@ fn bigToNativeEndian(comptime T: type, v: T) T {
|
||||
}
|
||||
test "type pun endianness" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend != .stage1) {
|
||||
// TODO https://github.com/ziglang/zig/issues/9646
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime {
|
||||
const StructOfBytes = extern struct { x: [4]u8 };
|
||||
@ -412,3 +399,26 @@ test "offset field ptr by enclosing array element size" {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test "accessing reinterpreted memory of parent object" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
const S = extern struct {
|
||||
a: f32,
|
||||
b: [4]u8,
|
||||
c: f32,
|
||||
};
|
||||
const expected = if (endian == .Little) 102 else 38;
|
||||
|
||||
comptime {
|
||||
const x = S{
|
||||
.a = 1.5,
|
||||
.b = [_]u8{ 1, 2, 3, 4 },
|
||||
.c = 2.6,
|
||||
};
|
||||
const ptr = &x.b[0];
|
||||
const b = @ptrCast([*c]const u8, ptr)[5];
|
||||
try testing.expect(b == expected);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user