authorgravatar for 37453713+ominitay@users.noreply.github.comominitay <37453713+ominitay@users.noreply.github.com> 2022-03-28 12:10:36+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-28 14:10:36+03:00
log25d4c5df706bb8ca6e7882f80d6f8209b9ad31f8
tree102a1619668a9734115f8dd74c17adc70c8c6d46
parent460e7a24451c9bf37a8c1e5e6a4554173416b149
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

std.mem.zeroInit: Fix behaviour with empty initialiser


1 files changed, 36 insertions(+), 14 deletions(-)

lib/std/mem.zig+36-14
......@@ -432,6 +432,13 @@ pub fn zeroInit(comptime T: type, init: anytype) T {
432432 .Struct => |init_info| {
433433 var value = std.mem.zeroes(T);
434434
435 inline for (struct_info.fields) |field| {
436 if (field.default_value) |default_value_ptr| {
437 const default_value = @ptrCast(*const field.field_type, default_value_ptr).*;
438 @field(value, field.name) = default_value;
439 }
440 }
441
435442 if (init_info.is_tuple) {
436443 inline for (init_info.fields) |field, i| {
437444 @field(value, struct_info.fields[i].name) = @field(init, field.name);
......@@ -443,21 +450,14 @@ pub fn zeroInit(comptime T: type, init: anytype) T {
443450 if (!@hasField(T, field.name)) {
444451 @compileError("Encountered an initializer for `" ++ field.name ++ "`, but it is not a field of " ++ @typeName(T));
445452 }
446 }
447453
448 inline for (struct_info.fields) |field| {
449 if (@hasField(Init, field.name)) {
450 switch (@typeInfo(field.field_type)) {
451 .Struct => {
452 @field(value, field.name) = zeroInit(field.field_type, @field(init, field.name));
453 },
454 else => {
455 @field(value, field.name) = @field(init, field.name);
456 },
457 }
458 } else if (field.default_value) |default_value_ptr| {
459 const default_value = @ptrCast(*const field.field_type, default_value_ptr).*;
460 @field(value, field.name) = default_value;
454 switch (@typeInfo(field.field_type)) {
455 .Struct => {
456 @field(value, field.name) = zeroInit(field.field_type, @field(init, field.name));
457 },
458 else => {
459 @field(value, field.name) = @field(init, field.name);
460 },
461461 }
462462 }
463463
......@@ -515,6 +515,28 @@ test "zeroInit" {
515515 .b = 0,
516516 .a = 0,
517517 }, c);
518
519 const Foo = struct {
520 foo: u8 = 69,
521 bar: u8,
522 };
523
524 const f = zeroInit(Foo, .{});
525 try testing.expectEqual(Foo{
526 .foo = 69,
527 .bar = 0,
528 }, f);
529
530 const Bar = struct {
531 foo: u32 = 666,
532 bar: u32 = 420,
533 };
534
535 const b = zeroInit(Bar, .{69});
536 try testing.expectEqual(Bar{
537 .foo = 69,
538 .bar = 420,
539 }, b);
518540}
519541
520542/// Compares two slices of numbers lexicographically. O(n).