2
votes

If I mark my struct as Sync will the compiler output differ? Will the compiler implement some Mutex-like magic?

struct MyStruct {
    data: RefCell<u32>,
}
unsafe impl Sync for MyStruct {}
unsafe impl Send for MyStruct {}
1
I guess you could try that yourself and see if the assembly differs? - ForceBru
"Will the compiler implement some Mutex-like magic?" No. Send and Sync are "marker traits". By implementing these types, you promise the compiler that your types fulfil the contract for those traits. You have to unsafe impl these traits because the compiler can't check you're doing it correctly. - Wesley Wiser
Thanks a lot. My understanding of Sync and Send traits got a lot better. - phip1611
Note that in cases where the compiler can check that you're doing it correctly, then you don't need to because "This trait is automatically implemented when the compiler determines it's appropriate." - Jmb

1 Answers

3
votes

The compiler uses a mechanism named "language items" to reference items (types, traits, etc.) that are defined in a library (usually core) but are used by the compiler, whether that be in code generated by the compiler, for validating the code or for producing specialized error messages.

Send and Sync are defined in the core library. Sync is a language item, but Send isn't. The only reference to Sync I could find in the compiler is where it checks that the type of a static variable implements Sync. (Send and Sync used to be more special to the compiler. Before auto traits were added to the language, they were implemented as "auto traits" explicitly.)

Other than that, the compiler doesn't care about what Send and Sync mean. It's the libraries (specifically, types/functions that are generic over Send/Sync types) that give the traits their meaning.

Neither trait influences what code is emitted by the compiler regarding a particular type. Making a type "thread-safe" is not something that can be done automatically. Consider a struct with many fields: even if the fields are all atomic types, a partially updated struct might not be in a valid state. The compiler doesn't know about the invariants of a particular type; only the programmer knows them. Therefore, it's the programmer's responsibility to make the type thread-safe.