Skip to content

Commit 21a6a1b

Browse files
mluggandrewrk
authored andcommitted
Sema: cap depth of value printing in type names
Certain types (notably, `std.ComptimeStringMap`) were resulting in excessively long type names when instantiated, which in turn resulted in excessively long symbol names. These are problematic for two reasons: * Symbol names are sometimes read by humans -- they ought to be readable. * Some other applications (looking at you, xcode) trip on very long symbol names. To work around this for now, we cap the depth of value printing at 1, as opposed to the normal 3. This doesn't guarantee anything -- there could still be, for instance, an incredibly long aggregate -- but it works around the issue in practice for the time being.
1 parent 187f0c1 commit 21a6a1b

File tree

3 files changed

+35
-19
lines changed

3 files changed

+35
-19
lines changed

src/Sema.zig

+27-17
Original file line numberDiff line numberDiff line change
@@ -2869,14 +2869,14 @@ fn createAnonymousDeclTypeNamed(
28692869
anon_prefix: []const u8,
28702870
inst: ?Zir.Inst.Index,
28712871
) !InternPool.DeclIndex {
2872-
const mod = sema.mod;
2873-
const ip = &mod.intern_pool;
2872+
const zcu = sema.mod;
2873+
const ip = &zcu.intern_pool;
28742874
const gpa = sema.gpa;
28752875
const namespace = block.namespace;
2876-
const src_decl = mod.declPtr(block.src_decl);
2876+
const src_decl = zcu.declPtr(block.src_decl);
28772877
const src_node = src_decl.relativeToNodeIndex(src.node_offset.x);
2878-
const new_decl_index = try mod.allocateNewDecl(namespace, src_node);
2879-
errdefer mod.destroyDecl(new_decl_index);
2878+
const new_decl_index = try zcu.allocateNewDecl(namespace, src_node);
2879+
errdefer zcu.destroyDecl(new_decl_index);
28802880

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

2890-
const name = mod.intern_pool.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{
2891-
src_decl.name.fmt(&mod.intern_pool), anon_prefix, @intFromEnum(new_decl_index),
2890+
const name = ip.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{
2891+
src_decl.name.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),
28922892
}, .no_embedded_nulls) catch unreachable;
2893-
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
2893+
try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
28942894
return new_decl_index;
28952895
},
28962896
.parent => {
2897-
const name = mod.declPtr(block.src_decl).name;
2898-
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
2897+
const name = zcu.declPtr(block.src_decl).name;
2898+
try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
28992899
return new_decl_index;
29002900
},
29012901
.func => {
@@ -2906,7 +2906,7 @@ fn createAnonymousDeclTypeNamed(
29062906
defer buf.deinit();
29072907

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

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

29232923
if (arg_i != 0) try writer.writeByte(',');
2924-
try writer.print("{}", .{arg_val.fmtValue(sema.mod, sema)});
2924+
2925+
// Limiting the depth here helps avoid type names getting too long, which
2926+
// in turn helps to avoid unreasonably long symbol names for namespaced
2927+
// symbols. Such names should ideally be human-readable, and additionally,
2928+
// some tooling may not support very long symbol names.
2929+
try writer.print("{}", .{Value.fmtValueFull(.{
2930+
.val = arg_val,
2931+
.mod = zcu,
2932+
.opt_sema = sema,
2933+
.depth = 1,
2934+
})});
29252935

29262936
arg_i += 1;
29272937
continue;
@@ -2930,8 +2940,8 @@ fn createAnonymousDeclTypeNamed(
29302940
};
29312941

29322942
try writer.writeByte(')');
2933-
const name = try mod.intern_pool.getOrPutString(gpa, buf.items, .no_embedded_nulls);
2934-
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
2943+
const name = try ip.getOrPutString(gpa, buf.items, .no_embedded_nulls);
2944+
try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
29352945
return new_decl_index;
29362946
},
29372947
.dbg_var => {
@@ -2942,10 +2952,10 @@ fn createAnonymousDeclTypeNamed(
29422952
.dbg_var_ptr, .dbg_var_val => {
29432953
if (zir_data[i].str_op.operand != ref) continue;
29442954

2945-
const name = try mod.intern_pool.getOrPutStringFmt(gpa, "{}.{s}", .{
2946-
src_decl.name.fmt(&mod.intern_pool), zir_data[i].str_op.getStr(sema.code),
2955+
const name = try ip.getOrPutStringFmt(gpa, "{}.{s}", .{
2956+
src_decl.name.fmt(ip), zir_data[i].str_op.getStr(sema.code),
29472957
}, .no_embedded_nulls);
2948-
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
2958+
try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
29492959
return new_decl_index;
29502960
},
29512961
else => {},

src/Value.zig

+5
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,14 @@ pub fn fmtValue(val: Value, mod: *Module, opt_sema: ?*Sema) std.fmt.Formatter(pr
4444
.val = val,
4545
.mod = mod,
4646
.opt_sema = opt_sema,
47+
.depth = 3,
4748
} };
4849
}
4950

51+
pub fn fmtValueFull(ctx: print_value.FormatContext) std.fmt.Formatter(print_value.format) {
52+
return .{ .data = ctx };
53+
}
54+
5055
/// Converts `val` to a null-terminated string stored in the InternPool.
5156
/// Asserts `val` is an array of `u8`
5257
pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminatedString {

src/print_value.zig

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ const Target = std.Target;
1414
const max_aggregate_items = 100;
1515
const max_string_len = 256;
1616

17-
const FormatContext = struct {
17+
pub const FormatContext = struct {
1818
val: Value,
1919
mod: *Module,
2020
opt_sema: ?*Sema,
21+
depth: u8,
2122
};
2223

2324
pub fn format(
@@ -28,7 +29,7 @@ pub fn format(
2829
) !void {
2930
_ = options;
3031
comptime std.debug.assert(fmt.len == 0);
31-
return print(ctx.val, writer, 3, ctx.mod, ctx.opt_sema) catch |err| switch (err) {
32+
return print(ctx.val, writer, ctx.depth, ctx.mod, ctx.opt_sema) catch |err| switch (err) {
3233
error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
3334
error.ComptimeBreak, error.ComptimeReturn => unreachable,
3435
error.AnalysisFail, error.NeededSourceLocation => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully

0 commit comments

Comments
 (0)