if (try entry.fields.fetchPut(config.field_name, new_value)) |old| {
old.value.deinit(allocator);
}
and I get this error:
src/cli/main.zig:876:22: error: expected type '*value.Value', found '*const value.Value'
old.value.deinit(allocator);
~~~~~~~~~^~~~~~~
src/cli/main.zig:876:22: note: cast discards const qualifier
src/core/value.zig:64:25: note: parameter type declared here
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
But the return type of fetchPut is !?KV, and my hash map owns Value: std.StringHashMap(Value) so old should be of type KV and the value field of that is of type Value not *const Value right? Is it the if () || syntax, is old like a const variable, I even tried doing |*old| but that didn’t work either.
the problem is that method call syntax that you use in the deinit call can coerce const thing: T to *const T and var thing: T to *T. you should attempt capturing by pointer |*old| so that old is of type *T. if that doesn’t work, you would need to assign var copy = old and call copy.deinit(). That sounds to me like a code smell, but I don’t know what the structure of your Value; if it needs a deinit because it owns some pointers inside, then this is fine.
The issue is, that the return value of a function is a constant, and capturing a pointer to it will still get you a pointer to constant memory.
I think fetchPut returning ?!*KV instead of ?!KV should solve it.
And I think, zig likely saved you from a bug there
Edit: thinking about it again, it is probably necessary to assign the return value to a variable instead of returning a pointer, because at that address the new value is when the function returns
var optional = try entry.fields.fetchPut(config.field_name, new_value);
if (optional) |*old| {
old.value.deinit(allocator);
}
This looks like the part of you code that works, if function return types are constant, we have it assigned to the var optional anyways, the only difference I see is that we are accessing field of old where your function calls the deinit function directly on f
if (try entry.fields.fetchPut(config.field_name, new_value)) |kv| {
// Assign because `old_value` is const
var old_value = kv.value;
old_value.deinit(allocator);
}