diff --git a/tokio/build.rs b/tokio/build.rs index 4c04a84d050..6da64cdea83 100644 --- a/tokio/build.rs +++ b/tokio/build.rs @@ -1,11 +1,38 @@ use autocfg::AutoCfg; +const CONST_THREAD_LOCAL_PROBE: &str = r#" +{ + thread_local! { + static MY_PROBE: usize = const { 10 }; + } + + MY_PROBE.with(|val| *val) +} +"#; + fn main() { + let mut enable_const_thread_local = false; + match AutoCfg::new() { Ok(ac) => { - // Const-initialized thread locals were stabilized in 1.59 - if ac.probe_rustc_version(1, 59) { - autocfg::emit("tokio_const_thread_local") + // These checks prefer to call only `probe_rustc_version` if that is + // enough to determine whether the feature is supported. This is + // because the `probe_expression` call involves a call to rustc, + // which the `probe_rustc_version` call avoids. + + // Const-initialized thread locals were stabilized in 1.59. + if ac.probe_rustc_version(1, 60) { + enable_const_thread_local = true; + } else if ac.probe_rustc_version(1, 59) { + // This compiler claims to be 1.59, but there are some nightly + // compilers that claim to be 1.59 without supporting the + // feature. Explicitly probe to check if code using them + // compiles. + // + // The oldest nightly that supports the feature is 2021-12-06. + if ac.probe_expression(CONST_THREAD_LOCAL_PROBE) { + enable_const_thread_local = true; + } } } @@ -19,4 +46,12 @@ fn main() { ); } } + + if !enable_const_thread_local { + // To disable this feature on compilers that support it, you can + // explicitly pass this flag with the following environment variable: + // + // RUSTFLAGS="--cfg tokio_no_const_thread_local" + autocfg::emit("tokio_no_const_thread_local") + } } diff --git a/tokio/src/macros/thread_local.rs b/tokio/src/macros/thread_local.rs index e82a3307249..13a4f467f50 100644 --- a/tokio/src/macros/thread_local.rs +++ b/tokio/src/macros/thread_local.rs @@ -10,12 +10,14 @@ macro_rules! thread_local { ($($tts:tt)+) => { loom::thread_local!{ $($tts)+ } } } -#[cfg(all(tokio_const_thread_local, not(all(loom, test))))] +#[cfg(not(tokio_no_const_thread_local))] +#[cfg(not(all(loom, test)))] macro_rules! thread_local { ($($tts:tt)+) => { ::std::thread_local!{ $($tts)+ } } } -#[cfg(all(not(tokio_const_thread_local), not(all(loom, test))))] +#[cfg(tokio_no_const_thread_local)] +#[cfg(not(all(loom, test)))] macro_rules! thread_local { ($(#[$attrs:meta])* $vis:vis static $name:ident: $ty:ty = const { $expr:expr } $(;)?) => { ::std::thread_local! { diff --git a/tokio/src/task/task_local.rs b/tokio/src/task/task_local.rs index e92b05fdc98..924af625b7b 100644 --- a/tokio/src/task/task_local.rs +++ b/tokio/src/task/task_local.rs @@ -47,7 +47,7 @@ macro_rules! task_local { } #[doc(hidden)] -#[cfg(tokio_const_thread_local)] +#[cfg(not(tokio_no_const_thread_local))] #[macro_export] macro_rules! __task_local_inner { ($(#[$attr:meta])* $vis:vis $name:ident, $t:ty) => { @@ -62,7 +62,7 @@ macro_rules! __task_local_inner { } #[doc(hidden)] -#[cfg(not(tokio_const_thread_local))] +#[cfg(tokio_no_const_thread_local)] #[macro_export] macro_rules! __task_local_inner { ($(#[$attr:meta])* $vis:vis $name:ident, $t:ty) => {