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