Skip to content

Sema: cap depth of value printing in type names #19682

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 27 additions & 17 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2869,14 +2869,14 @@ fn createAnonymousDeclTypeNamed(
anon_prefix: []const u8,
inst: ?Zir.Inst.Index,
) !InternPool.DeclIndex {
const mod = sema.mod;
const ip = &mod.intern_pool;
const zcu = sema.mod;
const ip = &zcu.intern_pool;
const gpa = sema.gpa;
const namespace = block.namespace;
const src_decl = mod.declPtr(block.src_decl);
const src_decl = zcu.declPtr(block.src_decl);
const src_node = src_decl.relativeToNodeIndex(src.node_offset.x);
const new_decl_index = try mod.allocateNewDecl(namespace, src_node);
errdefer mod.destroyDecl(new_decl_index);
const new_decl_index = try zcu.allocateNewDecl(namespace, src_node);
errdefer zcu.destroyDecl(new_decl_index);

switch (name_strategy) {
.anon => {
Expand All @@ -2887,15 +2887,15 @@ fn createAnonymousDeclTypeNamed(
// This name is also used as the key in the parent namespace so it cannot be
// renamed.

const name = mod.intern_pool.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{
src_decl.name.fmt(&mod.intern_pool), anon_prefix, @intFromEnum(new_decl_index),
const name = ip.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{
src_decl.name.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),
}, .no_embedded_nulls) catch unreachable;
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
return new_decl_index;
},
.parent => {
const name = mod.declPtr(block.src_decl).name;
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
const name = zcu.declPtr(block.src_decl).name;
try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
return new_decl_index;
},
.func => {
Expand All @@ -2906,7 +2906,7 @@ fn createAnonymousDeclTypeNamed(
defer buf.deinit();

const writer = buf.writer();
try writer.print("{}(", .{mod.declPtr(block.src_decl).name.fmt(&mod.intern_pool)});
try writer.print("{}(", .{zcu.declPtr(block.src_decl).name.fmt(ip)});

var arg_i: usize = 0;
for (fn_info.param_body) |zir_inst| switch (zir_tags[@intFromEnum(zir_inst)]) {
Expand All @@ -2921,7 +2921,17 @@ fn createAnonymousDeclTypeNamed(
return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null);

if (arg_i != 0) try writer.writeByte(',');
try writer.print("{}", .{arg_val.fmtValue(sema.mod, sema)});

// Limiting the depth here helps avoid type names getting too long, which
// in turn helps to avoid unreasonably long symbol names for namespaced
// symbols. Such names should ideally be human-readable, and additionally,
// some tooling may not support very long symbol names.
try writer.print("{}", .{Value.fmtValueFull(.{
.val = arg_val,
.mod = zcu,
.opt_sema = sema,
.depth = 1,
})});

arg_i += 1;
continue;
Expand All @@ -2930,8 +2940,8 @@ fn createAnonymousDeclTypeNamed(
};

try writer.writeByte(')');
const name = try mod.intern_pool.getOrPutString(gpa, buf.items, .no_embedded_nulls);
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
const name = try ip.getOrPutString(gpa, buf.items, .no_embedded_nulls);
try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
return new_decl_index;
},
.dbg_var => {
Expand All @@ -2942,10 +2952,10 @@ fn createAnonymousDeclTypeNamed(
.dbg_var_ptr, .dbg_var_val => {
if (zir_data[i].str_op.operand != ref) continue;

const name = try mod.intern_pool.getOrPutStringFmt(gpa, "{}.{s}", .{
src_decl.name.fmt(&mod.intern_pool), zir_data[i].str_op.getStr(sema.code),
const name = try ip.getOrPutStringFmt(gpa, "{}.{s}", .{
src_decl.name.fmt(ip), zir_data[i].str_op.getStr(sema.code),
}, .no_embedded_nulls);
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
return new_decl_index;
},
else => {},
Expand Down
5 changes: 5 additions & 0 deletions src/Value.zig
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@ pub fn fmtValue(val: Value, mod: *Module, opt_sema: ?*Sema) std.fmt.Formatter(pr
.val = val,
.mod = mod,
.opt_sema = opt_sema,
.depth = 3,
} };
}

pub fn fmtValueFull(ctx: print_value.FormatContext) std.fmt.Formatter(print_value.format) {
return .{ .data = ctx };
}

/// Converts `val` to a null-terminated string stored in the InternPool.
/// Asserts `val` is an array of `u8`
pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminatedString {
Expand Down
5 changes: 3 additions & 2 deletions src/print_value.zig
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ const Target = std.Target;
const max_aggregate_items = 100;
const max_string_len = 256;

const FormatContext = struct {
pub const FormatContext = struct {
val: Value,
mod: *Module,
opt_sema: ?*Sema,
depth: u8,
};

pub fn format(
Expand All @@ -28,7 +29,7 @@ pub fn format(
) !void {
_ = options;
comptime std.debug.assert(fmt.len == 0);
return print(ctx.val, writer, 3, ctx.mod, ctx.opt_sema) catch |err| switch (err) {
return print(ctx.val, writer, ctx.depth, ctx.mod, ctx.opt_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, error.NeededSourceLocation => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully
Expand Down