diff options
| author | Mitchell Hashimoto <m@mitchellh.com> | 2024-11-20 19:03:49 -0800 |
|---|---|---|
| committer | Mitchell Hashimoto <m@mitchellh.com> | 2024-11-20 19:05:52 -0800 |
| commit | 4ef2240618d94cbbf53d873d1dd43c8a37f3483e (patch) | |
| tree | 6629189171706f3100f48eac452375fede011ed1 /src/cli/args.zig | |
| parent | d3b2f33061bf68004e70ce7b4d66f8a42a0fd0bb (diff) | |
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.
Diffstat (limited to 'src/cli/args.zig')
| -rw-r--r-- | src/cli/args.zig | 26 |
1 files 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"), }, |
