# Send and Sync: Data Races at Compile Time — Rust

Source: https://www.skillbyai.com/en/rust/p-send

> The type system knows what can cross threads.

## Marker traits enforced by the compiler

**Send** marks types that can be moved to another thread; **Sync** marks types that can be shared between threads by reference. The compiler implements them automatically for safe types and refuses to compile code that would send a non-thread-safe type across threads. `Rc` (a single-threaded reference count) is neither, so it must be replaced by `Arc` in threaded code. This is how Rust turns many concurrency bugs into compile errors.

## Sending an Rc to a thread, compile error

I compiled this with Rust 1.99.0 (cargo build); it is meant to fail. The output is trimmed to the error lines. Moving an Rc into a spawned thread fails with E0277: Rc<Vec<i32>> cannot be sent between threads safely, because Rc does not implement Send.

```rust
use std::rc::Rc;
use std::thread;

fn main() {
    let shared = Rc::new(vec![1, 2, 3]);   // Rc is not thread-safe
    let handle = thread::spawn(move || {
        println!("{:?}", shared);
    });
    handle.join().unwrap();
}
```

Output:

```
error[E0277]: `Rc<Vec<i32>>` cannot be sent between threads safely
 --> src/main.rs:6:32
  = help: within `{closure@src/main.rs:6:32: 6:39}`, the trait `Send` is not implemented for `Rc<Vec<i32>>`
 --> src/main.rs:6:32
error: could not compile `demo` (bin "demo") due to 1 previous error
```

## Rc for one thread, Arc for many

Use Rc when everything stays on one thread (it is cheaper) and Arc when ownership crosses threads.

**Quiz:** What does it mean when a type does not implement Send?

- [ ] It cannot be printed
- [x] It cannot be moved to another thread
- [ ] It cannot be cloned
- [ ] It cannot be stored in a Vec

*Answer:* It cannot be moved to another thread. The compiler blocks unsafe sharing.
