In this lesson, you will learn how the Rust compiler determines memory layout for generic structs and how your type choices impact alignment.
How Rust Packs Generic Memory
When you define a struct with a generic parameter, like struct Container<T> { data: T }, Rust does not know the final size or alignment of T until you actually instantiate it. Because of monomorphization, the compiler creates a specific version of Container<T> for every concrete type you use.
The compiler follows a simple rule: a struct's alignment is determined by its most strictly aligned field. When that field is a generic type T, the alignment of your struct depends entirely on what T is.
The Alignment Challenge
Consider this example:
struct Wrapper<T> {
flag: u8,
value: T,
}
If you use Wrapper<u8>, the size is 2 bytes (1 byte for flag, 1 byte for u8, no padding needed). However, if you use Wrapper<u64>, the compiler must insert 7 bytes of padding after flag to ensure the u64 starts on an 8-byte boundary.
This means the memory layout of Wrapper<T> is dynamic. While this is efficient—it prevents the "bloat" of forcing every instance to align to the size of the largest possible type—it creates a pitfall: you cannot predict the exact memory offset of your fields if you don't know the concrete type of T.
Why Does This Matter?
If you are building low-level systems or working with FFI (Foreign Function Interface), assuming a fixed layout for generic structs will lead to bugs. Rust does not guarantee a specific field order or padding for standard structs unless you explicitly use the #[repr(C)] attribute. Even with #[repr(C)], the alignment of your struct remains dependent on the alignment of the generic type T. If you swap T for a type with a higher alignment requirement, your entire struct will automatically increase its padding to accommodate it.
Key Takeaway: Because Rust monomorphizes generics, the alignment and size of a generic struct are determined at compile-time based on the concrete type, meaning your struct’s memory footprint shifts to match the requirements of the type parameter provided.