Why Box::new requires T to be 'static


#1
pub trait Action<T: ?Sized> {
    fn run(self: Box<Self>, target: &mut T);
}

pub struct Person {
    actions: Vec<Box<Action<Person>>>,
    name: String,
}

impl Person {
    pub fn add_action<A>(&mut self, action: A)
        where A: Action<Person> + 'static // Without 'static compilation error
    {
        self.actions.push(Box::new(action));
    }
}

#2

You should update your compiler. The current stable does not have this issue.


#3

I am using nightly. Should I make an issue?


#4

This is equivalent to:

actions: Vec<Box<Action<Person> + 'static>>,

so that’s the origin of the lifetime bound.

If you want to allow borrowed data inside the trait object, you need to add a lifetime parameter to Person like this:

pub struct Person<'a> {
    actions: Vec<Box<Action<Person<'a>> + 'a>>,
    name: String,
}

impl<'a> Person<'a> {
    pub fn add_action<A>(&mut self, action: A)
        where A: 'a + Action<Person<'a>> 
    {
        self.actions.push(Box::new(action));
    }
}

#5

See add_action. I don’t borrow. I take ownership of action.


#6

action A can still contain borrowed data. You can for example take ownership of a Vec<&i32>, that doesn’t change the fact that the elements of the vector are borrowed.

In fact, a bound like A: 'static is the same as “does not contain references” (Except &'static references).


#7

I got it. Thanks.