summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMitchell Hashimoto <m@mitchellh.com>2024-11-20 19:03:49 -0800
committerMitchell Hashimoto <m@mitchellh.com>2024-11-20 19:05:52 -0800
commit4ef2240618d94cbbf53d873d1dd43c8a37f3483e (patch)
tree6629189171706f3100f48eac452375fede011ed1 /src
parentd3b2f33061bf68004e70ce7b4d66f8a42a0fd0bb (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')
-rw-r--r--src/cli/args.zig26
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"),
},