1#[macro_use]
2extern crate lazy_static;
3use std::collections::HashMap;
4
5lazy_static! {
6 /// Documentation!
7 pub static ref NUMBER: u32 = times_two(3);
8
9 static ref ARRAY_BOXES: [Box<u32>; 3] = [Box::new(1), Box::new(2), Box::new(3)];
10
11 /// More documentation!
12 #[allow(unused_variables)]
13 #[derive(Copy, Clone, Debug)]
14 pub static ref STRING: String = "hello".to_string();
15
16 static ref HASHMAP: HashMap<u32, &'static str> = {
17 let mut m = HashMap::new();
18 m.insert(0, "abc");
19 m.insert(1, "def");
20 m.insert(2, "ghi");
21 m
22 };
23
24 // This should not compile if the unsafe is removed.
25 static ref UNSAFE: u32 = unsafe {
26 std::mem::transmute::<i32, u32>(-1)
27 };
28}
29
30lazy_static! {
31 static ref S1: &'static str = "a";
32 static ref S2: &'static str = "b";
33}
34lazy_static! {
35 static ref S3: String = [*S1, *S2].join("");
36}
37
38#[test]
39fn s3() {
40 assert_eq!(&*S3, "ab");
41}
42
43fn times_two(n: u32) -> u32 {
44 n * 2
45}
46
47#[test]
48fn test_basic() {
49 assert_eq!(&**STRING, "hello");
50 assert_eq!(*NUMBER, 6);
51 assert!(HASHMAP.get(&1).is_some());
52 assert!(HASHMAP.get(&3).is_none());
53 assert_eq!(&*ARRAY_BOXES, &[Box::new(1), Box::new(2), Box::new(3)]);
54 assert_eq!(*UNSAFE, std::u32::MAX);
55}
56
57#[test]
58fn test_repeat() {
59 assert_eq!(*NUMBER, 6);
60 assert_eq!(*NUMBER, 6);
61 assert_eq!(*NUMBER, 6);
62}
63
64#[test]
65fn test_meta() {
66 // this would not compile if STRING were not marked #[derive(Copy, Clone)]
67 let copy_of_string = STRING;
68 // just to make sure it was copied
69 assert!(&STRING as *const _ != ©_of_string as *const _);
70
71 // this would not compile if STRING were not marked #[derive(Debug)]
72 assert_eq!(format!("{:?}", STRING), "STRING { __private_field: () }".to_string());
73}
74
75mod visibility {
76 lazy_static! {
77 pub static ref FOO: Box<u32> = Box::new(0);
78 static ref BAR: Box<u32> = Box::new(98);
79 }
80
81 pub mod inner {
82 lazy_static! {
83 pub(in visibility) static ref BAZ: Box<u32> = Box::new(42);
84 pub(crate) static ref BAG: Box<u32> = Box::new(37);
85 }
86 }
87
88 #[test]
89 fn sub_test() {
90 assert_eq!(**FOO, 0);
91 assert_eq!(**BAR, 98);
92 assert_eq!(**inner::BAZ, 42);
93 assert_eq!(**inner::BAG, 37);
94 }
95}
96
97#[test]
98fn test_visibility() {
99 assert_eq!(*visibility::FOO, Box::new(0));
100 assert_eq!(*visibility::inner::BAG, Box::new(37));
101}
102
103// This should not cause a warning about a missing Copy implementation
104lazy_static! {
105 pub static ref VAR: i32 = { 0 };
106}
107
108#[derive(Copy, Clone, Debug, PartialEq)]
109struct X;
110struct Once(X);
111const ONCE_INIT: Once = Once(X);
112static DATA: X = X;
113static ONCE: X = X;
114fn require_sync() -> X { X }
115fn transmute() -> X { X }
116fn __static_ref_initialize() -> X { X }
117fn test(_: Vec<X>) -> X { X }
118
119// All these names should not be shadowed
120lazy_static! {
121 static ref ITEM_NAME_TEST: X = {
122 test(vec![X, Once(X).0, ONCE_INIT.0, DATA, ONCE,
123 require_sync(), transmute(),
124 // Except this, which will sadly be shadowed by internals:
125 // __static_ref_initialize()
126 ])
127 };
128}
129
130#[test]
131fn item_name_shadowing() {
132 assert_eq!(*ITEM_NAME_TEST, X);
133}
134
135use std::sync::atomic::AtomicBool;
136#[allow(deprecated)]
137use std::sync::atomic::ATOMIC_BOOL_INIT;
138use std::sync::atomic::Ordering::SeqCst;
139
140#[allow(deprecated)]
141static PRE_INIT_FLAG: AtomicBool = ATOMIC_BOOL_INIT;
142
143lazy_static! {
144 static ref PRE_INIT: () = {
145 PRE_INIT_FLAG.store(true, SeqCst);
146 ()
147 };
148}
149
150#[test]
151fn pre_init() {
152 assert_eq!(PRE_INIT_FLAG.load(SeqCst), false);
153 lazy_static::initialize(&PRE_INIT);
154 assert_eq!(PRE_INIT_FLAG.load(SeqCst), true);
155}
156
157lazy_static! {
158 static ref LIFETIME_NAME: for<'a> fn(&'a u8) = { fn f(_: &u8) {} f };
159}
160
161#[test]
162fn lifetime_name() {
163 let _ = LIFETIME_NAME;
164}
165