# Rust Send and Sync

`Send` and `Sync` are Rust's two auto-traits for thread safety. They're auto-derived (every struct gets them iff all fields have them), and they govern what the borrow checker permits across threads:

- **`T: Send`** — values of `T` can be moved to another thread. `Rc<T>` is not `Send` (refcount race); `Arc<T>` is `Send` if `T: Send + Sync`.
- **`T: Sync`** — `&T` can be shared across threads. Equivalently, `T: Sync` ⇔ `&T: Send`. `Cell<T>` is not `Sync` (interior mutation without synchronization); `Mutex<T>: Sync` only requires `T: Send`.

The non-obvious rules that make this load-bearing in practice:

| Type | `Send` requires | `Sync` requires |
|------|-----------------|-----------------|
| `&T` | `T: Sync` | `T: Sync` |
| `&mut T` | `T: Send` | `T: Sync` |
| `Box<T>` | `T: Send` | `T: Sync` |
| `Rc<T>` | never | never |
| `Arc<T>` | `T: Send + Sync` | `T: Send + Sync` |
| `Mutex<T>` | `T: Send` | `T: Send` |
| `RwLock<T>` | `T: Send` | `T: Send + Sync` |
| `Cell<T>` | `T: Send` | never |

The `&T: Send ⇔ T: Sync` rule is the one that surprises people, and it's the source of the [[rust-async-trait-sync-bound]] gotcha — capturing `&self` in a `Send` future silently demands `Self: Sync`, even when nothing in the code obviously asks for it.

Workarounds when you have a `!Sync` field but need a `Send` future:
- Wrap the field in `Mutex<T>` — `Mutex<T>: Sync` only requires `T: Send`
- Use `&mut self` instead of `&self` — `&mut T: Send` only needs `T: Send`
- Make the captured value owned (move into the future) — owned-vs-borrowed avoids the issue

For the language-design rationale (`&mut` as uniqueness, not mutation), Niko Matsakis's "Focusing on ownership" is canonical.

Cross-references: [[rust-async-trait-sync-bound]], [[message-passing-vs-shared-memory]].
