25.6 Implementing Unsafe Traits
A trait can be declared as unsafe trait
if implementing it requires the type to uphold specific invariants or properties that the Rust compiler cannot statically verify. These invariants often relate to low-level details like memory layout, thread safety guarantees, or interaction patterns with unsafe code.
// Hypothetical example: A trait indicating a type can be safely zero-initialized.
// (The standard library has `MaybeUninit<T>` for related concepts).
unsafe trait Pod (Plain Old Data) {
// Implementing this trait asserts that a byte pattern of all zeros
// represents a valid instance of the type.
// Incorrectly implementing this could lead to UB if zero-initialization
// is used based on this trait implementation.
}
struct MyStruct {
a: u32,
b: bool,
}
// The `unsafe impl` signifies that the programmer guarantees MyStruct
// conforms to the Pod contract.
unsafe impl Pod for MyStruct {
// No methods required; the guarantee is encoded in the implementation itself.
}
Implementing an unsafe trait
is an unsafe operation (requires unsafe impl
). This is because other code (potentially safe code) might rely on the invariants promised by the trait implementation. A faulty implementation could violate these assumptions, leading to undefined behavior throughout the program.
The standard library’s marker traits Send
and Sync
are related. While they are automatically implemented by the compiler for many types, implementing them manually (which is sometimes necessary, e.g., for types containing raw pointers) requires unsafe impl
because the programmer must guarantee thread safety properties that the compiler cannot infer.