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 _ != ©_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