Open
Description
I tried this code:
#[cfg(test)]
mod tests {
use std::sync::OnceLock;
struct MySystem {
_state: u32,
}
impl MySystem {
async fn print(&self, buff: &[u8]) {
println!("MySystem: {:?}", buff)
}
}
static SYSTEM: OnceLock<MySystem> = OnceLock::new();
#[tokio::test]
async fn test_async_closure() {
SYSTEM.get_or_init(|| MySystem { _state: 1 });
// The commented code produces the error:
// tokio::spawn(async {
// let sys: &'static OnceLock<MySystem> = &SYSTEM;
// loop {
// recv_message(async move |buff| {
// hand_message(sys, buff).await;
// })
// .await;
// }
// });
// This uncommented version is ok:
tokio::spawn(async {
loop {
recv_message(async move |buff| {
hand_message(&SYSTEM, buff).await;
})
.await;
}
});
}
async fn recv_message<T>(mut handle: T)
where
T: AsyncFnMut(&[u8]),
{
let buff = [0u8];
handle(&buff).await;
}
async fn hand_message(system: &'static OnceLock<MySystem>, buff: &[u8]) {
system.get().unwrap().print(buff).await;
}
}
I expected to see this happen:
I expect the commented code to compile without errors
Instead, this happened:
The commented code produces a compile error: implementation of Send
is not general enough.
Meta
rustc --version --verbose
:
rustc 1.85.0 (4d91de4e4 2025-02-17)
binary: rustc
commit-hash: 4d91de4e48198da2e33413efdcd9cd2cc0c46688
commit-date: 2025-02-17
host: x86_64-pc-windows-msvc
release: 1.85.0
LLVM version: 19.1.7
Tokio version: 1.42.0
Backtrace
implementation of `Send` is not general enough
`Send` would have to be implemented for the type `&'0 OnceLock<MySystem>`, for any lifetime `'0`...
...but `Send` is actually implemented for the type `&'1 OnceLock<MySystem>`, for some specific lifetime `'1`