E0711: Container element not trivially droppable
| Code | Category | Stability |
|---|---|---|
E0711 | Intrinsic | Permanent |
Explanation
@require_trivially_droppable(T) rejects an element type that owns resources. Duplicating such an element leaves two values cleaning up the same owned buffer, a double-free, so the gate rejects the duplication before it happens. It guards three shapes and the message says which. A by-copy read on a container that offers alternatives (ArrayBuf(T)::get, get_or) duplicates one stored element while the slot stays live; a construction (Grid2D(T)::new, or a -> type producer that gates its element type) duplicates one value into every cell of a new container; every other duplicating operation — ArrayBuf(T)::extend_from copying a run of elements from one container into another, a BinaryHeap(T) sift, a std.sort pass, or a by-copy read such as Stack(T)::peek on a container with no get_ref/pop pair — copies elements while the originals stay live and has no accessor to redirect you to.
Likely cause
For a read: a by-copy accessor such as get or get_or was called on a container whose element type has a destructor or nested drop glue. Read the element in place through get_ref, or transfer its ownership with pop or pop_or. For a construction: the container stores its cells by copy and has no by-reference form to offer, so the element type itself must be trivially droppable — hold the owning values in an ArrayBuf and store an index instead. For any other duplicating operation: there is no by-reference or move form of it to fall back to, so either use an element type without drop glue, or move the elements yourself (pop from the source, push onto the destination), which empties the source instead of copying it; where the container does have an in-place reader under another name, such as Stack(T)::peek_ref or Queue(T)::peek_ref, that reader is ungated and stays available. The diagnostic points at the earliest call, in source order, that demanded the gated body, with the gate itself labelled in the library that states it.
Examples
Copy an element in place
struct Resource { value: i32 }
drop fn Resource(self) {}
fn Cells(comptime T: type) -> type {
struct {
first: T,
second: T,
fn copy_first_into_second(inout self) {
@require_trivially_droppable(T);
self.second = self.first;
}
}
}
fn main() -> i32 {
let C = Cells(Resource);
let mut cells = C { first: Resource { value: 1 }, second: Resource { value: 2 } };
cells.copy_first_into_second();
0
}
Copy a trivially droppable element
fn Reader(comptime T: type) -> type {
struct {
value: T,
fn first(borrow self) -> T {
@require_trivially_droppable(T);
self.value
}
}
}
fn main() -> i32 {
let R = Reader(i32);
let reader = R { value: 42 };
reader.first()
}