My code bellow compiles and works just fine with Rust edition 2018:
fn rust_f(_: impl FnOnce() + Send + 'static) {
todo!()
}
unsafe impl Send for CFnOnce {}
#[repr(C)]
pub struct CFnOnce {
cb: extern "C" fn(*mut ::std::os::raw::c_void),
ctx: *mut ::std::os::raw::c_void,
}
fn c_f(c_cb: CFnOnce) {
let mut r_cb = move || {
(c_cb.cb)(c_cb.ctx);
};
rust_f(r_cb)
}
But with edition 2021 I got error:
error[E0277]: `*mut c_void` cannot be sent between threads safely
--> src/main.rs:21:5
|
18 | let mut r_cb = move || {
| ____________________-
19 | | (c_cb.cb)(c_cb.ctx);
20 | | };
| |_____- within this `[closure@src/main.rs:18:20: 20:6]`
21 | rust_f(r_cb)
| ^^^^^^ `*mut c_void` cannot be sent between threads safely
And I can not undernstand why I got this error and how to fix.
2021 can capture only several fields of struct
, and if I use only c_cb.ctx
inside closure,
that error message has sense, but I obviously use both fields of struct inside closure.
And for example such trick:
fn c_f(c_cb: CFnOnce) {
let mut r_cb = move || {
let _ = c_cb;//<-- TRICK
(c_cb.cb)(c_cb.ctx);
};
rust_f(r_cb)
}
changes nothing,
so any idea what is going on, is this bug of rustc ?