Confusion about struct variance with &mut dyn

⚓ Rust    📅 2026-04-21    👤 surdeus    👁️ 2      

surdeus

Hello,

I'm a bit confused by the following Rust error: Rust Playground

trait Trait {}

struct Impl;
impl Trait for Impl {}

struct Holder<'r> {
    r: &'r mut dyn Trait,
}

fn static_holder() -> Holder<'static> {
    Holder{ r: Box::leak(Box::new(Impl)) }
}

impl<'r> Default for Holder<'r> {
    fn default() -> Holder<'r> {
        static_holder()
    }
}

I'm getting:

error: lifetime may not live long enough
  --> src/lib.rs:16:9
   |
14 | impl<'r> Default for Holder<'r> {
   |      -- lifetime `'r` defined here
15 |     fn default() -> Holder<'r> {
16 |         static_holder()
   |         ^^^^^^^^^^^^^^^ returning this value requires that `'r` must outlive `'static`
   |
   = note: requirement occurs because of the type `Holder<'_>`, which makes the generic argument `'_` invariant
   = note: the struct `Holder<'r>` is invariant over the parameter `'r`
   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
  1. Why is Holder<'r> invariant over r? The linked nomicon says &'r mut T is covariant over 'r.
  2. Why does it work when I remove the dyn Trait and instead hardcode Impl? Rust Playground
  3. Why does it work when I manually deconstruct static_holder and reconstruct a new Holder instance? Rust Playground

Thanks!
Jonathan

4 posts - 3 participants

Read full topic

🏷️ Rust_feed