zig
zig copied to clipboard
Add note about assignment of pointer to constant array to mutable variable
The following does not do what one would expect it to do:
var slice = &[_]i32 {1, 2, 3};
for (slice) |*v| {
v.* = v.* + 3;
}
It fails with:
./constslice.zig:4:19: error: cannot assign to constant
v.* = v.* + 3;
^
It would be helpful to add a diagnostic like so, to reduce confusion about this behavior:
./constslice.zig:2:16: note: pointer to constant array assigned to mutable variable; remove '&' to assign mutable array
var slice = &[_]i32 {1, 2, 3};
^
Another example with payload capture from a different scope:
test "payload capture which requires pointer" {
const std = @import("std");
const File = std.fs.File;
const ExtraStreamIo = enum {
out,
in,
};
const ParentPipe = union(ExtraStreamIo) {
in: ?File,
out: ?File,
};
var parentPipe = ParentPipe{ .in = null };
switch (parentPipe) {
.in, .out => |*opt_file| {
if (opt_file.*) |*file| {
file.close();
opt_file = null; // error: cannot assign to constant
//opt_file.* = null; // works
}
},
}
}
We cannot, in the general case, figure out the place in the code a value came from. A more plausible approach would be to print the type of v, which should by enough of a hint. @matu3ba's example is a bit of a different problem; the error message for that one could use a hint along the lines of the capture binding is always constant, capture a reference and dereference it to mutate the value.