Skip to content

Commit 48aa3f1

Browse files
committed
Merge pull request rust-lang-nursery#21 from durka/metadata
support metadata on statics
2 parents 94dda0a + 3a47450 commit 48aa3f1

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

src/lib.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ lazy_static! {
1717
}
1818
```
1919
20+
Metadata (such as doc comments) is allowed on each ref.
21+
2022
# Semantic
2123
22-
For a given `static ref NAME: TYPE = EXPR;`, the macro generates a
23-
unique type that implements `Deref<TYPE>` and stores it in a static with name `NAME`.
24+
For a given `static ref NAME: TYPE = EXPR;`, the macro generates a unique type that
25+
implements `Deref<TYPE>` and stores it in a static with name `NAME`. (Metadata ends up
26+
attaching to this type.)
2427
2528
On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
2629
can return a reference to the same object.
@@ -72,14 +75,14 @@ define uninitialized `static mut` values.
7275

7376
#[macro_export]
7477
macro_rules! lazy_static {
75-
(static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
76-
lazy_static!(PRIV static ref $N : $T = $e; $($t)*);
78+
($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
79+
lazy_static!(PRIV, $(#[$attr])* static ref $N : $T = $e; $($t)*);
7780
};
78-
(pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
79-
lazy_static!(PUB static ref $N : $T = $e; $($t)*);
81+
($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
82+
lazy_static!(PUB, $(#[$attr])* static ref $N : $T = $e; $($t)*);
8083
};
81-
($VIS:ident static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
82-
lazy_static!(MAKE TY $VIS $N);
84+
($VIS:ident, $(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
85+
lazy_static!(MAKE TY, $VIS, $(#[$attr])*, $N);
8386
impl ::std::ops::Deref for $N {
8487
type Target = $T;
8588
fn deref<'a>(&'a self) -> &'a $T {
@@ -106,18 +109,22 @@ macro_rules! lazy_static {
106109
}
107110
lazy_static!($($t)*);
108111
};
109-
(MAKE TY PUB $N:ident) => {
112+
(MAKE TY, PUB, $(#[$attr:meta])*, $N:ident) => {
110113
#[allow(missing_copy_implementations)]
111114
#[allow(non_camel_case_types)]
112115
#[allow(dead_code)]
116+
$(#[$attr])*
113117
pub struct $N {__private_field: ()}
118+
#[doc(hidden)]
114119
pub static $N: $N = $N {__private_field: ()};
115120
};
116-
(MAKE TY PRIV $N:ident) => {
121+
(MAKE TY, PRIV, $(#[$attr:meta])*, $N:ident) => {
117122
#[allow(missing_copy_implementations)]
118123
#[allow(non_camel_case_types)]
119124
#[allow(dead_code)]
125+
$(#[$attr])*
120126
struct $N {__private_field: ()}
127+
#[doc(hidden)]
121128
static $N: $N = $N {__private_field: ()};
122129
};
123130
() => ()

tests/test.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,29 @@ extern crate lazy_static;
33
use std::collections::HashMap;
44

55
lazy_static! {
6-
static ref NUMBER: u32 = times_two(3);
6+
/// Documentation!
7+
pub static ref NUMBER: u32 = times_two(3);
8+
79
static ref ARRAY_BOXES: [Box<u32>; 3] = [Box::new(1), Box::new(2), Box::new(3)];
8-
static ref STRING: String = "hello".to_string();
10+
11+
/// More documentation!
12+
#[allow(unused_variables)]
13+
#[derive(Copy, Clone, Debug)]
14+
pub static ref STRING: String = "hello".to_string();
15+
916
static ref HASHMAP: HashMap<u32, &'static str> = {
1017
let mut m = HashMap::new();
1118
m.insert(0, "abc");
1219
m.insert(1, "def");
1320
m.insert(2, "ghi");
1421
m
1522
};
23+
1624
// This should not compile if the unsafe is removed.
1725
static ref UNSAFE: u32 = unsafe {
1826
std::mem::transmute::<i32, u32>(-1)
1927
};
28+
2029
// This *should* triggger warn(dead_code) by design.
2130
static ref UNUSED: () = ();
2231

@@ -43,6 +52,17 @@ fn test_repeat() {
4352
assert_eq!(*NUMBER, 6);
4453
}
4554

55+
#[test]
56+
fn test_meta() {
57+
// this would not compile if STRING were not marked #[derive(Copy, Clone)]
58+
let copy_of_string = STRING;
59+
// just to make sure it was copied
60+
assert!(&STRING as *const _ != &copy_of_string as *const _);
61+
62+
// this would not compile if STRING were not marked #[derive(Debug)]
63+
assert_eq!(format!("{:?}", STRING), "STRING { __private_field: () }".to_string());
64+
}
65+
4666
mod visibility {
4767
lazy_static! {
4868
pub static ref FOO: Box<u32> = Box::new(0);

0 commit comments

Comments
 (0)