Skip to content

Commit b6a2d7e

Browse files
committed
support pub(restricted) in thread_local!
1 parent 1475e2c commit b6a2d7e

File tree

2 files changed

+58
-39
lines changed

2 files changed

+58
-39
lines changed

src/libstd/thread/local.rs

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
115115
/// # Syntax
116116
///
117117
/// The macro wraps any number of static declarations and makes them thread local.
118-
/// Each static may be public or private, and attributes are allowed. Example:
118+
/// Publicity and attributes for each static are allowed. Example:
119119
///
120120
/// ```
121121
/// use std::cell::RefCell;
@@ -136,31 +136,40 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
136136
#[stable(feature = "rust1", since = "1.0.0")]
137137
#[allow_internal_unstable]
138138
macro_rules! thread_local {
139-
// rule 0: empty (base case for the recursion)
139+
// empty (base case for the recursion)
140140
() => {};
141141

142-
// rule 1: process multiple declarations where the first one is private
142+
// process multiple declarations where the first one is private
143143
($(#[$attr:meta])* static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
144-
thread_local!($(#[$attr])* static $name: $t = $init); // go to rule 2
144+
__thread_local_inner!($(#[$attr])* [] $name, $t, $init);
145145
thread_local!($($rest)*);
146146
);
147147

148-
// rule 2: handle a single private declaration
148+
// handle a single private declaration
149149
($(#[$attr:meta])* static $name:ident: $t:ty = $init:expr) => (
150-
$(#[$attr])* static $name: $crate::thread::LocalKey<$t> =
151-
__thread_local_inner!($t, $init);
150+
__thread_local_inner!($(#[$attr])* [] $name, $t, $init);
152151
);
153152

154-
// rule 3: handle multiple declarations where the first one is public
153+
// handle multiple declarations where the first one is public
155154
($(#[$attr:meta])* pub static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
156-
thread_local!($(#[$attr])* pub static $name: $t = $init); // go to rule 4
155+
__thread_local_inner!($(#[$attr])* [pub] $name, $t, $init);
157156
thread_local!($($rest)*);
158157
);
159158

160-
// rule 4: handle a single public declaration
159+
// handle a single public declaration
161160
($(#[$attr:meta])* pub static $name:ident: $t:ty = $init:expr) => (
162-
$(#[$attr])* pub static $name: $crate::thread::LocalKey<$t> =
163-
__thread_local_inner!($t, $init);
161+
__thread_local_inner!($(#[$attr])* [pub] $name, $t, $init);
162+
);
163+
164+
// handle multiple declarations where the first one is restricted public
165+
($(#[$attr:meta])* pub $vis:tt static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
166+
__thread_local_inner!($(#[$attr])* [pub $vis] $name, $t, $init);
167+
thread_local!($($rest)*);
168+
);
169+
170+
// handle a single restricted public declaration
171+
($(#[$attr:meta])* pub $vis:tt static $name:ident: $t:ty = $init:expr) => (
172+
__thread_local_inner!($(#[$attr])* [pub $vis] $name, $t, $init);
164173
);
165174
}
166175

@@ -171,27 +180,29 @@ macro_rules! thread_local {
171180
#[macro_export]
172181
#[allow_internal_unstable]
173182
macro_rules! __thread_local_inner {
174-
($t:ty, $init:expr) => {{
175-
fn __init() -> $t { $init }
176-
177-
fn __getit() -> $crate::option::Option<
178-
&'static $crate::cell::UnsafeCell<
179-
$crate::option::Option<$t>>>
180-
{
181-
#[thread_local]
182-
#[cfg(target_thread_local)]
183-
static __KEY: $crate::thread::__FastLocalKeyInner<$t> =
184-
$crate::thread::__FastLocalKeyInner::new();
185-
186-
#[cfg(not(target_thread_local))]
187-
static __KEY: $crate::thread::__OsLocalKeyInner<$t> =
188-
$crate::thread::__OsLocalKeyInner::new();
189-
190-
__KEY.get()
191-
}
183+
($(#[$attr:meta])* [$($vis:tt)*] $name:ident, $t:ty, $init:expr) => {
184+
$(#[$attr])* $($vis)* static $name: $crate::thread::LocalKey<$t> = {
185+
fn __init() -> $t { $init }
186+
187+
fn __getit() -> $crate::option::Option<
188+
&'static $crate::cell::UnsafeCell<
189+
$crate::option::Option<$t>>>
190+
{
191+
#[thread_local]
192+
#[cfg(target_thread_local)]
193+
static __KEY: $crate::thread::__FastLocalKeyInner<$t> =
194+
$crate::thread::__FastLocalKeyInner::new();
195+
196+
#[cfg(not(target_thread_local))]
197+
static __KEY: $crate::thread::__OsLocalKeyInner<$t> =
198+
$crate::thread::__OsLocalKeyInner::new();
199+
200+
__KEY.get()
201+
}
192202

193-
$crate::thread::LocalKey::new(__getit, __init)
194-
}}
203+
$crate::thread::LocalKey::new(__getit, __init)
204+
};
205+
}
195206
}
196207

197208
/// Indicator of the state of a thread local storage key.

src/test/run-pass/thread-local-syntax.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,21 @@
1111
#![deny(missing_docs)]
1212
//! this tests the syntax of `thread_local!`
1313
14-
thread_local! {
15-
// no docs
16-
#[allow(unused)]
17-
static FOO: i32 = 42;
18-
/// docs
19-
pub static BAR: String = String::from("bar");
14+
mod foo {
15+
mod bar {
16+
thread_local! {
17+
// no docs
18+
#[allow(unused)]
19+
static FOO: i32 = 42;
20+
/// docs
21+
pub static BAR: String = String::from("bar");
22+
23+
// look at these restrictions!!
24+
pub(crate) static BAZ: usize = 0;
25+
pub(in foo) static QUUX: usize = 0;
26+
}
27+
thread_local!(static SPLOK: u32 = 0);
28+
}
2029
}
21-
thread_local!(static BAZ: u32 = 0);
2230

2331
fn main() {}

0 commit comments

Comments
 (0)