1 #[macro_use]
2 extern crate lazy_static;
3 use std::collections::HashMap;
4 
5 lazy_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 
30 lazy_static! {
31     static ref S1: &'static str = "a";
32     static ref S2: &'static str = "b";
33 }
34 lazy_static! {
35     static ref S3: String = [*S1, *S2].join("");
36 }
37 
38 #[test]
s3()39 fn s3() {
40     assert_eq!(&*S3, "ab");
41 }
42 
times_two(n: u32) -> u3243 fn times_two(n: u32) -> u32 {
44     n * 2
45 }
46 
47 #[test]
test_basic()48 fn 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]
test_repeat()58 fn test_repeat() {
59     assert_eq!(*NUMBER, 6);
60     assert_eq!(*NUMBER, 6);
61     assert_eq!(*NUMBER, 6);
62 }
63 
64 #[test]
test_meta()65 fn 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 _ != &copy_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 
75 mod 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]
sub_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]
test_visibility()98 fn 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
104 lazy_static! {
105     pub static ref VAR: i32 = { 0 };
106 }
107 
108 #[derive(Copy, Clone, Debug, PartialEq)]
109 struct X;
110 struct Once(X);
111 const ONCE_INIT: Once = Once(X);
112 static DATA: X = X;
113 static ONCE: X = X;
require_sync() -> X114 fn require_sync() -> X { X }
transmute() -> X115 fn transmute() -> X { X }
__static_ref_initialize() -> X116 fn __static_ref_initialize() -> X { X }
test(_: Vec<X>) -> X117 fn test(_: Vec<X>) -> X { X }
118 
119 // All these names should not be shadowed
120 lazy_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]
item_name_shadowing()131 fn item_name_shadowing() {
132     assert_eq!(*ITEM_NAME_TEST, X);
133 }
134 
135 use std::sync::atomic::AtomicBool;
136 #[allow(deprecated)]
137 use std::sync::atomic::ATOMIC_BOOL_INIT;
138 use std::sync::atomic::Ordering::SeqCst;
139 
140 #[allow(deprecated)]
141 static PRE_INIT_FLAG: AtomicBool = ATOMIC_BOOL_INIT;
142 
143 lazy_static! {
144     static ref PRE_INIT: () = {
145         PRE_INIT_FLAG.store(true, SeqCst);
146         ()
147     };
148 }
149 
150 #[test]
pre_init()151 fn 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 
157 lazy_static! {
158     static ref LIFETIME_NAME: for<'a> fn(&'a u8) = { fn f(_: &u8) {} f };
159 }
160 
161 #[test]
lifetime_name()162 fn lifetime_name() {
163     let _ = LIFETIME_NAME;
164 }
165