Hey, folks.
I'm a rust beginner. How could I fix this issue?
pub struct Context<'env> {
raw: &'env *mut String,
}
fn closure<F>(callback: F) -> ()
where
F: Send + Fn(Context<'_>) + 'static,
{
}
pub(crate) struct SafeContext<'e>(Context<'e>);
unsafe impl<'e> Send for SafeContext<'e> {}
unsafe impl<'e> Sync for SafeContext<'e> {}
fn main() {
let rt = tokio::runtime::Builder::new_multi_thread().build().unwrap();
let _guard = rt.enter();
closure(move |ctx: Context<'_>| {
let s_ctx = SafeContext(ctx);
rt.spawn(async {
let a = s_ctx;
});
});
}
Error
error[E0521]: borrowed data escapes outside of closure
--> src\main.rs:22:5
|
19 | closure(move |ctx: Context<'_>| {
| ---
| |
| `ctx` is a reference that is only valid in the closure body
| has type `Context<'1>`
...
22 | / rt.spawn(async {
23 | | let a = s_ctx;
24 | |
25 | | });
| | ^
| | |
| |______`ctx` escapes the closure body here
| argument requires that `'1` must outlive `'static`
A pointer is small and is suitable for copying. You can treat it as usize.
If You need that pointer to be mutable, consider
use std::sync::atomic::AtomicPtr;
pub struct Context {
raw: Arc<AtomicPtr<String>>,
}
Generally whether you need that pointer to be mutable or not, Context must be 'static. Consider using Arc and AtomicPtr to solve this problem.
The reason is Rust, even the operate system cannot be sure in two thread which one exits first without additional guarantee. So only struct whose validation must not affected by other thread can be sent through threads, that is what 'static partly means.