Skip to content

Commit a15ddc1

Browse files
committed
Made macro not use a heap allocation on nightly
1 parent 7dab6d4 commit a15ddc1

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

src/lib.rs

+36-8
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ define uninitialized `static mut` values.
7171
7272
*/
7373

74+
#![cfg_attr(feature="nightly", feature(const_fn))]
7475
#![crate_type = "dylib"]
7576

7677
#[macro_export]
@@ -87,21 +88,48 @@ macro_rules! lazy_static {
8788
type Target = $T;
8889
fn deref<'a>(&'a self) -> &'a $T {
8990
#[inline(always)]
90-
fn __static_ref_initialize() -> Box<$T> { Box::new($e) }
91+
fn __static_ref_initialize() -> $T { $e }
9192

9293
unsafe {
9394
use std::sync::{Once, ONCE_INIT};
94-
use std::mem::transmute;
9595

9696
#[inline(always)]
9797
fn require_sync<T: Sync>(_: &T) { }
9898

99-
static mut DATA: *const $T = 0 as *const $T;
100-
static mut ONCE: Once = ONCE_INIT;
101-
ONCE.call_once(|| {
102-
DATA = transmute::<Box<$T>, *const $T>(__static_ref_initialize());
103-
});
104-
let static_ref = &*DATA;
99+
#[inline(always)]
100+
#[cfg(feature="nightly")]
101+
unsafe fn __stability() -> &'static $T {
102+
use std::cell::UnsafeCell;
103+
104+
struct SyncCell(UnsafeCell<Option<$T>>);
105+
unsafe impl Sync for SyncCell {}
106+
107+
static DATA: SyncCell = SyncCell(UnsafeCell::new(None));
108+
static ONCE: Once = ONCE_INIT;
109+
ONCE.call_once(|| {
110+
*DATA.0.get() = Some(__static_ref_initialize());
111+
});
112+
match *DATA.0.get() {
113+
Some(ref x) => x,
114+
None => loop { /* unreachable */ },
115+
}
116+
}
117+
118+
#[inline(always)]
119+
#[cfg(not(feature="nightly"))]
120+
unsafe fn __stability() -> &'static $T {
121+
use std::mem::transmute;
122+
123+
static mut DATA: *const $T = 0 as *const $T;
124+
static mut ONCE: Once = ONCE_INIT;
125+
ONCE.call_once(|| {
126+
DATA = transmute::<Box<$T>, *const $T>(
127+
Box::new(__static_ref_initialize()));
128+
});
129+
&*DATA
130+
}
131+
132+
let static_ref = __stability();
105133
require_sync(static_ref);
106134
static_ref
107135
}

tests/test.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![cfg_attr(feature="nightly", feature(const_fn))]
2+
13
#[macro_use]
24
extern crate lazy_static;
35
use std::collections::HashMap;

0 commit comments

Comments
 (0)