zig icon indicating copy to clipboard operation
zig copied to clipboard

Add note about assignment of pointer to constant array to mutable variable

Open sin-ack opened this issue 3 years ago • 2 comments

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};
                ^

sin-ack avatar Apr 23 '22 19:04 sin-ack

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
            }
        },
    }
}

matu3ba avatar May 06 '22 09:05 matu3ba

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.

tau-dev avatar Jul 23 '24 21:07 tau-dev