Trait object can not be shared between threads safely

Change Box<dyn A> to Box<dyn A + Sync>.

For concrete types the compiler automatically handles Send and Sync bounds, but trait objects can't be checked statically. You have to manually specify which auto traits your trait object requires.

In this case you are sharing references to the trait object between threads, so you need Sync to be implemented for your trait object.

Playground

#![allow(dead_code)]
trait A {}

struct B;

impl A for B {}

struct C {
    a: Box<dyn A + Sync>,
}

impl C {
    fn f(&self) -> i32 {
        1
    }
}

fn main() {
    let b: Box<dyn A + Sync> = Box::new(B);
    let c = C { a: b };
    std::thread::scope(|scope| {
        scope.spawn(|| c.f());
        scope.spawn(|| c.f());
    })
}
7 Likes