Skip to content

Commit 1bfbfbf

Browse files
Support all cfg_attr arities
1 parent 8d3352a commit 1bfbfbf

File tree

6 files changed

+192
-53
lines changed

6 files changed

+192
-53
lines changed

library/std/src/sys/thread_local/os.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,46 +59,45 @@ pub macro thread_local_inner {
5959
},
6060

6161
// process a single `rustc_align_static` attribute
62-
(@align_single $final_align:ident, rustc_align_static $($attr_rest:tt)*) => {
63-
#[allow(unused_parens)]
64-
let new_align: usize = $($attr_rest)*;
62+
(@align_single $final_align:ident, rustc_align_static($($align:tt)*) $(, $($attr_rest:tt)+)?) => {
63+
let new_align: $crate::primitive::usize = $($align)*;
6564
if new_align > $final_align {
6665
$final_align = new_align;
6766
}
67+
68+
$($crate::thread::local_impl::thread_local_inner!(@align_single $final_align, $($attr_rest)+);)?
6869
},
6970

7071
// process a single `cfg_attr` attribute
7172
// by translating it into a `cfg`ed block and recursing.
7273
// https://doc.rust-lang.org/reference/conditional-compilation.html#railroad-ConfigurationPredicate
7374

74-
(@align_single $final_align:ident, cfg_attr(true, $($cfg_rhs:tt)*)) => {
75+
(@align_single $final_align:ident, cfg_attr(true, $($cfg_rhs:tt)*) $(, $($attr_rest:tt)+)?) => {
7576
#[cfg(true)]
7677
{
7778
$crate::thread::local_impl::thread_local_inner!(@align_single $final_align, $($cfg_rhs)*);
7879
}
80+
81+
$($crate::thread::local_impl::thread_local_inner!(@align_single $final_align, $($attr_rest)+);)?
7982
},
8083

81-
(@align_single $final_align:ident, cfg_attr(false, $($cfg_rhs:tt)*)) => {
84+
(@align_single $final_align:ident, cfg_attr(false, $($cfg_rhs:tt)*) $(, $($attr_rest:tt)+)?) => {
8285
#[cfg(false)]
8386
{
8487
$crate::thread::local_impl::thread_local_inner!(@align_single $final_align, $($cfg_rhs)*);
8588
}
86-
},
8789

88-
(@align_single $final_align:ident, cfg_attr($cfg_op:ident ($($cfg_preds:tt)*), $($cfg_rhs:tt)*)) => {
89-
#[cfg($cfg_op ($($cfg_preds)*))]
90-
{
91-
$crate::thread::local_impl::thread_local_inner!(@align_single $final_align, $($cfg_rhs)*);
92-
}
90+
$($crate::thread::local_impl::thread_local_inner!(@align_single $final_align, $($attr_rest)+);)?
9391
},
9492

95-
(@align_single $final_align:ident, cfg_attr($cfg_ident:ident $(= $cfg_val:expr)?, $($cfg_rhs:tt)*)) => {
96-
#[cfg($cfg_ident $(= $cfg_val)?)]
93+
(@align_single $final_align:ident, cfg_attr($cfg_pred:meta, $($cfg_rhs:tt)*) $(, $($attr_rest:tt)+)?) => {
94+
#[cfg($cfg_pred)]
9795
{
9896
$crate::thread::local_impl::thread_local_inner!(@align_single $final_align, $($cfg_rhs)*);
9997
}
100-
},
10198

99+
$($crate::thread::local_impl::thread_local_inner!(@align_single $final_align, $($attr_rest)+);)?
100+
},
102101

103102
($(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $(#[$($align_attr:tt)*])*, $($init:tt)*) => {
104103
$(#[$attr])* $vis const $name: $crate::thread::LocalKey<$t> =

library/std/src/thread/local.rs

Lines changed: 140 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,122 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
137137
#[unstable(feature = "thread_local_internals", issue = "none")]
138138
#[rustc_macro_transparency = "semitransparent"]
139139
pub macro thread_local_process_attrs {
140+
141+
// Parse `cfg_attr` to figure out whether it's a `rustc_align_static`.
142+
// Each `cfg_attr` can have zero or more attributes on the RHS, and can be nested.
143+
144+
// finished parsing the `cfg_attr`, it had no `rustc_align_static`
145+
(
146+
[] [$(#[$($prev_other_attrs:tt)*])*];
147+
@processing_cfg_attr { pred: ($($predicate:tt)*), rhs: [] };
148+
[$($prev_align_attrs_ret:tt)*] [$($prev_other_attrs_ret:tt)*];
149+
$($rest:tt)*
150+
) => (
151+
$crate::thread::local_impl::thread_local_process_attrs!(
152+
[$($prev_align_attrs_ret)*] [$($prev_other_attrs_ret)* #[cfg_attr($($predicate)*, $($($prev_other_attrs)*),*)]];
153+
$($rest)*
154+
);
155+
),
156+
157+
// finished parsing the `cfg_attr`, it had nothing but `rustc_align_static`
158+
(
159+
[$(#[$($prev_align_attrs:tt)*])+] [];
160+
@processing_cfg_attr { pred: ($($predicate:tt)*), rhs: [] };
161+
[$($prev_align_attrs_ret:tt)*] [$($prev_other_attrs_ret:tt)*];
162+
$($rest:tt)*
163+
) => (
164+
$crate::thread::local_impl::thread_local_process_attrs!(
165+
[$($prev_align_attrs_ret)* #[cfg_attr($($predicate)*, $($($prev_align_attrs)*),+)]] [$($prev_other_attrs_ret)*];
166+
$($rest)*
167+
);
168+
),
169+
170+
// finished parsing the `cfg_attr`, it had a mix of `rustc_align_static` and other attrs
171+
(
172+
[$(#[$($prev_align_attrs:tt)*])+] [$(#[$($prev_other_attrs:tt)*])+];
173+
@processing_cfg_attr { pred: ($($predicate:tt)*), rhs: [] };
174+
[$($prev_align_attrs_ret:tt)*] [$($prev_other_attrs_ret:tt)*];
175+
$($rest:tt)*
176+
) => (
177+
$crate::thread::local_impl::thread_local_process_attrs!(
178+
[$($prev_align_attrs_ret)* #[cfg_attr($($predicate)*, $($($prev_align_attrs)*),+)]] [$($prev_other_attrs_ret)* #[cfg_attr($($predicate)*, $($($prev_other_attrs)*),+)]];
179+
$($rest)*
180+
);
181+
),
182+
183+
// it's a `rustc_align_static`
184+
(
185+
[$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*];
186+
@processing_cfg_attr { pred: ($($predicate:tt)*), rhs: [rustc_align_static($($align_static_args:tt)*) $(, $($attr_rhs:tt)*)?] };
187+
$($rest:tt)*
188+
) => (
189+
$crate::thread::local_impl::thread_local_process_attrs!(
190+
[$($prev_align_attrs)* #[rustc_align_static($($align_static_args)*)]] [$($prev_other_attrs)*];
191+
@processing_cfg_attr { pred: ($($predicate)*), rhs: [$($($attr_rhs)*)?] };
192+
$($rest)*
193+
);
194+
),
195+
196+
// it's a nested `cfg_attr(true, ...)`; recurse into RHS
197+
(
198+
[$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*];
199+
@processing_cfg_attr { pred: ($($predicate:tt)*), rhs: [cfg_attr(true, $($cfg_rhs:tt)*) $(, $($attr_rhs:tt)*)?] };
200+
$($rest:tt)*
201+
) => (
202+
$crate::thread::local_impl::thread_local_process_attrs!(
203+
[] [];
204+
@processing_cfg_attr { pred: (true), rhs: [$($cfg_rhs)*] };
205+
[$($prev_align_attrs)*] [$($prev_other_attrs)*];
206+
@processing_cfg_attr { pred: ($($predicate)*), rhs: [$($($attr_rhs)*)?] };
207+
$($rest)*
208+
);
209+
),
210+
211+
// it's a nested `cfg_attr(false, ...)`; recurse into RHS
212+
(
213+
[$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*];
214+
@processing_cfg_attr { pred: ($($predicate:tt)*), rhs: [cfg_attr(false, $($cfg_rhs:tt)*) $(, $($attr_rhs:tt)*)?] };
215+
$($rest:tt)*
216+
) => (
217+
$crate::thread::local_impl::thread_local_process_attrs!(
218+
[] [];
219+
@processing_cfg_attr { pred: (false), rhs: [$($cfg_rhs)*] };
220+
[$($prev_align_attrs)*] [$($prev_other_attrs)*];
221+
@processing_cfg_attr { pred: ($($predicate)*), rhs: [$($($attr_rhs)*)?] };
222+
$($rest)*
223+
);
224+
),
225+
226+
227+
// it's a nested `cfg_attr(..., ...)`; recurse into RHS
228+
(
229+
[$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*];
230+
@processing_cfg_attr { pred: ($($predicate:tt)*), rhs: [cfg_attr($cfg_lhs:meta, $($cfg_rhs:tt)*) $(, $($attr_rhs:tt)*)?] };
231+
$($rest:tt)*
232+
) => (
233+
$crate::thread::local_impl::thread_local_process_attrs!(
234+
[] [];
235+
@processing_cfg_attr { pred: ($cfg_lhs), rhs: [$($cfg_rhs)*] };
236+
[$($prev_align_attrs)*] [$($prev_other_attrs)*];
237+
@processing_cfg_attr { pred: ($($predicate)*), rhs: [$($($attr_rhs)*)?] };
238+
$($rest)*
239+
);
240+
),
241+
242+
// it's some other attribute
243+
(
244+
[$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*];
245+
@processing_cfg_attr { pred: ($($predicate:tt)*), rhs: [$meta:meta $(, $($attr_rhs:tt)*)?] };
246+
$($rest:tt)*
247+
) => (
248+
$crate::thread::local_impl::thread_local_process_attrs!(
249+
[$($prev_align_attrs)*] [$($prev_other_attrs)* #[$meta]];
250+
@processing_cfg_attr { pred: ($($predicate)*), rhs: [$($($attr_rhs)*)?] };
251+
$($rest)*
252+
);
253+
),
254+
255+
140256
// Separate attributes into `rustc_align_static` and everything else:
141257

142258
// `rustc_align_static` attribute
@@ -147,10 +263,31 @@ pub macro thread_local_process_attrs {
147263
);
148264
),
149265

150-
// `cfg_attr` attribute; parse it to determine whether the RHS is `rustc_align_static`
151-
([$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*]; #[cfg_attr $($attr_rest:tt)*] $($rest:tt)*) => (
266+
// `cfg_attr(true, ...)` attribute; parse it
267+
([$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*]; #[cfg_attr(true, $($cfg_rhs:tt)*)] $($rest:tt)*) => (
268+
$crate::thread::local_impl::thread_local_process_attrs!(
269+
[] [];
270+
@processing_cfg_attr { pred: (true), rhs: [$($cfg_rhs)*] };
271+
[$($prev_align_attrs)*] [$($prev_other_attrs)*];
272+
$($rest)*
273+
);
274+
),
275+
276+
// `cfg_attr(false, ...)` attribute; parse it
277+
([$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*]; #[cfg_attr(false, $($cfg_rhs:tt)*)] $($rest:tt)*) => (
278+
$crate::thread::local_impl::thread_local_process_attrs!(
279+
[] [];
280+
@processing_cfg_attr { pred: (false), rhs: [$($cfg_rhs)*] };
281+
[$($prev_align_attrs)*] [$($prev_other_attrs)*];
282+
$($rest)*
283+
);
284+
),
285+
286+
// `cfg_attr(..., ...)` attribute; parse it
287+
([$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*]; #[cfg_attr($cfg_pred:meta, $($cfg_rhs:tt)*)] $($rest:tt)*) => (
152288
$crate::thread::local_impl::thread_local_process_attrs!(
153-
@processing_cfg_attr #[cfg_attr $($attr_rest)*] at [cfg_attr $($attr_rest)*];
289+
[] [];
290+
@processing_cfg_attr { pred: ($cfg_pred), rhs: [$($cfg_rhs)*] };
154291
[$($prev_align_attrs)*] [$($prev_other_attrs)*];
155292
$($rest)*
156293
);
@@ -186,34 +323,6 @@ pub macro thread_local_process_attrs {
186323
),
187324

188325

189-
// Parse `cfg_attr` to figure out whether it's a `rustc_align_static`:
190-
191-
// yes, it's a `rustc_align_static`
192-
(@processing_cfg_attr #[$($full_attr:tt)*] at [rustc_align_static $($attr_rest:tt)*]; [$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*]; $($rest:tt)*) => (
193-
$crate::thread::local_impl::thread_local_process_attrs!(
194-
[$($prev_align_attrs)* #[$($full_attr)*]] [$($prev_other_attrs)*];
195-
$($rest)*
196-
);
197-
),
198-
199-
// it's a nested `cfg_attr`; recurse into RHS
200-
(@processing_cfg_attr #[$($full_attr:tt)*] at [cfg_attr($cfg_lhs:expr, $($cfg_rhs:tt)*)]; [$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*]; $($rest:tt)*) => (
201-
$crate::thread::local_impl::thread_local_process_attrs!(
202-
@processing_cfg_attr #[$($full_attr)*] at [$($cfg_rhs)*];
203-
[$($prev_align_attrs)*] [$($prev_other_attrs)*];
204-
$($rest)*
205-
);
206-
),
207-
208-
// it's neither of the two
209-
(@processing_cfg_attr #[$($full_attr:tt)*] at [$($remaining_attr:tt)*]; [$($prev_align_attrs:tt)*] [$($prev_other_attrs:tt)*]; $($rest:tt)*) => (
210-
$crate::thread::local_impl::thread_local_process_attrs!(
211-
[$($prev_align_attrs)*] [$($prev_other_attrs)* #[$($full_attr)*]];
212-
$($rest)*
213-
);
214-
),
215-
216-
217326
// Delegate to `thread_local_inner` once attributes are fully categorized:
218327

219328
// process `const` declaration and recurse

src/tools/miri/tests/pass/static_align.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(static_align)]
2+
#![deny(non_upper_case_globals)]
23

34
use std::cell::Cell;
45

@@ -38,6 +39,17 @@ thread_local! {
3839
#[allow(unused_mut, reason = "test attribute handling")]
3940
/// I love doc comments.
4041
static HASDROP_CONST_LOCAL: Cell<HasDrop> = const { Cell::new(HasDrop(core::ptr::null())) };
42+
43+
#[cfg_attr(true,)]
44+
#[cfg_attr(false,)]
45+
#[cfg_attr(
46+
true,
47+
rustc_align_static(32),
48+
cfg_attr(true, allow(non_upper_case_globals, reason = "test attribute handling")),
49+
cfg_attr(false,)
50+
)]
51+
#[cfg_attr(false, rustc_align_static(0))]
52+
static more_attr_testing: u64 = 0;
4153
}
4254

4355
fn thread_local_ptr<T>(key: &'static std::thread::LocalKey<T>) -> *const T {
@@ -52,6 +64,7 @@ fn main() {
5264
assert!(thread_local_ptr(&CONST_LOCAL).addr().is_multiple_of(4096));
5365
assert!(thread_local_ptr(&HASDROP_LOCAL).addr().is_multiple_of(4096));
5466
assert!(thread_local_ptr(&HASDROP_CONST_LOCAL).addr().is_multiple_of(4096));
67+
assert!(thread_local_ptr(&more_attr_testing).addr().is_multiple_of(32));
5568

5669
// Test that address (and therefore alignment) is maintained during drop
5770
let hasdrop_ptr = thread_local_ptr(&HASDROP_LOCAL);

tests/ui/static/static-align.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//@ run-pass
22
//@ compile-flags: --cfg FOURTY_TWO="42" --cfg TRUE --check-cfg=cfg(FOURTY_TWO,values("42")) --check-cfg=cfg(TRUE)
33
#![feature(static_align)]
4+
#![deny(non_upper_case_globals)]
45

56
use std::cell::Cell;
67

@@ -66,6 +67,18 @@ thread_local! {
6667
/// I love doc comments.
6768
/// I love doc comments.
6869
static HASDROP_CONST_LOCAL: Cell<HasDrop> = const { Cell::new(HasDrop(core::ptr::null())) };
70+
71+
#[cfg_attr(TRUE,)]
72+
#[cfg_attr(true,)]
73+
#[cfg_attr(false,)]
74+
#[cfg_attr(
75+
TRUE,
76+
rustc_align_static(32),
77+
cfg_attr(true, allow(non_upper_case_globals, reason = "test attribute handling")),
78+
cfg_attr(false,)
79+
)]
80+
#[cfg_attr(false, rustc_align_static(0))]
81+
static more_attr_testing: u64 = 0;
6982
}
7083

7184
fn thread_local_ptr<T>(key: &'static std::thread::LocalKey<T>) -> *const T {
@@ -83,6 +96,7 @@ fn main() {
8396
assert!(thread_local_ptr(&CONST_LOCAL).addr().is_multiple_of(4096));
8497
assert!(thread_local_ptr(&HASDROP_LOCAL).addr().is_multiple_of(4096));
8598
assert!(thread_local_ptr(&HASDROP_CONST_LOCAL).addr().is_multiple_of(4096));
99+
assert!(thread_local_ptr(&more_attr_testing).addr().is_multiple_of(32));
86100

87101
// Test that address (and therefore alignment) is maintained during drop
88102
let hasdrop_ptr = thread_local_ptr(&HASDROP_LOCAL);
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
thread_local! {
22
//~^ ERROR: use of an internal attribute [E0658]
3+
//~| ERROR: use of an internal attribute [E0658]
34
//~| ERROR: `#[used(linker)]` is currently unstable [E0658]
45
//~| ERROR: `#[used]` attribute cannot be used on constants
56

67
#[rustc_dummy = 17]
78
pub static FOO: () = ();
89

910
#[cfg_attr(true, rustc_dummy = 17)]
10-
//~^ ERROR: use of an internal attribute [E0658]
1111
pub static BAR: () = ();
1212

1313
#[used(linker)]
14-
pub static BARZ: () = ();
14+
pub static BAZ: () = ();
1515
}
1616

1717
fn main() {}

tests/ui/thread-local/no-unstable.stderr

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ error[E0658]: use of an internal attribute
33
|
44
LL | / thread_local! {
55
... |
6-
LL | | pub static BARZ: () = ();
6+
LL | | pub static BAZ: () = ();
77
LL | | }
88
| |_^
99
|
@@ -13,21 +13,25 @@ LL | | }
1313
= note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
1414

1515
error[E0658]: use of an internal attribute
16-
--> $DIR/no-unstable.rs:9:22
16+
--> $DIR/no-unstable.rs:1:1
1717
|
18-
LL | #[cfg_attr(true, rustc_dummy = 17)]
19-
| ^^^^^^^^^^^^^^^^
18+
LL | / thread_local! {
19+
... |
20+
LL | | pub static BAZ: () = ();
21+
LL | | }
22+
| |_^
2023
|
2124
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
2225
= note: the `#[rustc_dummy]` attribute is an internal implementation detail that will never be stable
2326
= note: the `#[rustc_dummy]` attribute is used for rustc unit tests
27+
= note: this error originates in the macro `$crate::thread::local_impl::thread_local_process_attrs` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
2428

2529
error[E0658]: `#[used(linker)]` is currently unstable
2630
--> $DIR/no-unstable.rs:1:1
2731
|
2832
LL | / thread_local! {
2933
... |
30-
LL | | pub static BARZ: () = ();
34+
LL | | pub static BAZ: () = ();
3135
LL | | }
3236
| |_^
3337
|
@@ -41,7 +45,7 @@ error: `#[used]` attribute cannot be used on constants
4145
|
4246
LL | / thread_local! {
4347
... |
44-
LL | | pub static BARZ: () = ();
48+
LL | | pub static BAZ: () = ();
4549
LL | | }
4650
| |_^
4751
|

0 commit comments

Comments
 (0)