I would like to initialize an error/string union (std.mem.Allocator.Error![]const u8
) and then assign the return value of a function to this union.
But the following code fail with zig test mytest.zig
:
const std = @import("std");
test "my test" {
const phrase = "test";
std.debug.print("input: {s}\n",.{phrase});
var o:std.mem.Allocator.Error![]const u8 = "";
std.debug.print("typeof(o): {}\n",.{@TypeOf(o)});
o = try isoReturn(std.testing.allocator,phrase);
defer std.testing.allocator.free(o);
}
pub fn isoReturn(allocator: std.mem.Allocator, phrase: []const u8) std.mem.Allocator.Error![]const u8 {
var o = try allocator.alloc(u8, phrase.len);
for (phrase, 0..) |c,i| {
o[i] = c;
}
return o;
}
With this error message:
$ zig test test.zig
/Users/[..]/lib/std/mem/Allocator.zig:308:45: error: access of union field 'pointer' while field 'error_union' is active
const Slice = @typeInfo(@TypeOf(memory)).pointer;
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
/Users/[..]/lib/std/builtin.zig:556:18: note: union declared here
pub const Type = union(enum) {
^~~~~
But if I declare the union directly with the function call (like: const o = try isoReturn(testing.allocator,phrase);
) I get no error and everything seems to works fine:
Code with union declaration directly with function call
const std = @import("std");
test "my test" {
const phrase = "text";
std.debug.print("input: {s}\n",.{phrase});
const o = try isoReturn(std.testing.allocator,phrase);
defer std.testing.allocator.free(o);
std.debug.print("output: {s}\n",.{o});
}
pub fn isoReturn(allocator: std.mem.Allocator, phrase: []const u8) std.mem.Allocator.Error![]const u8 {
var o = try allocator.alloc(u8, phrase.len);
for (phrase, 0..) |c,i| {
o[i] = c;
}
return o;
}
Questions
Why my first code fail? If it is because of the union initialization, how to properly make the initialization in this case?
$ zig version
0.14.0-dev.2370+5c6b25d9b