Why closure complains about UnsafeCell that I access through Sync structure?

⚓ Rust    📅 2025-08-20    👤 surdeus    👁️ 5      

surdeus

Minimized code:

use std::cell::UnsafeCell;

fn run_in_threads<F>(f: F)
where
    F: Fn() -> () + Sync,
{
}

fn function2() {
    struct Buffer {
        values: Vec<UnsafeCell<i32>>,
    }
    // I am implementing synchronization externally
    unsafe impl Sync for Buffer {}

    let buffer = Buffer {
        values: (0..128usize * 1024 * 1024)
            .map(|_| UnsafeCell::new(0))
            .collect(),
    };

    // Why it says that the closure is not Sync
    // because of UnsafeCell when UnsafeCell is
    // wrapped into a Sync structure?
    run_in_threads(|| {
        let x = 0;
        unsafe {
            *buffer.values[x].get() = 0;
        }
    });
}

Error message:

error[E0277]: `UnsafeCell<i32>` cannot be shared between threads safely
   --> src/lib.rs:21:20
    |
21  |       run_in_threads(|| {
    |       -------------- ^-
    |       |              |
    |  _____|______________within this `{closure@src/lib.rs:21:20: 21:22}`
    | |     |
    | |     required by a bound introduced by this call
22  | |         let x = 0;
23  | |         unsafe {
24  | |             *buffer.values[x].get() = 0;
25  | |         }
26  | |     });
    | |_____^ `UnsafeCell<i32>` cannot be shared between threads safely

This is incorrect error because I wrapped UnsafeCell into a Sync structure so it should be irrelevant that UnsafeCell itself is not Sync.

How can I workaround this?

4 posts - 2 participants

Read full topic

🏷️ Rust_feed