From 4595b1ee06972df7ad913acb5349a1c5e7b07451 Mon Sep 17 00:00:00 2001 From: samy007 Date: Mon, 24 Mar 2025 22:08:05 +0100 Subject: [PATCH] std.mem.bytesAsSlice: fix to support zero-bytes sized types also added a test for json parsing of zero sized type --- lib/std/json/static_test.zig | 16 ++++++++++++++++ lib/std/mem.zig | 16 +++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/std/json/static_test.zig b/lib/std/json/static_test.zig index 3375ae0572..3a1919e40c 100644 --- a/lib/std/json/static_test.zig +++ b/lib/std/json/static_test.zig @@ -925,3 +925,19 @@ test "parse at comptime" { }; comptime testing.expectEqual(@as(u64, 9999), config.uptime) catch unreachable; } + +test "parse with zero-bit field" { + const str = + \\{ + \\ "a": ["a", "a"], + \\ "b": "a" + \\} + ; + const ZeroSizedEnum = enum { a }; + try testing.expectEqual(0, @sizeOf(ZeroSizedEnum)); + + const Inner = struct { a: []const ZeroSizedEnum, b: ZeroSizedEnum }; + const expected: Inner = .{ .a = &.{ .a, .a }, .b = .a }; + + try testAllParseFunctions(Inner, expected, str); +} diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 320c71f33d..2363fe125e 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -4219,10 +4219,11 @@ fn BytesAsSliceReturnType(comptime T: type, comptime bytesType: type) type { /// Given a slice of bytes, returns a slice of the specified type /// backed by those bytes, preserving pointer attributes. +/// If `T` is zero-bytes sized, the returned slice has a len of zero. pub fn bytesAsSlice(comptime T: type, bytes: anytype) BytesAsSliceReturnType(T, @TypeOf(bytes)) { // let's not give an undefined pointer to @ptrCast // it may be equal to zero and fail a null check - if (bytes.len == 0) { + if (bytes.len == 0 or @sizeOf(T) == 0) { return &[0]T{}; } @@ -4300,6 +4301,19 @@ test "bytesAsSlice preserves pointer attributes" { try testing.expectEqual(in.alignment, out.alignment); } +test "bytesAsSlice with zero-bit element type" { + { + const bytes = [_]u8{}; + const slice = bytesAsSlice(void, &bytes); + try testing.expectEqual(0, slice.len); + } + { + const bytes = [_]u8{ 0x01, 0x02, 0x03, 0x04 }; + const slice = bytesAsSlice(u0, &bytes); + try testing.expectEqual(0, slice.len); + } +} + fn SliceAsBytesReturnType(comptime Slice: type) type { return CopyPtrAttrs(Slice, .slice, u8); }