diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-01-22 16:55:00 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-22 16:55:00 +0100 |
| commit | d3761de43fbb66a19fb53cd25a7bdfcca0b7c318 (patch) | |
| tree | 01569c3d1b08ebd6f2878f9385f02c54263a399c | |
| parent | 6e4933f94f9b06a7a5ab4ad3e39a0229e9f17023 (diff) | |
| parent | c43344e839906624a388847906f6a9b27dcd35c4 (diff) | |
| download | rust-d3761de43fbb66a19fb53cd25a7bdfcca0b7c318.tar.gz rust-d3761de43fbb66a19fb53cd25a7bdfcca0b7c318.zip | |
Rollup merge of #120181 - dtolnay:tlconst, r=thomcc
Allow any `const` expression blocks in `thread_local!`
This PR contains a rebase of the macro change from #116392, together with adding a test under library/std/tests.
Testing this feature by making the documentation's example code needlessly more complicated was not appropriate as pointed out in https://github.com/rust-lang/rust/pull/116392#pullrequestreview-1753097757.
Without the macro change, this new test would fail to build as follows:
```console
error: no rules expected the token `let`
--> library/std/tests/thread.rs:26:13
|
26 | let value = 1;
| ^^^ no rules expected this token in macro call
|
note: while trying to match meta-variable `$init:expr`
--> library/std/src/thread/local.rs:189:69
|
189 | ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = const { $init:expr }; $($rest:tt)*) => (
| ^^^^^^^^^^
```
Closes #116392.
| -rw-r--r-- | library/std/src/thread/local.rs | 4 | ||||
| -rw-r--r-- | library/std/tests/thread.rs | 22 |
2 files changed, 24 insertions, 2 deletions
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 338567777f7..2e13f433dcf 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -186,12 +186,12 @@ macro_rules! thread_local { // empty (base case for the recursion) () => {}; - ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = const { $init:expr }; $($rest:tt)*) => ( + ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = const $init:block; $($rest:tt)*) => ( $crate::thread::local_impl::thread_local_inner!($(#[$attr])* $vis $name, $t, const $init); $crate::thread_local!($($rest)*); ); - ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = const { $init:expr }) => ( + ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = const $init:block) => ( $crate::thread::local_impl::thread_local_inner!($(#[$attr])* $vis $name, $t, const $init); ); diff --git a/library/std/tests/thread.rs b/library/std/tests/thread.rs index 754b264c6ad..4ce81f2846e 100644 --- a/library/std/tests/thread.rs +++ b/library/std/tests/thread.rs @@ -1,3 +1,4 @@ +use std::cell::{Cell, RefCell}; use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; @@ -14,3 +15,24 @@ fn sleep() { thread::sleep(Duration::from_millis(100)); assert_eq!(*finished.lock().unwrap(), false); } + +#[test] +fn thread_local_containing_const_statements() { + // This exercises the `const $init:block` cases of the thread_local macro. + // Despite overlapping with expression syntax, the `const { ... }` is not + // parsed as `$init:expr`. + thread_local! { + static CELL: Cell<u32> = const { + let value = 1; + Cell::new(value) + }; + + static REFCELL: RefCell<u32> = const { + let value = 1; + RefCell::new(value) + }; + } + + assert_eq!(CELL.get(), 1); + assert_eq!(REFCELL.take(), 1); +} |
