From f2084ab74a8279db4a4607d97d49d27b0acda4db Mon Sep 17 00:00:00 2001 From: Alexander Mitterholzer Date: Fri, 9 Oct 2026 21:55:17 +0200 Subject: [PATCH] std.testing: refuse resizes in checkAllAllocationFailures (#37142) Fixes #37141 With resizes refused every growth goes through alloc, which is what the check counts, so the count no longer depends on the backing allocator. Reviewed-on: https://codeberg.org/ziglang/zig/pulls/37142 Reviewed-by: Andrew Kelley --- lib/std/testing.zig | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 53c52b71073a80a1360ca4d9bd39b9e2d603eb1d..fe785191d9bd4f537983bb1c764f69eb1510467f 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -1149,7 +1149,9 @@ pub fn checkAllAllocationFailures( ) !void { // Try it once with unlimited memory, make sure it works const needed_alloc_count = x: { - var failing_allocator_inst = std.testing.FailingAllocator.init(backing_allocator, .{}); + var failing_allocator_inst = std.testing.FailingAllocator.init(backing_allocator, .{ + .resize_fail_index = 0, + }); try @call(.auto, test_fn, .{failing_allocator_inst.allocator()} ++ extra_args); break :x failing_allocator_inst.alloc_index; @@ -1158,6 +1160,7 @@ pub fn checkAllAllocationFailures( for (0..needed_alloc_count) |fail_index| { var failing_allocator_inst = std.testing.FailingAllocator.init(backing_allocator, .{ .fail_index = fail_index, + .resize_fail_index = 0, }); if (@call(.auto, test_fn, .{failing_allocator_inst.allocator()} ++ extra_args)) |_| { @@ -1239,6 +1242,24 @@ test "checkAllAllocationFailures provide result type to 'extra_args' argument" { ); } +test "checkAllAllocationFailures does not depend on in-place resizes" { + // `std.testing.allocator` never reuses memory, so whether a list can grow in place depends + // on where in its bucket it landed, which differs from one run to the next. + const S = struct { + fn f(gpa: std.mem.Allocator) !void { + var a: std.ArrayList(u8) = .empty; + defer a.deinit(gpa); + var b: std.ArrayList(u8) = .empty; + defer b.deinit(gpa); + for (0..2000) |i| { + try a.append(gpa, @truncate(i)); + try b.append(gpa, @truncate(i)); + } + } + }; + try checkAllAllocationFailures(std.testing.allocator, S.f, .{}); +} + /// Given a type, references all the declarations inside, so that the semantic analyzer sees them. pub fn refAllDecls(comptime T: type) void { if (!builtin.is_test) return; -- 2.54.0