commit 3d56df1716601440f580df3eee7e12bea44d919b (tree)
parent 994547d19acfd8ed79983b5b928052e8b01601fa
Author: Andrew Kelley <andrew@ziglang.org>
Date: Wed, 6 May 2026 19:34:52 +0200
Merge pull request 'std.fmt, std.mem.Allocator: Remove bufPrintZ()/dupeZ() in favor of bufPrintSentinel()/dupeSentinel()' (#35190) from linus/zig:deprecated-std-fmt-mem into master
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35190
Reviewed-by: Andrew Kelley <andrew@ziglang.org>
Diffstat:
22 files changed, 30 insertions(+), 41 deletions(-)
diff --git a/build.zig b/build.zig
@@ -307,7 +307,7 @@ pub fn build(b: *std.Build) !void {
},
}
};
- const version = try b.allocator.dupeZ(u8, version_slice);
+ const version = try b.allocator.dupeSentinel(u8, version_slice, 0);
exe_options.addOption([:0]const u8, "version", version);
if (enable_llvm) {
diff --git a/lib/compiler/aro/aro/CodeGen.zig b/lib/compiler/aro/aro/CodeGen.zig
@@ -894,7 +894,7 @@ fn genLval(c: *CodeGen, node_index: Node.Index) Error!Ir.Ref {
}
}
- const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice);
+ const duped_name = try c.builder.arena.allocator().dupeSentinel(u8, slice, 0);
const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len);
try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr });
return ref;
@@ -1112,7 +1112,7 @@ fn genCall(c: *CodeGen, call: Node.Call) Error!Ir.Ref {
}
}
- const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice);
+ const duped_name = try c.builder.arena.allocator().dupeSentinel(u8, slice, 0);
const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len);
try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr });
break :blk ref;
diff --git a/lib/std/Build/Watch/FsEvents.zig b/lib/std/Build/Watch/FsEvents.zig
@@ -195,7 +195,7 @@ pub fn setPaths(fse: *FsEvents, gpa: Allocator, steps: []const *std.Build.Step)
} else {
fse.watch_roots = try gpa.realloc(fse.watch_roots, need_dirs.count());
for (fse.watch_roots, need_dirs.keys()) |*out, in| {
- out.* = try paths_arena.dupeZ(u8, in);
+ out.* = try paths_arena.dupeSentinel(u8, in, 0);
}
}
if (enable_debug_logs) {
diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig
@@ -944,7 +944,7 @@ pub const RealPathFileAllocError = RealPathFileError || Allocator.Error;
pub fn realPathFileAlloc(dir: Dir, io: Io, sub_path: []const u8, allocator: Allocator) RealPathFileAllocError![:0]u8 {
var buffer: [max_path_bytes]u8 = undefined;
const n = try realPathFile(dir, io, sub_path, &buffer);
- return allocator.dupeZ(u8, buffer[0..n]);
+ return allocator.dupeSentinel(u8, buffer[0..n], 0);
}
/// Same as `realPathFile` except `absolute_path` is asserted to be an absolute
@@ -974,7 +974,7 @@ pub fn realPathFileAbsolute(io: Io, absolute_path: []const u8, out_buffer: []u8)
pub fn realPathFileAbsoluteAlloc(io: Io, absolute_path: []const u8, allocator: Allocator) RealPathFileAllocError![:0]u8 {
var buffer: [max_path_bytes]u8 = undefined;
const n = try realPathFileAbsolute(io, absolute_path, &buffer);
- return allocator.dupeZ(u8, buffer[0..n]);
+ return allocator.dupeSentinel(u8, buffer[0..n], 0);
}
pub const DeleteFileError = error{
diff --git a/lib/std/Io/Dispatch.zig b/lib/std/Io/Dispatch.zig
@@ -4086,7 +4086,7 @@ fn processReplace(userdata: ?*anyopaque, options: process.ReplaceOptions) proces
const arena = arena_allocator.allocator();
const argv_buf = try arena.allocSentinel(?[*:0]const u8, options.argv.len, null);
- for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr;
+ for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeSentinel(u8, arg, 0)).ptr;
const env_block = env_block: {
const prog_fd: i32 = -1;
@@ -4222,7 +4222,7 @@ fn spawn(ev: *Evented, options: process.SpawnOptions) process.SpawnError!Spawned
// Therefore, we do all the allocation for the execve() before the fork().
// This means we must do the null-termination of argv and env vars here.
const argv_buf = try arena.allocSentinel(?[*:0]const u8, options.argv.len, null);
- for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr;
+ for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeSentinel(u8, arg, 0)).ptr;
const env_block = env_block: {
const prog_fd: i32 = if (prog_pipe[1] == -1) -1 else prog_fileno;
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
@@ -13851,7 +13851,7 @@ fn netLookupFallible(
const name_c = name_buffer[0..name.len :0];
var port_buffer: [8]u8 = undefined;
- const port_c = std.fmt.bufPrintZ(&port_buffer, "{d}", .{options.port}) catch unreachable;
+ const port_c = std.fmt.bufPrintSentinel(&port_buffer, "{d}", .{options.port}, 0) catch unreachable;
const hints: posix.addrinfo = .{
.flags = .{ .CANONNAME = options.canonical_name_buffer != null, .NUMERICSERV = true },
@@ -14954,7 +14954,7 @@ fn processReplace(userdata: ?*anyopaque, options: process.ReplaceOptions) proces
const arena = arena_allocator.allocator();
const argv_buf = try arena.allocSentinel(?[*:0]const u8, options.argv.len, null);
- for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr;
+ for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeSentinel(u8, arg, 0)).ptr;
const env_block = env_block: {
const prog_fd: i32 = -1;
@@ -15061,7 +15061,7 @@ fn spawnPosix(t: *Threaded, options: process.SpawnOptions) process.SpawnError!Sp
// Therefore, we do all the allocation for the execve() before the fork().
// This means we must do the null-termination of argv and env vars here.
const argv_buf = try arena.allocSentinel(?[*:0]const u8, options.argv.len, null);
- for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr;
+ for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeSentinel(u8, arg, 0)).ptr;
const prog_fileno = 3;
comptime assert(@max(posix.STDIN_FILENO, posix.STDOUT_FILENO, posix.STDERR_FILENO) + 1 == prog_fileno);
diff --git a/lib/std/Io/Uring.zig b/lib/std/Io/Uring.zig
@@ -4226,7 +4226,7 @@ fn processReplace(userdata: ?*anyopaque, options: process.ReplaceOptions) proces
const arena = arena_allocator.allocator();
const argv_buf = try arena.allocSentinel(?[*:0]const u8, options.argv.len, null);
- for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr;
+ for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeSentinel(u8, arg, 0)).ptr;
const env_block = env_block: {
const prog_fd: i32 = -1;
@@ -4369,7 +4369,7 @@ fn spawn(ev: *Evented, options: process.SpawnOptions) process.SpawnError!Spawned
// Therefore, we do all the allocation for the execve() before the fork().
// This means we must do the null-termination of argv and env vars here.
const argv_buf = try arena.allocSentinel(?[*:0]const u8, options.argv.len, null);
- for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr;
+ for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeSentinel(u8, arg, 0)).ptr;
const env_block = env_block: {
const prog_fd: i32 = if (prog_pipe[1] == -1) -1 else prog_fileno;
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
@@ -520,7 +520,7 @@ pub fn defaultPanic(msg: []const u8, first_trace_addr: ?usize) noreturn {
if (uefi.system_table.boot_services) |bs| {
// ExitData buffer must be allocated using boot_services.allocatePool (spec: page 220)
- const exit_data = uefi.raw_pool_allocator.dupeZ(u16, exit_msg) catch @trap();
+ const exit_data = uefi.raw_pool_allocator.dupeSentinel(u16, exit_msg, 0) catch @trap();
bs.exit(uefi.handle, .aborted, exit_data) catch {};
}
@trap();
diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig
@@ -602,11 +602,6 @@ pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintErro
return w.buffered();
}
-/// Deprecated in favor of `bufPrintSentinel`
-pub fn bufPrintZ(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintError![:0]u8 {
- return try bufPrintSentinel(buf, fmt, args, 0);
-}
-
pub fn bufPrintSentinel(
buf: []u8,
comptime fmt: []const u8,
diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig
@@ -135,7 +135,7 @@ const TestContext = struct {
const allocator = self.arena.allocator();
const transformed_path = try self.transform_fn(allocator, self.io, self.dir, relative_path);
if (native_os == .windows) {
- const transformed_sep_path = try allocator.dupeZ(u8, transformed_path);
+ const transformed_sep_path = try allocator.dupeSentinel(u8, transformed_path, 0);
std.mem.replaceScalar(u8, transformed_sep_path, switch (self.path_sep) {
'/' => '\\',
'\\' => '/',
@@ -153,7 +153,7 @@ const TestContext = struct {
pub fn toCanonicalPathSep(self: *TestContext, path: [:0]const u8) ![:0]const u8 {
if (native_os == .windows) {
const allocator = self.arena.allocator();
- const transformed_sep_path = try allocator.dupeZ(u8, path);
+ const transformed_sep_path = try allocator.dupeSentinel(u8, path, 0);
std.mem.replaceScalar(u8, transformed_sep_path, '/', '\\');
return transformed_sep_path;
}
diff --git a/lib/std/mem.zig b/lib/std/mem.zig
@@ -4964,7 +4964,7 @@ test isAligned {
}
test "freeing empty string with null-terminated sentinel" {
- const empty_string = try testing.allocator.dupeZ(u8, "");
+ const empty_string = try testing.allocator.dupeSentinel(u8, "", 0);
testing.allocator.free(empty_string);
}
diff --git a/lib/std/mem/Allocator.zig b/lib/std/mem/Allocator.zig
@@ -456,12 +456,6 @@ pub fn dupe(allocator: Allocator, comptime T: type, m: []const T) Error![]T {
return new_buf;
}
-/// Deprecated in favor of `dupeSentinel`
-/// Copies `m` to newly allocated memory, with a null-terminated element. Caller owns the memory.
-pub fn dupeZ(allocator: Allocator, comptime T: type, m: []const T) Error![:0]T {
- return allocator.dupeSentinel(T, m, 0);
-}
-
/// Copies `m` to newly allocated memory, with a null-terminated element. Caller owns the memory.
pub fn dupeSentinel(
allocator: Allocator,
diff --git a/lib/std/os/plan9.zig b/lib/std/os/plan9.zig
@@ -299,7 +299,7 @@ pub fn openat(dirfd: i32, path: [*:0]const u8, flags: u32, _: mode_t) usize {
const dir_path = std.mem.span(@as([*:0]u8, @ptrCast(&dir_path_buf)));
const total_path = std.fs.path.join(alloc, &.{ dir_path, std.mem.span(path) }) catch unreachable; // the allocation shouldn't fail because it should not exceed max_path_bytes
fba.reset();
- const total_path_z = alloc.dupeZ(u8, total_path) catch unreachable; // should not exceed max_path_bytes + 1
+ const total_path_z = alloc.dupeSentinel(u8, total_path, 0) catch unreachable; // should not exceed max_path_bytes + 1
return open(total_path_z.ptr, flags);
}
diff --git a/lib/std/process.zig b/lib/std/process.zig
@@ -86,7 +86,7 @@ pub fn currentPathAlloc(io: Io, allocator: Allocator) CurrentPathAllocError![:0]
error.NameTooLong => unreachable,
else => |e| return e,
};
- return allocator.dupeZ(u8, buffer[0..n]);
+ return allocator.dupeSentinel(u8, buffer[0..n], 0);
}
test currentPathAlloc {
@@ -735,7 +735,7 @@ pub fn executablePathAlloc(io: Io, allocator: Allocator) ExecutablePathAllocErro
error.NameTooLong => unreachable,
else => |e| return e,
};
- return allocator.dupeZ(u8, buffer[0..n]);
+ return allocator.dupeSentinel(u8, buffer[0..n], 0);
}
pub const ExecutablePathError = ExecutablePathBaseError || error{NameTooLong};
diff --git a/lib/std/process/Environ.zig b/lib/std/process/Environ.zig
@@ -754,7 +754,7 @@ pub fn createPosixBlock(
},
.nothing => {},
};
- envp[envp_len] = try gpa.dupeZ(u8, mem.span(entry));
+ envp[envp_len] = try gpa.dupeSentinel(u8, mem.span(entry), 0);
envp_len += 1;
}
diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig
@@ -70,7 +70,7 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const
if (value.len == 0) {
@field(self, field.name) = null;
} else {
- found_keys[i].allocated = try allocator.dupeZ(u8, value);
+ found_keys[i].allocated = try allocator.dupeSentinel(u8, value, 0);
@field(self, field.name) = found_keys[i].allocated;
}
break;
diff --git a/src/Compilation.zig b/src/Compilation.zig
@@ -1869,7 +1869,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
const comp: *Compilation = comp: {
// We put the `Compilation` itself in the arena. Freeing the arena will free the module.
// It's initialized later after we prepare the initialization options.
- const root_name = try arena.dupeZ(u8, options.root_name);
+ const root_name = try arena.dupeSentinel(u8, options.root_name, 0);
// The "any" values provided by resolved config only account for
// explicitly-provided settings. We now make them additionally account
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
@@ -918,7 +918,7 @@ pub const Object = struct {
}
const target_triple_sentinel =
- try o.gpa.dupeZ(u8, o.builder.target_triple.slice(&o.builder).?);
+ try o.gpa.dupeSentinel(u8, o.builder.target_triple.slice(&o.builder).?, 0);
defer o.gpa.free(target_triple_sentinel);
const emit_asm_msg = options.asm_path orelse "(none)";
diff --git a/src/link/Lld.zig b/src/link/Lld.zig
@@ -287,7 +287,7 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void {
const comp = base.comp;
const directory = base.emit.root_dir; // Just an alias to make it shorter to type.
const full_out_path = try directory.join(arena, &[_][]const u8{base.emit.sub_path});
- const full_out_path_z = try arena.dupeZ(u8, full_out_path);
+ const full_out_path_z = try arena.dupeSentinel(u8, full_out_path, 0);
const opt_zcu = comp.zcu;
const zcu_obj_path: ?Cache.Path = if (opt_zcu != null) p: {
@@ -326,7 +326,7 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void {
object_files.appendAssumeCapacity(try key.status.success.object_path.toStringZ(arena));
}
for (comp.win32_resource_table.keys()) |key| {
- object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.res_path));
+ object_files.appendAssumeCapacity(try arena.dupeSentinel(u8, key.status.success.res_path, 0));
}
if (zcu_obj_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena));
if (compiler_rt_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena));
diff --git a/src/main.zig b/src/main.zig
@@ -5969,7 +5969,7 @@ extern "c" fn ZigLlvmAr_main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
fn argsCopyZ(alloc: Allocator, args: []const []const u8) ![:null]?[*:0]u8 {
var argv = try alloc.allocSentinel(?[*:0]u8, args.len, null);
for (args, 0..) |arg, i| {
- argv[i] = try alloc.dupeZ(u8, arg); // TODO If there was an argsAllocZ we could avoid this allocation.
+ argv[i] = try alloc.dupeSentinel(u8, arg, 0); // TODO If there was an argsAllocZ we could avoid this allocation.
}
return argv;
}
@@ -6599,7 +6599,7 @@ fn cmdDumpLlvmInts(
if (!build_options.have_llvm)
fatal("compiler does not use LLVM; cannot dump LLVM integer sizes", .{});
- const triple = try arena.dupeZ(u8, args[0]);
+ const triple = try arena.dupeSentinel(u8, args[0], 0);
const llvm = @import("codegen/llvm/bindings.zig");
diff --git a/tools/docgen.zig b/tools/docgen.zig
@@ -679,7 +679,7 @@ fn tokenizeAndPrintRaw(
raw_src: []const u8,
) !void {
const src_non_terminated = mem.trim(u8, raw_src, " \r\n");
- const src = try allocator.dupeZ(u8, src_non_terminated);
+ const src = try allocator.dupeSentinel(u8, src_non_terminated, 0);
try out.writeAll("<code>");
var tokenizer = std.zig.Tokenizer.init(src);
diff --git a/tools/doctest.zig b/tools/doctest.zig
@@ -607,7 +607,7 @@ fn printSourceBlock(arena: Allocator, out: *Writer, source_bytes: []const u8, na
fn tokenizeAndPrint(arena: Allocator, out: *Writer, raw_src: []const u8) !void {
const src_non_terminated = mem.trim(u8, raw_src, " \r\n");
- const src = try arena.dupeZ(u8, src_non_terminated);
+ const src = try arena.dupeSentinel(u8, src_non_terminated, 0);
try out.writeAll("<code>");
var tokenizer = std.zig.Tokenizer.init(src);