-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Make @typeInfo
return null-terminated strings
#18470
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
Changes from all commits
a02bd81
c8fa767
9245809
01b48e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17259,28 +17259,29 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | |
const vals = try sema.arena.alloc(InternPool.Index, names.len); | ||
for (vals, 0..) |*field_val, i| { | ||
// TODO: write something like getCoercedInts to avoid needing to dupe | ||
const name = try sema.arena.dupe(u8, ip.stringToSlice(names.get(ip)[i])); | ||
const name = try sema.arena.dupeZ(u8, ip.stringToSlice(names.get(ip)[i])); | ||
const name_val = v: { | ||
const new_decl_ty = try mod.arrayType(.{ | ||
.len = name.len, | ||
.sentinel = .zero_u8, | ||
.child = .u8_type, | ||
}); | ||
const new_decl_val = try mod.intern(.{ .aggregate = .{ | ||
.ty = new_decl_ty.toIntern(), | ||
.storage = .{ .bytes = name }, | ||
} }); | ||
break :v try mod.intern(.{ .ptr = .{ | ||
.ty = .slice_const_u8_type, | ||
.ty = .slice_const_u8_sentinel_0_type, | ||
.addr = .{ .anon_decl = .{ | ||
.val = new_decl_val, | ||
.orig_ty = .slice_const_u8_type, | ||
.orig_ty = .slice_const_u8_sentinel_0_type, | ||
} }, | ||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(), | ||
} }); | ||
}; | ||
|
||
const error_field_fields = .{ | ||
// name: []const u8, | ||
// name: [:0]const u8, | ||
name_val, | ||
}; | ||
field_val.* = try mod.intern(.{ .aggregate = .{ | ||
|
@@ -17387,28 +17388,29 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | |
else | ||
(try mod.intValue(Type.comptime_int, i)).toIntern(); | ||
// TODO: write something like getCoercedInts to avoid needing to dupe | ||
const name = try sema.arena.dupe(u8, ip.stringToSlice(enum_type.names.get(ip)[i])); | ||
const name = try sema.arena.dupeZ(u8, ip.stringToSlice(enum_type.names.get(ip)[i])); | ||
const name_val = v: { | ||
const new_decl_ty = try mod.arrayType(.{ | ||
.len = name.len, | ||
.sentinel = .zero_u8, | ||
.child = .u8_type, | ||
}); | ||
const new_decl_val = try mod.intern(.{ .aggregate = .{ | ||
.ty = new_decl_ty.toIntern(), | ||
.storage = .{ .bytes = name }, | ||
} }); | ||
break :v try mod.intern(.{ .ptr = .{ | ||
.ty = .slice_const_u8_type, | ||
.ty = .slice_const_u8_sentinel_0_type, | ||
.addr = .{ .anon_decl = .{ | ||
.val = new_decl_val, | ||
.orig_ty = .slice_const_u8_type, | ||
.orig_ty = .slice_const_u8_sentinel_0_type, | ||
} }, | ||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(), | ||
} }); | ||
}; | ||
|
||
const enum_field_fields = .{ | ||
// name: []const u8, | ||
// name: [:0]const u8, | ||
name_val, | ||
// value: comptime_int, | ||
value_val, | ||
|
@@ -17512,21 +17514,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | |
|
||
for (union_field_vals, 0..) |*field_val, i| { | ||
// TODO: write something like getCoercedInts to avoid needing to dupe | ||
const name = try sema.arena.dupe(u8, ip.stringToSlice(union_obj.field_names.get(ip)[i])); | ||
const name = try sema.arena.dupeZ(u8, ip.stringToSlice(union_obj.field_names.get(ip)[i])); | ||
const name_val = v: { | ||
const new_decl_ty = try mod.arrayType(.{ | ||
.len = name.len, | ||
.sentinel = .zero_u8, | ||
.child = .u8_type, | ||
}); | ||
const new_decl_val = try mod.intern(.{ .aggregate = .{ | ||
.ty = new_decl_ty.toIntern(), | ||
.storage = .{ .bytes = name }, | ||
} }); | ||
break :v try mod.intern(.{ .ptr = .{ | ||
.ty = .slice_const_u8_type, | ||
.ty = .slice_const_u8_sentinel_0_type, | ||
.addr = .{ .anon_decl = .{ | ||
.val = new_decl_val, | ||
.orig_ty = .slice_const_u8_type, | ||
.orig_ty = .slice_const_u8_sentinel_0_type, | ||
} }, | ||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(), | ||
} }); | ||
|
@@ -17539,7 +17542,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | |
|
||
const field_ty = union_obj.field_types.get(ip)[i]; | ||
const union_field_fields = .{ | ||
// name: []const u8, | ||
// name: [:0]const u8, | ||
name_val, | ||
// type: type, | ||
field_ty, | ||
|
@@ -17658,22 +17661,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | |
// TODO: write something like getCoercedInts to avoid needing to dupe | ||
const bytes = if (tuple.names.len != 0) | ||
// https://github.com/ziglang/zig/issues/15709 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this comment be removed? The issue was closed in May last year. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it can. But maybe it will be nicer if I just merge your PR for now since it's already green. |
||
try sema.arena.dupe(u8, ip.stringToSlice(ip.indexToKey(ty.toIntern()).anon_struct_type.names.get(ip)[i])) | ||
try sema.arena.dupeZ(u8, ip.stringToSlice(ip.indexToKey(ty.toIntern()).anon_struct_type.names.get(ip)[i])) | ||
else | ||
try std.fmt.allocPrint(sema.arena, "{d}", .{i}); | ||
try std.fmt.allocPrintZ(sema.arena, "{d}", .{i}); | ||
const new_decl_ty = try mod.arrayType(.{ | ||
.len = bytes.len, | ||
.sentinel = .zero_u8, | ||
.child = .u8_type, | ||
}); | ||
const new_decl_val = try mod.intern(.{ .aggregate = .{ | ||
.ty = new_decl_ty.toIntern(), | ||
.storage = .{ .bytes = bytes }, | ||
} }); | ||
break :v try mod.intern(.{ .ptr = .{ | ||
.ty = .slice_const_u8_type, | ||
.ty = .slice_const_u8_sentinel_0_type, | ||
.addr = .{ .anon_decl = .{ | ||
.val = new_decl_val, | ||
.orig_ty = .slice_const_u8_type, | ||
.orig_ty = .slice_const_u8_sentinel_0_type, | ||
} }, | ||
.len = (try mod.intValue(Type.usize, bytes.len)).toIntern(), | ||
} }); | ||
|
@@ -17685,7 +17689,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | |
const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null; | ||
const default_val_ptr = try sema.optRefValue(opt_default_val); | ||
const struct_field_fields = .{ | ||
// name: []const u8, | ||
// name: [:0]const u8, | ||
name_val, | ||
// type: type, | ||
field_ty, | ||
|
@@ -17713,7 +17717,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | |
for (struct_field_vals, 0..) |*field_val, i| { | ||
// TODO: write something like getCoercedInts to avoid needing to dupe | ||
const name = if (struct_type.fieldName(ip, i).unwrap()) |name_nts| | ||
try sema.arena.dupe(u8, ip.stringToSlice(name_nts)) | ||
try sema.arena.dupeZ(u8, ip.stringToSlice(name_nts)) | ||
else | ||
try std.fmt.allocPrintZ(sema.arena, "{d}", .{i}); | ||
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | ||
|
@@ -17722,17 +17726,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | |
const name_val = v: { | ||
const new_decl_ty = try mod.arrayType(.{ | ||
.len = name.len, | ||
.sentinel = .zero_u8, | ||
.child = .u8_type, | ||
}); | ||
const new_decl_val = try mod.intern(.{ .aggregate = .{ | ||
.ty = new_decl_ty.toIntern(), | ||
.storage = .{ .bytes = name }, | ||
} }); | ||
break :v try mod.intern(.{ .ptr = .{ | ||
.ty = .slice_const_u8_type, | ||
.ty = .slice_const_u8_sentinel_0_type, | ||
.addr = .{ .anon_decl = .{ | ||
.val = new_decl_val, | ||
.orig_ty = .slice_const_u8_type, | ||
.orig_ty = .slice_const_u8_sentinel_0_type, | ||
} }, | ||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(), | ||
} }); | ||
|
@@ -17750,7 +17755,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | |
}; | ||
|
||
const struct_field_fields = .{ | ||
// name: []const u8, | ||
// name: [:0]const u8, | ||
name_val, | ||
// type: type, | ||
field_ty.toIntern(), | ||
|
@@ -17957,27 +17962,28 @@ fn typeInfoNamespaceDecls( | |
if (decl.kind != .named or !decl.is_pub) continue; | ||
const name_val = v: { | ||
// TODO: write something like getCoercedInts to avoid needing to dupe | ||
const name = try sema.arena.dupe(u8, ip.stringToSlice(decl.name)); | ||
const name = try sema.arena.dupeZ(u8, ip.stringToSlice(decl.name)); | ||
const new_decl_ty = try mod.arrayType(.{ | ||
.len = name.len, | ||
.sentinel = .zero_u8, | ||
.child = .u8_type, | ||
}); | ||
const new_decl_val = try mod.intern(.{ .aggregate = .{ | ||
.ty = new_decl_ty.toIntern(), | ||
.storage = .{ .bytes = name }, | ||
} }); | ||
break :v try mod.intern(.{ .ptr = .{ | ||
.ty = .slice_const_u8_type, | ||
.ty = .slice_const_u8_sentinel_0_type, | ||
.addr = .{ .anon_decl = .{ | ||
.orig_ty = .slice_const_u8_type, | ||
.orig_ty = .slice_const_u8_sentinel_0_type, | ||
.val = new_decl_val, | ||
} }, | ||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(), | ||
} }); | ||
}; | ||
|
||
const fields = .{ | ||
//name: []const u8, | ||
//name: [:0]const u8, | ||
name_val, | ||
}; | ||
try decl_vals.append(try mod.intern(.{ .aggregate = .{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CI run for Linux ran into a buffer overflow panic when initializing a sentinel-terminated array for reasons seemingly unrelated to the
@typeInfo
changes.https://github.com/ziglang/zig/actions/runs/7439194713/job/20238792974
I based this fix on
zig/src/InternPool.zig
Line 5274 in 804cee3
I'm not at all familiar with compiler internals so I could be completely off base, but from skimming through code from
zirArrayInit
to here it appears to me that the problem is thataggregate.storage.elems
includes the sentinelwhich makes these two operations require an available capacity of
len_including_sentinel + 1
Judging by the related (?) fix in 5fa260b it's possible that
elems
should be sliced to exclude the sentinelbut I have no idea what the consequences of doing so would be so I decided not to touch it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the notes