Skip to content

Commit 67e2c36

Browse files
committed
Made macro more hygenic by re-arranging items inside the expansion to not be
visible inside the user-provided code.
1 parent 46d69dc commit 67e2c36

File tree

2 files changed

+40
-12
lines changed

2 files changed

+40
-12
lines changed

src/lazy_static.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,22 @@ macro_rules! lazy_static {
8383
impl ::std::ops::Deref for $N {
8484
type Target = $T;
8585
fn deref<'a>(&'a self) -> &'a $T {
86-
use std::sync::{Once, ONCE_INIT};
87-
use std::mem::transmute;
88-
89-
#[inline(always)]
90-
fn require_sync<T: Sync>(_: &T) { }
91-
9286
#[inline(always)]
93-
fn initialize() -> Box<$T> { Box::new($e) }
87+
fn __static_ref_initialize() -> Box<$T> { Box::new($e) }
9488

9589
unsafe {
96-
static mut __static: *const $T = 0 as *const $T;
97-
static mut __ONCE: Once = ONCE_INIT;
98-
__ONCE.call_once(|| {
99-
__static = transmute::<Box<$T>, *const $T>(initialize());
90+
use std::sync::{Once, ONCE_INIT};
91+
use std::mem::transmute;
92+
93+
#[inline(always)]
94+
fn require_sync<T: Sync>(_: &T) { }
95+
96+
static mut DATA: *const $T = 0 as *const $T;
97+
static mut ONCE: Once = ONCE_INIT;
98+
ONCE.call_once(|| {
99+
DATA = transmute::<Box<$T>, *const $T>(__static_ref_initialize());
100100
});
101-
let static_ref = &*__static;
101+
let static_ref = &*DATA;
102102
require_sync(static_ref);
103103
static_ref
104104
}

tests/test.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ lazy_static! {
1919
};
2020
// This *should* triggger warn(dead_code) by design.
2121
static ref UNUSED: () = ();
22+
2223
}
2324

2425
fn times_two(n: u32) -> u32 {
@@ -57,3 +58,30 @@ fn test_visibility() {
5758
lazy_static! {
5859
pub static ref VAR: i32 = { 0 };
5960
}
61+
62+
#[derive(Copy, Clone, Debug, PartialEq)]
63+
struct X;
64+
struct Once(X);
65+
const ONCE_INIT: Once = Once(X);
66+
static DATA: X = X;
67+
static ONCE: X = X;
68+
fn require_sync() -> X { X }
69+
fn transmute() -> X { X }
70+
fn __static_ref_initialize() -> X { X }
71+
fn test(_: Vec<X>) -> X { X }
72+
73+
// All these names should not be shadowed
74+
lazy_static! {
75+
static ref ITEM_NAME_TEST: X = {
76+
test(vec![X, Once(X).0, ONCE_INIT.0, DATA, ONCE,
77+
require_sync(), transmute(),
78+
// Except this, which will sadly be shadowed by internals:
79+
// __static_ref_initialize()
80+
])
81+
};
82+
}
83+
84+
#[test]
85+
fn item_name_shadowing() {
86+
assert_eq!(*ITEM_NAME_TEST, X);
87+
}

0 commit comments

Comments
 (0)