From 4ef2240618d94cbbf53d873d1dd43c8a37f3483e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 20 Nov 2024 19:03:49 -0800 Subject: [PATCH] cli: parseCLI for optionals should not be null in release modes Fixes #2747 I admit I don't fully understand this. But somehow, doing `var x: ?T = undefined` in release fast mode makes `x` act as if its unset. I am guessing since undefined does nothing to the memory, the memory layout is such that it looks null for zeroed stack memory. This is a guess. To fix this, I now initialize the type `T` and set it onto the optional later. This commit also fixes an issue where calling `parseCLI` multiple times on an optional would not modify the previous value if set. --- src/cli/args.zig | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/cli/args.zig b/src/cli/args.zig index 076137dd5..3e378f347 100644 --- a/src/cli/args.zig +++ b/src/cli/args.zig @@ -256,10 +256,20 @@ pub fn parseIntoField( .Enum, => try @field(dst, field.name).parseCLI(value), - .Optional => { - @field(dst, field.name) = undefined; - try @field(dst, field.name).?.parseCLI(value); + // If the field is optional and set, then we use + // the pointer value directly into it. If its not + // set we need to create a new instance. + .Optional => if (@field(dst, field.name)) |*v| { + try v.parseCLI(value); + } else { + // Note: you cannot do @field(dst, name) = undefined + // because this causes the value to be "null" + // in ReleaseFast modes. + var tmp: Field = undefined; + try tmp.parseCLI(value); + @field(dst, field.name) = tmp; }, + else => @compileError("unexpected field type"), }, @@ -270,10 +280,14 @@ pub fn parseIntoField( .Enum, => try @field(dst, field.name).parseCLI(alloc, value), - .Optional => { - @field(dst, field.name) = undefined; - try @field(dst, field.name).?.parseCLI(alloc, value); + .Optional => if (@field(dst, field.name)) |*v| { + try v.parseCLI(alloc, value); + } else { + var tmp: Field = undefined; + try tmp.parseCLI(alloc, value); + @field(dst, field.name) = tmp; }, + else => @compileError("unexpected field type"), },