Skip to content

Commit 4d9faf3

Browse files
authored
Auto merge of #34077 - durka:patch-23, r=alexcrichton
upgrade thread_local! invocation syntax Allows declaring multiple statics in one macro invocation, and supports attaching attributes to the generated items. In particular, `#![forbid(missing_docs, unused)]` is now tenable on a crate/module containing thread locals. For an example see [here](https://is.gd/aVFZZF). This change is fully backwards compatible as far as I can tell. cc @frankmcsherry
2 parents ad7fe65 + fc28ee2 commit 4d9faf3

File tree

2 files changed

+61
-4
lines changed

2 files changed

+61
-4
lines changed

src/libstd/thread/local.rs

+38-4
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,52 @@ pub struct LocalKey<T: 'static> {
100100

101101
/// Declare a new thread local storage key of type `std::thread::LocalKey`.
102102
///
103+
/// # Syntax
104+
///
105+
/// The macro wraps any number of static declarations and makes them thread local.
106+
/// Each static may be public or private, and attributes are allowed. Example:
107+
///
108+
/// ```
109+
/// use std::cell::RefCell;
110+
/// thread_local! {
111+
/// pub static FOO: RefCell<u32> = RefCell::new(1);
112+
///
113+
/// #[allow(unused)]
114+
/// static BAR: RefCell<f32> = RefCell::new(1.0);
115+
/// }
116+
/// # fn main() {}
117+
/// ```
118+
///
103119
/// See [LocalKey documentation](thread/struct.LocalKey.html) for more
104120
/// information.
105121
#[macro_export]
106122
#[stable(feature = "rust1", since = "1.0.0")]
107123
#[allow_internal_unstable]
108124
macro_rules! thread_local {
109-
(static $name:ident: $t:ty = $init:expr) => (
110-
static $name: $crate::thread::LocalKey<$t> =
125+
// rule 0: empty (base case for the recursion)
126+
() => {};
127+
128+
// rule 1: process multiple declarations where the first one is private
129+
($(#[$attr:meta])* static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
130+
thread_local!($(#[$attr])* static $name: $t = $init); // go to rule 2
131+
thread_local!($($rest)*);
132+
);
133+
134+
// rule 2: handle a single private declaration
135+
($(#[$attr:meta])* static $name:ident: $t:ty = $init:expr) => (
136+
$(#[$attr])* static $name: $crate::thread::LocalKey<$t> =
111137
__thread_local_inner!($t, $init);
112138
);
113-
(pub static $name:ident: $t:ty = $init:expr) => (
114-
pub static $name: $crate::thread::LocalKey<$t> =
139+
140+
// rule 3: handle multiple declarations where the first one is public
141+
($(#[$attr:meta])* pub static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
142+
thread_local!($(#[$attr])* pub static $name: $t = $init); // go to rule 4
143+
thread_local!($($rest)*);
144+
);
145+
146+
// rule 4: handle a single public declaration
147+
($(#[$attr:meta])* pub static $name:ident: $t:ty = $init:expr) => (
148+
$(#[$attr])* pub static $name: $crate::thread::LocalKey<$t> =
115149
__thread_local_inner!($t, $init);
116150
);
117151
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![deny(missing_docs)]
12+
//! this tests the syntax of `thread_local!`
13+
14+
thread_local! {
15+
// no docs
16+
#[allow(unused)]
17+
static FOO: i32 = 42;
18+
/// docs
19+
pub static BAR: String = String::from("bar");
20+
}
21+
thread_local!(static BAZ: u32 = 0);
22+
23+
fn main() {}

0 commit comments

Comments
 (0)