I'm trying to create a ScopeRunner type that can store method calls to a method of types implementing the Scope trait like this:
trait Scope {
    fn run(&self) -> String;
}
struct ScopeImpl;
impl Scope for ScopeImpl {
    fn run(&self) -> String {
        "Some string".to_string()
    }
}
struct ScopeRunner {
    runner: Box<dyn Fn() -> String>,
}
impl ScopeRunner {
    fn new<S: Scope>(scope: S) -> Self {
        ScopeRunner {
            runner: Box::new(move || scope.run())
        }
    }
    pub fn run(self) -> String {
        (self.runner)()
    }
}
fn main() {
    let scope = ScopeImpl {};
    let scope_runner = ScopeRunner::new(scope);
    dbg!(scope_runner.run());
}
I would expect that since ScopeRunner::new creates a move closure this would cause scope to be moved into the closure. But instead the borrow checker gives me this error:
error[E0310]: the parameter type `S` may not live long enough
  --> src/main.rs:21:30
   |
20 |     fn new<S: Scope>(scope: S) -> Self {
   |            -- help: consider adding an explicit lifetime bound `S: 'static`...
21 |         ScopeRunner {runner: Box::new(move || scope.run())}
   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: ...so that the type `[closure@src/main.rs:21:39: 21:58 scope:S]` will meet its required lifetime bounds
  --> src/main.rs:21:30
   |
21 |         ScopeRunner {runner: Box::new(move || scope.run())}
   | 
When I replace ScopeRunner::new with a non generic version that just takes a ScopeImpl this code does work.
fn new(scope: ScopeImpl) -> Self {
    ScopeRunner {
        runner: Box::new(move || scope.run())
    }
}
I don't understand why this is different. To me it seems the lifetime of the generic Scope would be the same as the concrete version.
 
    