Skip to content

Commit 97b3a66

Browse files
authored
Rollup merge of rust-lang#137194 - kornelski:ftls, r=tgross35
More const {} init in thread_local `const {}` in `thread_local!` gets an optimization just based on the syntax, rather than the expression being const-compatible. This is easy to miss, so I've added more examples to the docs. I've also added `const {}` in a couple of places in std where this optimization has been missed.
2 parents 947d1fa + 42e10af commit 97b3a66

File tree

5 files changed

+25
-7
lines changed

5 files changed

+25
-7
lines changed

Diff for: std/src/io/stdio.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type LocalStream = Arc<Mutex<Vec<u8>>>;
2020

2121
thread_local! {
2222
/// Used by the test crate to capture the output of the print macros and panics.
23-
static OUTPUT_CAPTURE: Cell<Option<LocalStream>> = {
23+
static OUTPUT_CAPTURE: Cell<Option<LocalStream>> = const {
2424
Cell::new(None)
2525
}
2626
}

Diff for: std/src/sync/mpmc/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1382,3 +1382,6 @@ impl<T> fmt::Debug for Receiver<T> {
13821382
f.pad("Receiver { .. }")
13831383
}
13841384
}
1385+
1386+
#[cfg(test)]
1387+
mod tests;

Diff for: std/src/sync/mpmc/tests.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Ensure that thread_local init with `const { 0 }` still has unique address at run-time
2+
#[test]
3+
fn waker_current_thread_id() {
4+
let first = super::waker::current_thread_id();
5+
let t = crate::thread::spawn(move || {
6+
let second = super::waker::current_thread_id();
7+
assert_ne!(first, second);
8+
assert_eq!(second, super::waker::current_thread_id());
9+
});
10+
11+
assert_eq!(first, super::waker::current_thread_id());
12+
t.join().unwrap();
13+
assert_eq!(first, super::waker::current_thread_id());
14+
}

Diff for: std/src/sync/mpmc/waker.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,6 @@ impl Drop for SyncWaker {
204204
pub fn current_thread_id() -> usize {
205205
// `u8` is not drop so this variable will be available during thread destruction,
206206
// whereas `thread::current()` would not be
207-
thread_local! { static DUMMY: u8 = 0 }
207+
thread_local! { static DUMMY: u8 = const { 0 } }
208208
DUMMY.with(|x| (x as *const u8).addr())
209209
}

Diff for: std/src/thread/local.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ use crate::fmt;
5050
/// use std::cell::Cell;
5151
/// use std::thread;
5252
///
53-
/// thread_local!(static FOO: Cell<u32> = Cell::new(1));
53+
/// // explicit `const {}` block enables more efficient initialization
54+
/// thread_local!(static FOO: Cell<u32> = const { Cell::new(1) });
5455
///
5556
/// assert_eq!(FOO.get(), 1);
5657
/// FOO.set(2);
@@ -138,7 +139,7 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
138139
/// use std::cell::{Cell, RefCell};
139140
///
140141
/// thread_local! {
141-
/// pub static FOO: Cell<u32> = Cell::new(1);
142+
/// pub static FOO: Cell<u32> = const { Cell::new(1) };
142143
///
143144
/// static BAR: RefCell<Vec<f32>> = RefCell::new(vec![1.0, 2.0]);
144145
/// }
@@ -394,7 +395,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
394395
/// use std::cell::Cell;
395396
///
396397
/// thread_local! {
397-
/// static X: Cell<i32> = Cell::new(1);
398+
/// static X: Cell<i32> = const { Cell::new(1) };
398399
/// }
399400
///
400401
/// assert_eq!(X.get(), 1);
@@ -423,7 +424,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
423424
/// use std::cell::Cell;
424425
///
425426
/// thread_local! {
426-
/// static X: Cell<Option<i32>> = Cell::new(Some(1));
427+
/// static X: Cell<Option<i32>> = const { Cell::new(Some(1)) };
427428
/// }
428429
///
429430
/// assert_eq!(X.take(), Some(1));
@@ -453,7 +454,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
453454
/// use std::cell::Cell;
454455
///
455456
/// thread_local! {
456-
/// static X: Cell<i32> = Cell::new(1);
457+
/// static X: Cell<i32> = const { Cell::new(1) };
457458
/// }
458459
///
459460
/// assert_eq!(X.replace(2), 1);

0 commit comments

Comments
 (0)