commit 25d4c5df706bb8ca6e7882f80d6f8209b9ad31f8 (tree)
parent 460e7a24451c9bf37a8c1e5e6a4554173416b149
Author: ominitay <37453713+ominitay@users.noreply.github.com>
Date: Mon, 28 Mar 2022 12:10:36 +0100
std.mem.zeroInit: Fix behaviour with empty initialiser
Diffstat:
1 file changed, 36 insertions(+), 14 deletions(-)
diff --git a/lib/std/mem.zig b/lib/std/mem.zig
@@ -432,6 +432,13 @@ pub fn zeroInit(comptime T: type, init: anytype) T {
.Struct => |init_info| {
var value = std.mem.zeroes(T);
+ inline for (struct_info.fields) |field| {
+ if (field.default_value) |default_value_ptr| {
+ const default_value = @ptrCast(*const field.field_type, default_value_ptr).*;
+ @field(value, field.name) = default_value;
+ }
+ }
+
if (init_info.is_tuple) {
inline for (init_info.fields) |field, i| {
@field(value, struct_info.fields[i].name) = @field(init, field.name);
@@ -443,21 +450,14 @@ pub fn zeroInit(comptime T: type, init: anytype) T {
if (!@hasField(T, field.name)) {
@compileError("Encountered an initializer for `" ++ field.name ++ "`, but it is not a field of " ++ @typeName(T));
}
- }
- inline for (struct_info.fields) |field| {
- if (@hasField(Init, field.name)) {
- switch (@typeInfo(field.field_type)) {
- .Struct => {
- @field(value, field.name) = zeroInit(field.field_type, @field(init, field.name));
- },
- else => {
- @field(value, field.name) = @field(init, field.name);
- },
- }
- } else if (field.default_value) |default_value_ptr| {
- const default_value = @ptrCast(*const field.field_type, default_value_ptr).*;
- @field(value, field.name) = default_value;
+ switch (@typeInfo(field.field_type)) {
+ .Struct => {
+ @field(value, field.name) = zeroInit(field.field_type, @field(init, field.name));
+ },
+ else => {
+ @field(value, field.name) = @field(init, field.name);
+ },
}
}
@@ -515,6 +515,28 @@ test "zeroInit" {
.b = 0,
.a = 0,
}, c);
+
+ const Foo = struct {
+ foo: u8 = 69,
+ bar: u8,
+ };
+
+ const f = zeroInit(Foo, .{});
+ try testing.expectEqual(Foo{
+ .foo = 69,
+ .bar = 0,
+ }, f);
+
+ const Bar = struct {
+ foo: u32 = 666,
+ bar: u32 = 420,
+ };
+
+ const b = zeroInit(Bar, .{69});
+ try testing.expectEqual(Bar{
+ .foo = 69,
+ .bar = 420,
+ }, b);
}
/// Compares two slices of numbers lexicographically. O(n).