Phantom types in Rust are zero-sized types used to carry type information at compile time without affecting runtime memory layout. You define a newtype wrapper around PhantomData<T> to encode state or constraints that the compiler enforces, preventing invalid operations like using an uninitialized value. This technique is used internally by the compiler, such as in TypedArena<T> to ensure the arena drops its owned instances of T correctly.
use std::marker::PhantomData;
struct Uninitialized<T> {
_marker: PhantomData<T>,
}
struct Initialized<T> {
value: T,
_marker: PhantomData<T>,
}
// The compiler prevents passing Uninitialized where Initialized is expected
fn process<T>(item: Initialized<T>) {
// Logic here
}