I mean that functions usually require
Sync, as the primary use is for safely sending stuff between threads – see
channel() for the two examples that come to mind. (But there are APIs that require
Sync, for example
Arc<T> won’t be
T: Sync – the same logic as in
&T: Send <=>
T: Sync applies).
Sync is kind of on the other end: it’s understandable how a type comes to be
T: !Sync means that
T employs interior mutability in a thread-unsafe way – whereas
T: Send either doesn’t use it or uses it thread-safely.
Then to bridge the gap, a value is
Send (that is, can be safely sent between threads), roughly speaking, if it doesn’t contain any references/pointers to
So to answer the question,
Thread: Sync is just saying that it’s OK to fetch data about a thread in parallel (i.e. in several other threads) via a shared reference.
In fact, all the types would be both
Sync (because ownership/borrowing/lifetimes system guarantees safety) if it weren’t for interior mutability and unsafe code. I think I might want to write an article about all of that if I manage to bring my thoughts in order and happen to have time.