| ... | @@ -285,7 +285,14 @@ pub fn zeroes(comptime T: type) T { | ... | @@ -285,7 +285,14 @@ pub fn zeroes(comptime T: type) T { |
| 285 | .Pointer => |ptr_info| { | 285 | .Pointer => |ptr_info| { |
| 286 | switch (ptr_info.size) { | 286 | switch (ptr_info.size) { |
| 287 | .Slice => { | 287 | .Slice => { |
| 288 | return &[_]ptr_info.child{}; | 288 | if (ptr_info.sentinel) |sentinel| { |
| | 289 | if (ptr_info.child == u8 and @ptrCast(*const u8, sentinel).* == 0) { |
| | 290 | return ""; // A special case for the most common use-case: null-terminated strings. |
| | 291 | } |
| | 292 | @compileError("Can't set a sentinel slice to zero. This would require allocating memory."); |
| | 293 | } else { |
| | 294 | return &[_]ptr_info.child{}; |
| | 295 | } |
| 289 | }, | 296 | }, |
| 290 | .C => { | 297 | .C => { |
| 291 | return null; | 298 | return null; |
| ... | @@ -373,6 +380,7 @@ test "zeroes" { | ... | @@ -373,6 +380,7 @@ test "zeroes" { |
| 373 | optional: ?*u8, | 380 | optional: ?*u8, |
| 374 | c_pointer: [*c]u8, | 381 | c_pointer: [*c]u8, |
| 375 | slice: []u8, | 382 | slice: []u8, |
| | 383 | nullTerminatedString: [:0]const u8, |
| 376 | }, | 384 | }, |
| 377 | | 385 | |
| 378 | array: [2]u32, | 386 | array: [2]u32, |
| ... | @@ -403,6 +411,7 @@ test "zeroes" { | ... | @@ -403,6 +411,7 @@ test "zeroes" { |
| 403 | try testing.expectEqual(@as(?*u8, null), b.pointers.optional); | 411 | try testing.expectEqual(@as(?*u8, null), b.pointers.optional); |
| 404 | try testing.expectEqual(@as([*c]u8, null), b.pointers.c_pointer); | 412 | try testing.expectEqual(@as([*c]u8, null), b.pointers.c_pointer); |
| 405 | try testing.expectEqual(@as([]u8, &[_]u8{}), b.pointers.slice); | 413 | try testing.expectEqual(@as([]u8, &[_]u8{}), b.pointers.slice); |
| | 414 | try testing.expectEqual(@as([:0]const u8, ""), b.pointers.nullTerminatedString); |
| 406 | for (b.array) |e| { | 415 | for (b.array) |e| { |
| 407 | try testing.expectEqual(@as(u32, 0), e); | 416 | try testing.expectEqual(@as(u32, 0), e); |
| 408 | } | 417 | } |