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