This is a competing proposal with #3803. It solves the same problem in a different way, which is arguably simpler, and safer by default.
It's pretty easy to explain: make all aggregate types non-copyable by default. So this would be an error:
const Point = struct {
x: i32,
y: i32,
};
test "copy a point" {
var pt = Point{.x = 1, .y = 2};
var pt2 = pt; // error: copy of struct which does not have the `copyok` attribute
}
But this would work:
const Point2 = struct copyok {
x: i32,
y: i32,
};
test "copy a point" {
var pt = Point{.x = 1, .y = 2};
var pt2 = pt; // OK
}
Some notes:
* Enums, anonymous struct literals and anonymous list literals would be copyable
I don't think enums should be, what about something like:
const Foo = struct {
const Self = @This();
x: i32,
qux: enum {
a, b, c,
pub fn validate(thisenum: *@This()) bool {
const self = @fieldParentPtr(Self, "qux", thisenum);
return switch (thisenum) {
a => self.x < 42,
b => self.x < 100,
c => self.x >= 50,
};
}
},
};
As good as it sounds, this proposal implies explicit move- and copy-semantics for a lot of types and special care for a lot of generics:
This would not work with non-copyok types, so most of std containers would have to be implemented again with special care for non-copyable types.
And as @daurnimator said: @fieldParentPtr gives us freedom to use any type for "inheritance", so any type should be markable as non-copyable
isn't this basically the same thing as #3803 but with pinned types rather than fields? perhaps these can be unified by having a @Pin attribute that marks types as immovable.
this proposal becomes:
const Point2 = @Pin(struct {
x: i32,
y: i32,
});
and #3803 becomes:
const FixedBufferAllocator = struct {
allocator: @Pin(Allocator),
buf: []u8,
};
in cases that it doesn't make sense for the type to be movable such as function pointers @Pin would be a compiler error.
Perhaps there should be a special copy operator := for aggregate types to make the intent clear?
Most helpful comment
isn't this basically the same thing as #3803 but with pinned types rather than fields? perhaps these can be unified by having a
@Pinattribute that marks types as immovable.this proposal becomes:
and #3803 becomes:
in cases that it doesn't make sense for the type to be movable such as function pointers
@Pinwould be a compiler error.