In Rust, when boxing a value passed as a generic argument, why is a `’static` lifetime bound required?

I'm trying to write a constructor function which takes a generic value implementing some trait by argument, and then boxes it (the point is to then initialize something with these boxes, but the following example is simplified):

struct Struct {}

trait Trait {}

impl Trait for Struct {}

fn f(arg: impl Trait) -> Box<dyn Trait> {

fn main() {
    let x = Struct {};

Here, the compiler whines that arg might not live long enough. This makes perfect sense to me, because the only requirement on arg is impl Trait, meaning it might in fact be a reference which implement the trait, in which case it cannot be boxed safely.

What confuses me is the following solution, adding a 'static bound:

fn f(arg: impl Trait + 'static) -> Box<dyn Trait> {

Now, of course it works, but in principle we are now constrained to passing in values with a 'static lifetime. Yet, the compiler lets me pass in x without a problem.

Here are my questions, more specifically:

  1. Doesn't x have a lifetime, residing on the stack? Why is it possible to pass it to f when arg has a 'static lifetime bound? Do these bounds only concern the lifetime of references?
  2. Is this solution valid in general, or will I face cases where the compiler will refuse my stack-allocated arguments?
  3. Is there a nicer way of saying "any type that impls Trait where the type is not a reference?

Note that 1) is mostly answered by Why does Rust require a `'static` lifetime for this variable? but I am left confused as to if this is the idiomatic way of boxing arguments.

Read more here:

Content Attribution

This content was originally published by yawn at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: