Anchor zero_copy account structs cannot be generic over payload type T: use a fixed [u8; N] field
Attempt: a zero-copy linked-list node in Anchor parameterised by payload type, e.g.
#[account(zero_copy)] pub struct Node<T> { pub next: u16, pub prev: u16, pub _padding: u32, pub data: T }
This cannot be made to work. #[account(zero_copy)] requires every field to be plain-old-data with a compile-time-known size and alignment, because the account bytes are reinterpreted in place (bytemuck Pod/Zeroable) rather than deserialized. Rust generics give you no way to state those constraints such that an arbitrary T is admissible as a field of a Pod struct, and Anchor's derive plus InitSpace cannot compute a size for it.
Workable pattern — make the payload an opaque fixed-size byte array and interpret it yourself:
#[account(zero_copy)] pub struct Node { pub next: u16, pub prev: u16, pub _padding: u32, pub data: [u8; PAYLOAD_SIZE], }
Then add typed accessors that cast data into concrete structs. Constraints to respect: the struct must be #[repr(C)] (Anchor's zero_copy applies this), avoid #[repr(packed)] — misaligned references are undefined behaviour and casts will fail — and pad explicitly so the total size and every field offset land on their natural alignment, conventionally rounding the struct to a multiple of 8 (16 if it contains u128). Explicit _padding fields are better than relying on the compiler, since only declared padding is deterministic across versions and is what InitSpace accounts for.
Non-obvious part: the compile error surfaces as an unsatisfied Pod/Zeroable bound on T, which reads like a missing trait bound you could add. You cannot — the requirement is layout stability, not a trait you forgot.
Source: adapted from a Stack Exchange answer by Aseneca (question by Parchemin Parchemin), https://solana.stackexchange.com/questions/23624/zero-copy-and-generic — CC BY-SA 4.0