"Is there a meaningful difference..." <- Completely different things :P `impl Trait` can mean different things in different places, but it's *always* resolved by the compiler to some *single* actual type `T` at compiletime (like a generic). `&impl T` is just a regular thin pointer to that type that gets fully resolved at compile time. `dyn Trait` is unsized, it can *at runtime* refer to any `T` that impls `Trait`, therefore you can't store it any place that needs size computed at compiletime (since the compilier can't know the actual T it will be storing!) To create one you need to create a concrete `T` at some place in memory and "Unsize coerce" it by pointing at it with a pointer instead (`&[mut] dyn Trait`), where the pointer now has a fixed size and so you can pass around the `&dyn Trait`, which is *itself* sized. But, `&dyn Trait` it's not just a regular thin pointer, it's a fat pointer (currently implemented as basically `(*const/mut (), &TraitVTable)`