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.
This commit is contained in:
Mitchell Hashimoto
2024-11-20 19:03:49 -08:00
parent d3b2f33061
commit 4ef2240618

View File

@ -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"),
},