Ownership to a reference of a Trait

This code should work!

#[derive(Debug)]
struct Val2<'a>(&'a str);

#[derive(Debug)]
struct Val3<'a>(Box<dyn Debug>, PhantomData<&'a bool>);

impl<'a> Val3<'a> {
  fn new(a: &'a str) -> Self {
    let b = Val2(a);
    Self(Box::new(b), PhantomData)
  }
}

The 'b' value should have the same lifetime of 'a', which is the same as 'Val3'. Why is this not accepted by the compiler?

Why do you think they should have the same lifetime? What guarantees that the owner of the str you receive (which could come from anywhere) is going to be the same scope that takes ownership of the Box that you're returning?

All trait objects have lifetimes associated with them. dyn Debug is actually shorthand for dyn Debug + 'static.[1] The simple solution:

#[derive(Debug)]
struct Val3<'a>(Box<dyn Debug + 'a>, PhantomData<&'a bool>);


  1. This is a slight oversimplification. When you have a fn that takes a &'a dyn Debug, then it actually desugars to &'a (dyn Debug + 'a). This is a rather specific exception, and in most cases the omitted lifetime is inferred to 'static. ↩ī¸Ž

2 Likes

For more explanation of why Box<dyn Debug> is short for Box<dyn Debug + 'static>, see Default trait object lifetimes.

1 Like

That works, and I can remove the PhantomData.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.