-
Notifications
You must be signed in to change notification settings - Fork 125
Description
While normally only used within the lazy_static
macro, the type and its fields need to be public, at least for the old macro_rules
macros. This poses both a safety (the fields are used in unsafe ways) and stability hazard (changing implementation details is technically breaking).
Because Lazy::get
takes &'static mut self
, it's hard to abuse (static mut
itself is unsafe, so it doesn't really count here), but Box::leak
does let you create a &'static mut
at runtime, so you could, in theory, leak a Lazy<T>
, trigger the call_once
manually, then call Lazy::get
, which will return an invalid reference to a T
(since no actual initialization occurred).
To construct a Lazy<T>
to initialize the static in the macro, you can use associated consts (since 1.20):
impl<T> Lazy<T> {
const INIT: Self = Lazy(None, ONCE_INIT);
}
This way, the fields can be made private (we should try a crater run if possible - cc @kennytm @Mark-Simulacrum - just to make sure nobody was using the Lazy
type themselves).