[Question] Using std::marker::Send for dynamic traits

Hello,

I wanted to use traits, without knowing which types it represents. So I switched from using <T> (generics) to using Box<dyn trait_name>. These traits I need to send across threads, but the compiler says the dynamic traits are not marked with std::marker::Send. I have read the chapter in the nomicon that explains how to declare a trait as Send, which is simply unsafe impl Send for MyBox {}. However, it also specifies that

Note that in and of itself it is impossible to incorrectly derive Send and Sync. Only types that are ascribed special meaning by other unsafe code can possible cause trouble by being incorrectly Send or Sync.

So now I am confused whether I can just declare these traits as safe for send, or do I have to do something special? Like using mutexes and such?

You can just require the object in the box to be Send:

Box<dyn trait_name + Send>

(You might need to add + Send in a few more places in which you use the trait).

Alternatively, you can make sure that all implementations of the trait require send:

trait trait_name: Send { … }
3 Likes

Thanks! I am going to look into that. Your last remark misses a word Alternatively, you can ... that: did you mean make sure?

Yeah, I accidentally a word :slight_smile: thanks. Edited now.

1 Like

I marked this one as the solution. It doesn't answer my question, but it does solve my problem.

Is this your remaining question?

If you add Send as a constraint, whether by dyn Trait + Send or Trait: Send, you are requiring it to be so. The compiler will do the type checking to make sure that types implementing this trait actually do implement Send as well.

If you write unsafe impl Send, then you are declaring it to be so, overriding whatever the compiler already inferred about these types. The onus is completely on you to make sure it really is send-able, which is why this is unsafe to implement. Usually you would only write this if you're doing things where the compiler can't tell your intent, especially if you have other unsafe code with raw pointers.

Using mutexes is a way to get a mutable reference from shared data, sending &Mutex<T> among threads and getting a &mut T, but that T still has to implement Send in the first place.

1 Like

Yes, thank you. This answers my question and solves my problem.