In this lesson, you will learn how Rust automatically converts concrete types into trait objects using the Unsize trait.
What is Unsize?
In Rust, some types have a size known only at runtime, such as slices ([T]) or trait objects (dyn Trait). These are called Dynamically Sized Types (DSTs). When you want to store a concrete type (like a struct) as a trait object (like dyn MyTrait), Rust must perform a special kind of coercion.
The Unsize trait is an internal "marker" trait that describes which types can be converted into these DSTs. Because it is a built-in compiler trait, you cannot implement it manually, but understanding it explains why your code suddenly gains the ability to use dynamic dispatch.
How Coercion Works
When you have a concrete type that implements MyTrait, the compiler automatically checks if the type can be "unsized" into dyn MyTrait. If it can, it performs a coercion. This process doesn't just change the type; it creates a "wide pointer"—a two-word pointer consisting of the data address and a pointer to the Virtual Method Table (vtable).
Consider this example:
trait Speak {
fn say(&self);
}
struct Dog;
impl Speak for Dog {
fn say(&self) { println!("Woof!"); }
}
fn make_it_speak(speaker: &dyn Speak) {
speaker.say();
}
fn main() {
let d = Dog;
// The compiler implicitly uses the Unsize trait
// to coerce &Dog into &dyn Speak.
make_it_speak(&d);
}
When you pass &d to make_it_speak, the compiler identifies that Dog satisfies the requirements to become a dyn Speak via Unsize. It transparently transforms the reference into a fat pointer, allowing the function to call say() dynamically.
This mechanism allows us to write flexible APIs that accept any type satisfying a trait without knowing the concrete size of that type at compile time. It is the invisible bridge between static memory layout and runtime polymorphism.
Key Takeaway: The Unsize trait is an internal compiler mechanism that enables the automatic coercion of concrete types into dynamically sized trait objects, allowing for flexible runtime dispatch.