E0277 rust type_error ai_generated true

error[E0277]: `Cell<i32>` cannot be shared between threads safely

ID: rust/e0277-send-not-implemented-for-arc-cell

Also available as: JSON · Markdown · 中文
85%Fix Rate
88%Confidence
1Evidence
2023-01-15First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
rustc 1.68 active
rustc 1.75 active
rustc 1.82 active
rustc 1.90 active

Root Cause

Attempting to send a type containing Cell (which is !Send) across threads, typically via Arc<Cell<T>> or a struct with Cell field.

generic

中文

尝试在线程间发送包含 `Cell`(它实现了 `!Send`)的类型,通常通过 `Arc<Cell<T>>` 或带有 `Cell` 字段的结构体。

Official Documentation

https://doc.rust-lang.org/stable/error_codes/E0277.html

Workarounds

  1. 95% success Replace Cell with Mutex: `let shared = Arc::new(Mutex::new(42));` then use `shared.lock().unwrap()` to access the value. This makes the type Send because Mutex<T> is Send if T: Send.
    Replace Cell with Mutex: `let shared = Arc::new(Mutex::new(42));` then use `shared.lock().unwrap()` to access the value. This makes the type Send because Mutex<T> is Send if T: Send.
  2. 80% success Use `std::cell::RefCell` with `Mutex` outer: `Arc<Mutex<RefCell<T>>>` if interior mutability is needed but the outer type must be Send.
    Use `std::cell::RefCell` with `Mutex` outer: `Arc<Mutex<RefCell<T>>>` if interior mutability is needed but the outer type must be Send.
  3. 85% success If the value is only read, use `Arc<std::sync::RwLock<T>>` for better concurrency.
    If the value is only read, use `Arc<std::sync::RwLock<T>>` for better concurrency.

中文步骤

  1. Replace Cell with Mutex: `let shared = Arc::new(Mutex::new(42));` then use `shared.lock().unwrap()` to access the value. This makes the type Send because Mutex<T> is Send if T: Send.
  2. Use `std::cell::RefCell` with `Mutex` outer: `Arc<Mutex<RefCell<T>>>` if interior mutability is needed but the outer type must be Send.
  3. If the value is only read, use `Arc<std::sync::RwLock<T>>` for better concurrency.

Dead Ends

Common approaches that don't work:

  1. 95% fail

    Arc<T> only implements Send if T: Send, and Cell is !Send, so Arc<Cell<i32>> remains !Send.

  2. 85% fail

    Unsafe impl of Send for a type containing Cell is unsound; the compiler will still reject it unless you also disable the lint, and it may cause data races at runtime.

  3. 90% fail

    The compiler correctly rejects because the closure captures a !Send type, even with move.