What PinCoerceUnsized does

PinCoerceUnsized is a trait exposed by the std::pin module of the Rust standard library. It is part of the public, stable API and you can rely on it from any edition of Rust.

As a trait, PinCoerceUnsized defines an interface that other types can implement. Code generic over T: PinCoerceUnsized can call any of its methods on values of any implementing type. The compiler monomorphises generic uses for zero-cost dispatch, while dyn PinCoerceUnsized opts into runtime dispatch with a vtable. The full canonical path is std::pin::PinCoerceUnsized; bring it into scope with use std::pin::PinCoerceUnsized; or refer to it by its full path.

When to use it

Implement PinCoerceUnsized on your own types to plug into the standard library's abstractions, or accept `T: PinCoerceUnsized` as a generic bound on functions that can operate uniformly across every PinCoerceUnsized-shaped type.

Annotated examples

Implementing PinCoerceUnsized for your own type

use std::pin::PinCoerceUnsized;

struct MyType;

// Implementing a std trait is a contract — the compiler enforces every
// required method and associated type. Hover the trait in your editor
// to see the full list of required and provided methods.
impl PinCoerceUnsized for MyType {
    // Required methods go here. Refer to the std::pin::PinCoerceUnsized docs
    // for the exact signatures.
}

Implementing a std trait integrates your type with every generic function and adapter that takes `T: PinCoerceUnsized`. That single impl block can unlock dozens of free helper methods.

For deeper background, see the canonical Rust patterns reference for the broader context behind this section.

Calling generic code that requires PinCoerceUnsized

use std::pin::PinCoerceUnsized;

// `T: PinCoerceUnsized` is a trait bound — only types that implement PinCoerceUnsized
// are accepted. The body can use any of PinCoerceUnsized's methods, and the
// compiler monomorphises the function for each concrete T at the
// call site, so dispatch is always direct.
fn use_with_trait<T: PinCoerceUnsized>(value: T) {
    let _ = value;
}

// Same idea with `impl Trait` for a single argument — equivalent
// when T appears only once in the signature.
fn observe(value: impl PinCoerceUnsized) {
    let _ = value;
}

Trait bounds are the language's zero-cost generics. Each call site is monomorphised, so there is no virtual-dispatch overhead — `dyn PinCoerceUnsized` is a separate, runtime-dispatch flavour you opt into explicitly when you need heterogeneous values.

Common pitfalls

Don't implement PinCoerceUnsized for types that don't naturally satisfy its contract — implementing a trait dishonestly is one of the few ways Rust will compile but produce surprising behaviour at runtime. If you need dynamic dispatch, use `Box<dyn PinCoerceUnsized>` or `&dyn PinCoerceUnsized` instead of a generic parameter.

For deeper background, see an in-depth Rust idioms cheat sheet for the broader context behind this section.

Performance & threading notes

Generic uses (`T: PinCoerceUnsized`) are monomorphised — each concrete T gets its own specialised function, with no virtual-dispatch overhead. `dyn PinCoerceUnsized` adds a single indirection through a vtable, which is fast but blocks some compiler optimisations.