What's a minimal:ish piece of code to require Sync
(in this case on MyObject
) without expressing it with an explicit bound?
Send
is easy:
let mut obj = MyObject::new();
let handle = std::thread::spawn(|| {
let id = obj.alloc();
(obj, id)
});
let (mut obj, id) = handle.join().unwrap();
obj.release(id).unwrap();
With regards to Sync
, the Nomicon phrases it sort-of like "We can safely assign this Sync
because of the guarantees the borrow-checker provides":
What about Sync? For
Carton
to be Sync we have to enforce that you can't write to something stored in a&Carton
while that same something could be read or written to from another&Carton
. Since you need an&mut Carton
to write to the pointer, and the borrow checker enforces that mutable references must be exclusive, there are no soundness issues makingCarton
sync either.
This to me makes it seem like Sync
, as opposed to Send
, doesn't unlock some feature, but is rather a way for the developer to slap a "Passed!" sticker on top of something they know fulfills the requirements of the borrow-checker.
But I'm wondering if there is something concrete that Sync
"unlocks" that is easily demonstrated, in the same spirit that Send
"unlocks" the ability demonstrated in the code snippet above.
(Purely for pedagogical reasons).