So, the error you're getting here is that the static itself needs synchronization, multiple threads can try to initialize the OnceCell at once because this is a static (only one initialization function gets called, the rest have to block).
consider an example like this:
use regex::Regex;
use std::cell::OnceCell;
// this can't compile because of the code below.
static INSTANCE: OnceCell<Regex> = OnceCell::new();
fn main() {
std::thread::spawn(|| {
let foo = INSTANCE.get_or_init(|| Regex::new("abc"));
// something that does something with `foo`
});
// uh-oh, this can happen at the exact same time as the above,
// which is UB if this compiles (we have a data race).
let foo = INSTANCE.get_or_init(|| Regex::new("abc"));
// again something that does something with foo.
}
lazy_static uses a lock under the hood. Specifically, when std is available (when std isn't available I think it uses a spinlock but I didn't actually check) it uses https://doc.rust-lang.org/std/sync/struct.Once.html (not to be confused with OnceCell/OnceLock), which explicitly states it locks. As in the excerpt below:
This method will block the calling thread if another initialization routine is currently running.
The short answer is, yes, you have to use OnceLock if you want this in a static, and OnceLock does roughly what lazy_static does anyway.
So, the error you're getting here is that the
static
itself needs synchronization, multiple threads can try to initialize theOnceCell
at once because this is a static (only one initialization function gets called, the rest have to block).consider an example like this:
lazy_static
uses a lock under the hood. Specifically, whenstd
is available (when std isn't available I think it uses a spinlock but I didn't actually check) it uses https://doc.rust-lang.org/std/sync/struct.Once.html (not to be confused withOnceCell
/OnceLock
), which explicitly states it locks. As in the excerpt below:The short answer is, yes, you have to use
OnceLock
if you want this in a static, andOnceLock
does roughly whatlazy_static
does anyway.