Course contentsShow
← Rust
Lesson 513 of 1,9105. Type System and TraitsFree lesson

The Unsize Trait and Coercion

Control how types are coerced into trait objects for dynamic dispatch.

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.