# Send and Sync

> Two auto traits that tell the compiler which types may move to or be shared with other threads — the reason safe Rust has no data races.

Concept · Rust · https://levelcode.org/concepts/send-and-sync

`Send` and `Sync` are **marker traits**: they have no methods, and the compiler implements them automatically for a type when all of its fields have them.

- **`Send`** — a value of the type can be **moved** to another thread.
- **`Sync`** — a value can be **shared** between threads by reference. Formally, `T` is `Sync` when `&T` is `Send`.

Almost everything is both. The exceptions are types whose internal mutation isn't synchronized:

| Type | Send | Sync | Why |
| --- | --- | --- | --- |
| `Rc<T>` | No | No | Its reference count is a plain integer; two threads updating it would race |
| `Cell<T>`, `RefCell<T>` | Yes (if `T` is) | No | Mutation through `&T` without synchronization |
| `Arc<T>` | Yes (if `T: Send + Sync`) | Yes (same) | Atomic reference count |
| `Mutex<T>` | Yes (if `T: Send`) | Yes (if `T: Send`) | Serializes access |
| Raw pointers | No | No | The compiler can't reason about them |

## Where they're checked

`std::thread::spawn` and `tokio::spawn` require the closure or future — and everything it captures or holds across an `.await` — to be `Send`:

```text
error[E0277]: `Rc<Vec<i32>>` cannot be sent between threads safely
```

Swap `Rc` for `Arc`, and `RefCell` for `Mutex`, and it compiles.

## Why this ends data races

A [data race](https://levelcode.org/concepts/data-races) needs shared memory plus unsynchronized writes. [The borrow checker](https://levelcode.org/concepts/borrow-checker) forbids unsynchronized writes through ordinary references; `Send` and `Sync` forbid sharing types that mutate internally without synchronization. Together they make data races a compile error in safe Rust. They don't prevent deadlocks or logic races, which you still design against.

Implementing them by hand (`unsafe impl Send for T {}`) is an unsafe promise, needed only for types built on raw pointers. See the [concurrency lesson](https://levelcode.org/roadmaps/rust/concurrency).
