@@ -71,6 +71,7 @@ define uninitialized `static mut` values.
71
71
72
72
*/
73
73
74
+ #![ cfg_attr( feature="nightly" , feature( const_fn) ) ]
74
75
#![ crate_type = "dylib" ]
75
76
76
77
#[ macro_export]
@@ -87,21 +88,48 @@ macro_rules! lazy_static {
87
88
type Target = $T;
88
89
fn deref<' a>( & ' a self ) -> & ' a $T {
89
90
#[ inline( always) ]
90
- fn __static_ref_initialize( ) -> Box <$T> { Box :: new ( $e ) }
91
+ fn __static_ref_initialize( ) -> $T { $e }
91
92
92
93
unsafe {
93
94
use std:: sync:: { Once , ONCE_INIT } ;
94
- use std:: mem:: transmute;
95
95
96
96
#[ inline( always) ]
97
97
fn require_sync<T : Sync >( _: & T ) { }
98
98
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( ) ;
105
133
require_sync( static_ref) ;
106
134
static_ref
107
135
}
0 commit comments