[Solved] Strange error with crossbeam scoped threads

Hi everyone,

I've rewritten my code from using normal threads to crossbeam scoped threads and now I have this problem:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4945333cef1f88a94781b085f0206a4c

use crossbeam::{self, thread::Scope};

trait Animal {
    fn sleep(&mut self);
}

struct Cat {
    name: String,
    sleeping: bool,
}

impl Animal for Cat {
    fn sleep(&mut self) {
        self.sleeping = true
    }
}

fn test<A: Animal + Send>(animal: A) {
    crossbeam::scope(|scope| {
        play_with(scope, animal);
    }).unwrap()
}

fn play_with<T: Animal + Send>(scope: &Scope, animal: T) {
    scope.spawn(move |_| {
        animal.sleep();
    });
}

fn main() {
    let cat = Cat { name: "Lucky".to_string(), sleeping: false };
    test(cat)
}

The error message (the help part) looks like a bug in the rust compiler to me:

25 |     scope.spawn(move |_| {
   |           ^^^^^
help: consider introducing an explicit lifetime bound
   |
24 | fn play_with<'a, T: 'a + Animal + Send>(scope: &Scope, animal: T) {
25 |     scope.spawn + 'a(move |_| {
   |

Any ideas how I can resolve this problem and use scoped threads in my code ? Thanks!

You can fix compile error by changing this line.

- fn play_with<T: Animal + Send>(scope: &Scope, animal: T) {
+ fn play_with<'a, T: Animal + Send + 'a>(scope: &Scope<'a>, mut animal: T) {

playground

The point is that Scope::spawn requires closures and their return values to live longer than 'env. (Closure's lifetimes depend on the captured variables, so they also need to live longer than 'env.)

impl<'env> Scope<'env>
    pub fn spawn<F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T>
    where
        F: FnOnce(&Scope<'env>) -> T + Send + 'env,
        T: Send + 'env, 

Perfect, thanks a lot!
Could have thought about this myself but the error message somehow confused me :wink: