From 1fc450aefba4b05cdff9b7825ca5e39cccb3780e Mon Sep 17 00:00:00 2001 From: Daksh <41485688+Daksh14@users.noreply.github.com> Date: Thu, 2 Apr 2026 09:13:24 -0400 Subject: [PATCH] runtime: stabilize `LocalRuntime` (#7557) --- tokio-macros/src/entry.rs | 22 ---------------------- tokio-macros/src/lib.rs | 13 ------------- tokio/src/runtime/builder.rs | 9 ++++----- tokio/src/runtime/local_runtime/runtime.rs | 1 - tokio/src/runtime/mod.rs | 12 ++++++------ tokio/src/task/local.rs | 10 +++------- 6 files changed, 13 insertions(+), 54 deletions(-) diff --git a/tokio-macros/src/entry.rs b/tokio-macros/src/entry.rs index 476006703..aa6523bfa 100644 --- a/tokio-macros/src/entry.rs +++ b/tokio-macros/src/entry.rs @@ -476,12 +476,7 @@ fn parse_knobs(mut input: ItemFn, is_test: bool, config: FinalConfig) -> TokenSt }, }; - let mut checks = vec![]; - let mut errors = vec![]; - let build = if let RuntimeFlavor::Local = config.flavor { - checks.push(quote! { tokio_unstable }); - errors.push("The local runtime flavor is only available when `tokio_unstable` is set."); quote_spanned! {last_stmt_start_span=> build_local(Default::default())} } else { quote_spanned! {last_stmt_start_span=> build()} @@ -509,23 +504,10 @@ fn parse_knobs(mut input: ItemFn, is_test: bool, config: FinalConfig) -> TokenSt quote! {} }; - let do_checks: TokenStream = checks - .iter() - .zip(&errors) - .map(|(check, error)| { - quote! { - #[cfg(not(#check))] - compile_error!(#error); - } - }) - .collect(); - let body_ident = quote! { body }; // This explicit `return` is intentional. See tokio-rs/tokio#4636 let last_block = quote_spanned! {last_stmt_end_span=> - #do_checks - #[cfg(all(#(#checks),*))] #[allow(clippy::expect_used, clippy::diverging_sub_expression, clippy::needless_return, clippy::unwrap_in_result)] { #use_builder @@ -537,10 +519,6 @@ fn parse_knobs(mut input: ItemFn, is_test: bool, config: FinalConfig) -> TokenSt .block_on(#body_ident); } - #[cfg(not(all(#(#checks),*)))] - { - panic!("fell through checks") - } }; let body = input.body(); diff --git a/tokio-macros/src/lib.rs b/tokio-macros/src/lib.rs index 9f999df6f..3b4f46c76 100644 --- a/tokio-macros/src/lib.rs +++ b/tokio-macros/src/lib.rs @@ -73,16 +73,11 @@ use proc_macro::TokenStream; /// /// ## Local /// -/// [Unstable API][unstable] only. -/// /// To use the [local runtime], the macro can be configured using /// /// ```rust -/// # #[cfg(tokio_unstable)] /// #[tokio::main(flavor = "local")] /// # async fn main() {} -/// # #[cfg(not(tokio_unstable))] -/// # fn main() {} /// ``` /// /// # Function arguments @@ -165,25 +160,19 @@ use proc_macro::TokenStream; /// /// ## Using the local runtime /// -/// Available in the [unstable API][unstable] only. -/// /// The [local runtime] is similar to the current-thread runtime but /// supports [`task::spawn_local`](../tokio/task/fn.spawn_local.html). /// /// ```rust -/// # #[cfg(tokio_unstable)] /// #[tokio::main(flavor = "local")] /// async fn main() { /// println!("Hello world"); /// } -/// # #[cfg(not(tokio_unstable))] -/// # fn main() {} /// ``` /// /// Equivalent code not using `#[tokio::main]` /// /// ```rust -/// # #[cfg(tokio_unstable)] /// fn main() { /// tokio::runtime::Builder::new_current_thread() /// .enable_all() @@ -193,8 +182,6 @@ use proc_macro::TokenStream; /// println!("Hello world"); /// }) /// } -/// # #[cfg(not(tokio_unstable))] -/// # fn main() {} /// ``` /// /// diff --git a/tokio/src/runtime/builder.rs b/tokio/src/runtime/builder.rs index 88c1699aa..04f7efff0 100644 --- a/tokio/src/runtime/builder.rs +++ b/tokio/src/runtime/builder.rs @@ -5,7 +5,9 @@ use crate::runtime::{ blocking, driver, Callback, HistogramBuilder, Runtime, TaskCallback, TimerFlavor, }; #[cfg(tokio_unstable)] -use crate::runtime::{metrics::HistogramConfiguration, LocalOptions, LocalRuntime, TaskMeta}; +use crate::runtime::{metrics::HistogramConfiguration, TaskMeta}; + +use crate::runtime::{LocalOptions, LocalRuntime}; use crate::util::rand::{RngSeed, RngSeedGenerator}; use crate::runtime::blocking::BlockingPool; @@ -241,7 +243,7 @@ impl Builder { /// Configuration methods can be chained on the return value. /// /// To spawn non-`Send` tasks on the resulting runtime, combine it with a - /// [`LocalSet`], or call [`build_local`] to create a [`LocalRuntime`] (unstable). + /// [`LocalSet`], or call [`build_local`] to create a [`LocalRuntime`]. /// /// [`LocalSet`]: crate::task::LocalSet /// [`LocalRuntime`]: crate::runtime::LocalRuntime @@ -1048,8 +1050,6 @@ impl Builder { /// }); /// ``` #[allow(unused_variables, unreachable_patterns)] - #[cfg(tokio_unstable)] - #[cfg_attr(docsrs, doc(cfg(tokio_unstable)))] pub fn build_local(&mut self, options: LocalOptions) -> io::Result { match &self.kind { Kind::CurrentThread => self.build_current_thread_local_runtime(), @@ -1605,7 +1605,6 @@ impl Builder { )) } - #[cfg(tokio_unstable)] fn build_current_thread_local_runtime(&mut self) -> io::Result { use crate::runtime::local_runtime::LocalRuntimeScheduler; diff --git a/tokio/src/runtime/local_runtime/runtime.rs b/tokio/src/runtime/local_runtime/runtime.rs index 8c47445d8..0d79f6f1d 100644 --- a/tokio/src/runtime/local_runtime/runtime.rs +++ b/tokio/src/runtime/local_runtime/runtime.rs @@ -29,7 +29,6 @@ use std::time::Duration; /// [runtime]: crate::runtime::Runtime /// [module]: crate::runtime #[derive(Debug)] -#[cfg_attr(docsrs, doc(cfg(tokio_unstable)))] pub struct LocalRuntime { /// Task scheduler scheduler: LocalRuntimeScheduler, diff --git a/tokio/src/runtime/mod.rs b/tokio/src/runtime/mod.rs index bd3c381bf..713f60de0 100644 --- a/tokio/src/runtime/mod.rs +++ b/tokio/src/runtime/mod.rs @@ -36,9 +36,9 @@ //! | Yes | No //! | | //! V | -//! +--------------------------+ | -//! | Local Runtime (unstable) | | -//! +--------------------------+ | +//! +---------------+ | +//! | Local Runtime | | +//! +---------------+ | //! | //! v //! +------------------------+ @@ -575,9 +575,6 @@ cfg_rt! { pub use self::builder::UnhandledPanic; pub use crate::util::rand::RngSeed; - mod local_runtime; - pub use local_runtime::{LocalRuntime, LocalOptions}; - /// Returns the index of the current worker thread, if called from a /// runtime worker thread. /// @@ -635,6 +632,9 @@ cfg_rt! { mod runtime; pub use runtime::{Runtime, RuntimeFlavor, is_rt_shutdown_err}; + mod local_runtime; + pub use local_runtime::{LocalRuntime, LocalOptions}; + mod id; pub use id::Id; diff --git a/tokio/src/task/local.rs b/tokio/src/task/local.rs index c1764300b..cf75097a8 100644 --- a/tokio/src/task/local.rs +++ b/tokio/src/task/local.rs @@ -328,9 +328,8 @@ impl<'a> Drop for LocalDataEnterGuard<'a> { cfg_rt! { /// Spawns a `!Send` future on the current [`LocalSet`] or [`LocalRuntime`]. /// - /// This is possible when either using one of these types - /// explicitly, or (with `tokio_unstable`) by opting to use the - /// `"local"` runtime flavor in `tokio::main`: + /// This is possible when either using one of these types explicitly, or by + /// opting to use the `"local"` runtime flavor in `tokio::main`: /// /// ```ignore /// #[tokio::main(flavor = "local")] @@ -374,10 +373,9 @@ cfg_rt! { /// }).await; /// # } /// ``` - /// With local runtime flavor ([Unstable API][unstable] only). + /// With local runtime flavor. /// /// ```rust - /// # #[cfg(tokio_unstable)] /// #[tokio::main(flavor = "local")] /// async fn main() { /// let join = tokio::task::spawn_local(async { @@ -386,8 +384,6 @@ cfg_rt! { /// /// join.await.unwrap() /// } - /// # #[cfg(not(tokio_unstable))] - /// # fn main() {} /// /// ``` ///