mirror of
https://github.com/ziglang/zig.git
synced 2025-12-15 18:53:07 +00:00
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.
This commit is contained in:
parent
187f0c1e26
commit
21a6a1b0f2
44
src/Sema.zig
44
src/Sema.zig
@ -2869,14 +2869,14 @@ fn createAnonymousDeclTypeNamed(
|
|||||||
anon_prefix: []const u8,
|
anon_prefix: []const u8,
|
||||||
inst: ?Zir.Inst.Index,
|
inst: ?Zir.Inst.Index,
|
||||||
) !InternPool.DeclIndex {
|
) !InternPool.DeclIndex {
|
||||||
const mod = sema.mod;
|
const zcu = sema.mod;
|
||||||
const ip = &mod.intern_pool;
|
const ip = &zcu.intern_pool;
|
||||||
const gpa = sema.gpa;
|
const gpa = sema.gpa;
|
||||||
const namespace = block.namespace;
|
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 src_node = src_decl.relativeToNodeIndex(src.node_offset.x);
|
||||||
const new_decl_index = try mod.allocateNewDecl(namespace, src_node);
|
const new_decl_index = try zcu.allocateNewDecl(namespace, src_node);
|
||||||
errdefer mod.destroyDecl(new_decl_index);
|
errdefer zcu.destroyDecl(new_decl_index);
|
||||||
|
|
||||||
switch (name_strategy) {
|
switch (name_strategy) {
|
||||||
.anon => {
|
.anon => {
|
||||||
@ -2887,15 +2887,15 @@ fn createAnonymousDeclTypeNamed(
|
|||||||
// This name is also used as the key in the parent namespace so it cannot be
|
// This name is also used as the key in the parent namespace so it cannot be
|
||||||
// renamed.
|
// renamed.
|
||||||
|
|
||||||
const name = mod.intern_pool.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{
|
const name = ip.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{
|
||||||
src_decl.name.fmt(&mod.intern_pool), anon_prefix, @intFromEnum(new_decl_index),
|
src_decl.name.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),
|
||||||
}, .no_embedded_nulls) catch unreachable;
|
}, .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;
|
return new_decl_index;
|
||||||
},
|
},
|
||||||
.parent => {
|
.parent => {
|
||||||
const name = mod.declPtr(block.src_decl).name;
|
const name = zcu.declPtr(block.src_decl).name;
|
||||||
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;
|
return new_decl_index;
|
||||||
},
|
},
|
||||||
.func => {
|
.func => {
|
||||||
@ -2906,7 +2906,7 @@ fn createAnonymousDeclTypeNamed(
|
|||||||
defer buf.deinit();
|
defer buf.deinit();
|
||||||
|
|
||||||
const writer = buf.writer();
|
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;
|
var arg_i: usize = 0;
|
||||||
for (fn_info.param_body) |zir_inst| switch (zir_tags[@intFromEnum(zir_inst)]) {
|
for (fn_info.param_body) |zir_inst| switch (zir_tags[@intFromEnum(zir_inst)]) {
|
||||||
@ -2921,7 +2921,17 @@ 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.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;
|
arg_i += 1;
|
||||||
continue;
|
continue;
|
||||||
@ -2930,8 +2940,8 @@ fn createAnonymousDeclTypeNamed(
|
|||||||
};
|
};
|
||||||
|
|
||||||
try writer.writeByte(')');
|
try writer.writeByte(')');
|
||||||
const name = try mod.intern_pool.getOrPutString(gpa, buf.items, .no_embedded_nulls);
|
const name = try ip.getOrPutString(gpa, buf.items, .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;
|
return new_decl_index;
|
||||||
},
|
},
|
||||||
.dbg_var => {
|
.dbg_var => {
|
||||||
@ -2942,10 +2952,10 @@ fn createAnonymousDeclTypeNamed(
|
|||||||
.dbg_var_ptr, .dbg_var_val => {
|
.dbg_var_ptr, .dbg_var_val => {
|
||||||
if (zir_data[i].str_op.operand != ref) continue;
|
if (zir_data[i].str_op.operand != ref) continue;
|
||||||
|
|
||||||
const name = try mod.intern_pool.getOrPutStringFmt(gpa, "{}.{s}", .{
|
const name = try ip.getOrPutStringFmt(gpa, "{}.{s}", .{
|
||||||
src_decl.name.fmt(&mod.intern_pool), zir_data[i].str_op.getStr(sema.code),
|
src_decl.name.fmt(ip), zir_data[i].str_op.getStr(sema.code),
|
||||||
}, .no_embedded_nulls);
|
}, .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;
|
return new_decl_index;
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
|
|||||||
@ -44,9 +44,14 @@ pub fn fmtValue(val: Value, mod: *Module, opt_sema: ?*Sema) std.fmt.Formatter(pr
|
|||||||
.val = val,
|
.val = val,
|
||||||
.mod = mod,
|
.mod = mod,
|
||||||
.opt_sema = opt_sema,
|
.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.
|
/// Converts `val` to a null-terminated string stored in the InternPool.
|
||||||
/// Asserts `val` is an array of `u8`
|
/// Asserts `val` is an array of `u8`
|
||||||
pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminatedString {
|
pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminatedString {
|
||||||
|
|||||||
@ -14,10 +14,11 @@ const Target = std.Target;
|
|||||||
const max_aggregate_items = 100;
|
const max_aggregate_items = 100;
|
||||||
const max_string_len = 256;
|
const max_string_len = 256;
|
||||||
|
|
||||||
const FormatContext = struct {
|
pub const FormatContext = struct {
|
||||||
val: Value,
|
val: Value,
|
||||||
mod: *Module,
|
mod: *Module,
|
||||||
opt_sema: ?*Sema,
|
opt_sema: ?*Sema,
|
||||||
|
depth: u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn format(
|
pub fn format(
|
||||||
@ -28,7 +29,7 @@ pub fn format(
|
|||||||
) !void {
|
) !void {
|
||||||
_ = options;
|
_ = options;
|
||||||
comptime std.debug.assert(fmt.len == 0);
|
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.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 use `opt_sema` more fully
|
error.AnalysisFail, error.NeededSourceLocation => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user