aboutsummaryrefslogtreecommitdiff
path: root/src/print_value.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/print_value.zig')
-rw-r--r--src/print_value.zig104
1 files changed, 69 insertions, 35 deletions
diff --git a/src/print_value.zig b/src/print_value.zig
index c19ba43af3..46b9203068 100644
--- a/src/print_value.zig
+++ b/src/print_value.zig
@@ -20,18 +20,35 @@ pub const FormatContext = struct {
depth: u8,
};
-pub fn format(
+pub fn formatSema(
ctx: FormatContext,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = options;
+ const sema = ctx.opt_sema.?;
comptime std.debug.assert(fmt.len == 0);
- return print(ctx.val, writer, ctx.depth, ctx.pt, ctx.opt_sema) catch |err| switch (err) {
+ return print(ctx.val, writer, ctx.depth, ctx.pt, true, sema) catch |err| switch (err) {
error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
error.ComptimeBreak, error.ComptimeReturn => unreachable,
- error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully
+ error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `sema` more fully
+ else => |e| return e,
+ };
+}
+
+pub fn format(
+ ctx: FormatContext,
+ comptime fmt: []const u8,
+ options: std.fmt.FormatOptions,
+ writer: anytype,
+) !void {
+ _ = options;
+ std.debug.assert(ctx.opt_sema == null);
+ comptime std.debug.assert(fmt.len == 0);
+ return print(ctx.val, writer, ctx.depth, ctx.pt, false, {}) catch |err| switch (err) {
+ error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
+ error.ComptimeBreak, error.ComptimeReturn, error.AnalysisFail => unreachable,
else => |e| return e,
};
}
@@ -42,7 +59,8 @@ pub fn print(
level: u8,
pt: Zcu.PerThread,
/// If this `Sema` is provided, we will recurse through pointers where possible to provide friendly output.
- opt_sema: ?*Sema,
+ comptime have_sema: bool,
+ sema: if (have_sema) *Sema else void,
) (@TypeOf(writer).Error || Zcu.CompileError)!void {
const mod = pt.zcu;
const ip = &mod.intern_pool;
@@ -80,11 +98,11 @@ pub fn print(
}),
.int => |int| switch (int.storage) {
inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),
- .lazy_align => |ty| if (opt_sema != null) {
+ .lazy_align => |ty| if (have_sema) {
const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(pt, .sema)).scalar;
try writer.print("{}", .{a.toByteUnits() orelse 0});
} else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(pt)}),
- .lazy_size => |ty| if (opt_sema != null) {
+ .lazy_size => |ty| if (have_sema) {
const s = (try Type.fromInterned(ty).abiSizeAdvanced(pt, .sema)).scalar;
try writer.print("{}", .{s});
} else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(pt)}),
@@ -96,7 +114,7 @@ pub fn print(
.err_name => |err_name| try writer.print("error.{}", .{
err_name.fmt(ip),
}),
- .payload => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema),
+ .payload => |payload| try print(Value.fromInterned(payload), writer, level, pt, have_sema, sema),
},
.enum_literal => |enum_literal| try writer.print(".{}", .{
enum_literal.fmt(ip),
@@ -110,7 +128,7 @@ pub fn print(
return writer.writeAll("@enumFromInt(...)");
}
try writer.writeAll("@enumFromInt(");
- try print(Value.fromInterned(enum_tag.int), writer, level - 1, pt, opt_sema);
+ try print(Value.fromInterned(enum_tag.int), writer, level - 1, pt, have_sema, sema);
try writer.writeAll(")");
},
.empty_enum_value => try writer.writeAll("(empty enum value)"),
@@ -124,15 +142,15 @@ pub fn print(
.decl, .int => false,
};
if (print_contents) {
- // TODO: eventually we want to load the slice as an array with `opt_sema`, but that's
+ // TODO: eventually we want to load the slice as an array with `sema`, but that's
// currently not possible without e.g. triggering compile errors.
}
- try printPtr(Value.fromInterned(slice.ptr), writer, level, pt, opt_sema);
+ try printPtr(Value.fromInterned(slice.ptr), writer, level, pt, have_sema, sema);
try writer.writeAll("[0..");
if (level == 0) {
try writer.writeAll("(...)");
} else {
- try print(Value.fromInterned(slice.len), writer, level - 1, pt, opt_sema);
+ try print(Value.fromInterned(slice.len), writer, level - 1, pt, have_sema, sema);
}
try writer.writeAll("]");
},
@@ -143,16 +161,16 @@ pub fn print(
.decl, .int => false,
};
if (print_contents) {
- // TODO: eventually we want to load the pointer with `opt_sema`, but that's
+ // TODO: eventually we want to load the pointer with `sema`, but that's
// currently not possible without e.g. triggering compile errors.
}
- try printPtr(val, writer, level, pt, opt_sema);
+ try printPtr(val, writer, level, pt, have_sema, sema);
},
.opt => |opt| switch (opt.val) {
.none => try writer.writeAll("null"),
- else => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema),
+ else => |payload| try print(Value.fromInterned(payload), writer, level, pt, have_sema, sema),
},
- .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, pt, opt_sema),
+ .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, pt, have_sema, sema),
.un => |un| {
if (level == 0) {
try writer.writeAll(".{ ... }");
@@ -161,13 +179,13 @@ pub fn print(
if (un.tag == .none) {
const backing_ty = try val.typeOf(mod).unionBackingType(pt);
try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(pt)});
- try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema);
+ try print(Value.fromInterned(un.val), writer, level - 1, pt, have_sema, sema);
try writer.writeAll("))");
} else {
try writer.writeAll(".{ ");
- try print(Value.fromInterned(un.tag), writer, level - 1, pt, opt_sema);
+ try print(Value.fromInterned(un.tag), writer, level - 1, pt, have_sema, sema);
try writer.writeAll(" = ");
- try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema);
+ try print(Value.fromInterned(un.val), writer, level - 1, pt, have_sema, sema);
try writer.writeAll(" }");
}
},
@@ -182,7 +200,8 @@ fn printAggregate(
writer: anytype,
level: u8,
pt: Zcu.PerThread,
- opt_sema: ?*Sema,
+ comptime have_sema: bool,
+ sema: if (have_sema) *Sema else void,
) (@TypeOf(writer).Error || Zcu.CompileError)!void {
if (level == 0) {
if (is_ref) try writer.writeByte('&');
@@ -203,7 +222,7 @@ fn printAggregate(
if (i != 0) try writer.writeAll(", ");
const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?;
try writer.print(".{i} = ", .{field_name.fmt(ip)});
- try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema);
+ try print(try val.fieldValue(pt, i), writer, level - 1, pt, have_sema, sema);
}
try writer.writeAll(" }");
return;
@@ -253,7 +272,7 @@ fn printAggregate(
const max_len = @min(len, max_aggregate_items);
for (0..max_len) |i| {
if (i != 0) try writer.writeAll(", ");
- try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema);
+ try print(try val.fieldValue(pt, i), writer, level - 1, pt, have_sema, sema);
}
if (len > max_aggregate_items) {
try writer.writeAll(", ...");
@@ -261,7 +280,14 @@ fn printAggregate(
return writer.writeAll(" }");
}
-fn printPtr(ptr_val: Value, writer: anytype, level: u8, pt: Zcu.PerThread, opt_sema: ?*Sema) (@TypeOf(writer).Error || Zcu.CompileError)!void {
+fn printPtr(
+ ptr_val: Value,
+ writer: anytype,
+ level: u8,
+ pt: Zcu.PerThread,
+ comptime have_sema: bool,
+ sema: if (have_sema) *Sema else void,
+) (@TypeOf(writer).Error || Zcu.CompileError)!void {
const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) {
.undef => return writer.writeAll("undefined"),
.ptr => |ptr| ptr,
@@ -278,7 +304,8 @@ fn printPtr(ptr_val: Value, writer: anytype, level: u8, pt: Zcu.PerThread, opt_s
writer,
level,
pt,
- opt_sema,
+ have_sema,
+ sema,
),
else => {},
}
@@ -286,12 +313,19 @@ fn printPtr(ptr_val: Value, writer: anytype, level: u8, pt: Zcu.PerThread, opt_s
var arena = std.heap.ArenaAllocator.init(pt.zcu.gpa);
defer arena.deinit();
- const derivation = try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, opt_sema);
- try printPtrDerivation(derivation, writer, level, pt, opt_sema);
+ const derivation = try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, have_sema, sema);
+ try printPtrDerivation(derivation, writer, level, pt, have_sema, sema);
}
/// Print `derivation` as an lvalue, i.e. such that writing `&` before this gives the pointer value.
-fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, level: u8, pt: Zcu.PerThread, opt_sema: ?*Sema) (@TypeOf(writer).Error || Zcu.CompileError)!void {
+fn printPtrDerivation(
+ derivation: Value.PointerDeriveStep,
+ writer: anytype,
+ level: u8,
+ pt: Zcu.PerThread,
+ comptime have_sema: bool,
+ sema: if (have_sema) *Sema else void,
+) (@TypeOf(writer).Error || Zcu.CompileError)!void {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
switch (derivation) {
@@ -305,31 +339,31 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve
.anon_decl_ptr => |anon| {
const ty = Value.fromInterned(anon.val).typeOf(zcu);
try writer.print("@as({}, ", .{ty.fmt(pt)});
- try print(Value.fromInterned(anon.val), writer, level - 1, pt, opt_sema);
+ try print(Value.fromInterned(anon.val), writer, level - 1, pt, have_sema, sema);
try writer.writeByte(')');
},
.comptime_alloc_ptr => |info| {
try writer.print("@as({}, ", .{info.val.typeOf(zcu).fmt(pt)});
- try print(info.val, writer, level - 1, pt, opt_sema);
+ try print(info.val, writer, level - 1, pt, have_sema, sema);
try writer.writeByte(')');
},
.comptime_field_ptr => |val| {
const ty = val.typeOf(zcu);
try writer.print("@as({}, ", .{ty.fmt(pt)});
- try print(val, writer, level - 1, pt, opt_sema);
+ try print(val, writer, level - 1, pt, have_sema, sema);
try writer.writeByte(')');
},
.eu_payload_ptr => |info| {
try writer.writeByte('(');
- try printPtrDerivation(info.parent.*, writer, level, pt, opt_sema);
+ try printPtrDerivation(info.parent.*, writer, level, pt, have_sema, sema);
try writer.writeAll(" catch unreachable)");
},
.opt_payload_ptr => |info| {
- try printPtrDerivation(info.parent.*, writer, level, pt, opt_sema);
+ try printPtrDerivation(info.parent.*, writer, level, pt, have_sema, sema);
try writer.writeAll(".?");
},
.field_ptr => |field| {
- try printPtrDerivation(field.parent.*, writer, level, pt, opt_sema);
+ try printPtrDerivation(field.parent.*, writer, level, pt, have_sema, sema);
const agg_ty = (try field.parent.ptrType(pt)).childType(zcu);
switch (agg_ty.zigTypeTag(zcu)) {
.Struct => if (agg_ty.structFieldName(field.field_idx, zcu).unwrap()) |field_name| {
@@ -351,16 +385,16 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve
}
},
.elem_ptr => |elem| {
- try printPtrDerivation(elem.parent.*, writer, level, pt, opt_sema);
+ try printPtrDerivation(elem.parent.*, writer, level, pt, have_sema, sema);
try writer.print("[{d}]", .{elem.elem_idx});
},
.offset_and_cast => |oac| if (oac.byte_offset == 0) {
try writer.print("@as({}, @ptrCast(", .{oac.new_ptr_ty.fmt(pt)});
- try printPtrDerivation(oac.parent.*, writer, level, pt, opt_sema);
+ try printPtrDerivation(oac.parent.*, writer, level, pt, have_sema, sema);
try writer.writeAll("))");
} else {
try writer.print("@as({}, @ptrFromInt(@intFromPtr(", .{oac.new_ptr_ty.fmt(pt)});
- try printPtrDerivation(oac.parent.*, writer, level, pt, opt_sema);
+ try printPtrDerivation(oac.parent.*, writer, level, pt, have_sema, sema);
try writer.print(") + {d}))", .{oac.byte_offset});
},
}