Skip to content

Ability to mark a struct field as "pinned" in memory #3803

Closed
@andrewrk

Description

@andrewrk

This is @dbandstra's comment extracted into a separate issue.

I propose to use the keyword pinmem since it is 2 words smashed together lowercase, and therefore unlikely to alias anything useful.

Example code:

const std = @import("std");
const Allocator = std.mem.Allocator;

const FixedBufferAllocator = struct {
    pinmem allocator: Allocator,
    buf: []u8,
};
test "allocator pattern" {
    var bytes: [10]u8 = undefined;
    var fba = FixedBufferAllocator{
        .allocator = Allocator{
            .reallocFn = undefined, // not needed for this example
            .shrinkFn = undefined, // not needed for this example
        },
        .buf = &bytes,
    };
    const allocator = fba.allocator; // error: copy of memory-pinned field `allocator`
    const allocator = &fba.allocator; // OK
}

This would provide compile-time error protections to prevent against #591.

@fieldParentPtr would give a compile error if the field used did not have the pinmem attribute.

This would become significantly more useful with #2761 and #2765 implemented.

Another example (see related issue #172):

const S = struct {
    pinmem a: i32,
    b: *i32,
};
test "pinned field" {
    var s = S{
        .a = 1,
        .b = undefined,
    };
    s.b = &s.a;
    var s2 = s; // error: copy of memory-pinned field `a`
    var x = s.a; // error: copy of memory-pinned field `a`
    var x = (&.sa).*; // OK
}

This makes the language bigger and more complicated. One of Zig's goals is to be a small, simple language. So what justifies the change? It prevents footguns.

Accepted proposal #2414 moves the footgun of #591 to be caught by runtime safety. However this proposal further eradicates this possible mistake, by making it a compile error. From the Zen:

Runtime crashes are better than bugs.
Compile errors are better than runtime crashes.

Additional use cases:

prealloc_segment: [prealloc_item_count]T,

/// TODO copy elision / named return values so that the threads referencing *Loop
/// have the correct pointer value.
/// https://github.com/ziglang/zig/issues/2761 and https://github.com/ziglang/zig/issues/2765
pub fn init(self: *Loop) !void {

Metadata

Metadata

Assignees

No one assigned

    Labels

    proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions