# The Sync Bound Nobody Asked For

verrchu's first blog post tracks a Rust async trait error that looks like a `Send` problem but is really a `Sync` problem in disguise. The four-cell truth table is the framing:

|  | impl `Send + Sync` | impl `Send + !Sync` |
|---|---|---|
| future *without* `+ Send` bound | compiles | compiles |
| future *with* `+ Send` bound    | compiles | **fails** |

The failing case (case 2.2) only fails because of two subtle Rust rules:
- `tokio::spawn` requires `F: Send + 'static`, so the returned future has to be `Send`
- `&T: Send` requires `T: Sync` (whereas `&mut T: Send` only requires `T: Send`)

So when the trait is `fn run(&self) -> impl Future<Output = ()> + Send`, the `&self` capture inside the future implies the future captures a `&Self` reference. For that capture to be `Send`, `Self` has to be `Sync`. The `Sync` requirement was hiding inside `&self` the whole time — a foreign `!Sync` field (`Cell<()>`) just makes it visible.

Two fixes:
1. **Wrap the `!Sync` field in a `Mutex`** — works because `Mutex<T>: Sync` only requires `T: Send`, but adds runtime locking overhead even though `Self` is never actually shared between threads
2. **Switch `&self` to `&mut self`** — `&mut T: Send` only requires `T: Send`, so the `Sync` demand disappears entirely

The second fix is counter-intuitive. The instinct in Rust is to reach for `&` because it's "tighter" (no mutation). Here it's looser in the trait-bound sense. The real meaning of `&mut T` is *unique reference*, not *mutable reference* — uniqueness is what rules out cross-thread sharing, which is what removes the `Sync` requirement. (Niko Matsakis's "Focusing on ownership" is the canonical write-up of `&mut` as uniqueness.)

The post is short, well-illustrated with full compile errors, and a good entry point for the broader topic of how `Send`/`Sync` cascade through async-trait return types. Practical takeaway: when an async trait method must return a `Send` future, default to `&mut self` unless you specifically need shared access.

Cross-references: [[rust-send-sync]], [[verrchu-blog]], [[message-passing-vs-shared-memory]].
