diff --git a/futures-macro/Cargo.toml b/futures-macro/Cargo.toml index 9fc1857bb9..26ae6bed22 100644 --- a/futures-macro/Cargo.toml +++ b/futures-macro/Cargo.toml @@ -16,6 +16,9 @@ proc-macro = true [features] +[build-dependencies] +autocfg = "1" + [dependencies] proc-macro2 = "1.0" proc-macro-hack = "0.5.19" diff --git a/futures-macro/build.rs b/futures-macro/build.rs new file mode 100644 index 0000000000..fec7b029eb --- /dev/null +++ b/futures-macro/build.rs @@ -0,0 +1,26 @@ +#![warn(rust_2018_idioms, single_use_lifetimes)] + +use autocfg::AutoCfg; + +// The rustc-cfg strings below are *not* public API. Please let us know by +// opening a GitHub issue if your build environment requires some way to enable +// these cfgs other than by executing our build script. +fn main() { + let cfg = match AutoCfg::new() { + Ok(cfg) => cfg, + Err(e) => { + println!( + "cargo:warning={}: unable to determine rustc version: {}", + env!("CARGO_PKG_NAME"), + e + ); + return; + } + }; + + // Function like procedural macros in expressions patterns statements stabilized in Rust 1.45: + // https://blog.rust-lang.org/2020/07/16/Rust-1.45.0.html#stabilizing-function-like-procedural-macros-in-expressions-patterns-and-statements + if cfg.probe_rustc_version(1, 45) { + println!("cargo:rustc-cfg=fn_like_proc_macro"); + } +} diff --git a/futures-macro/src/lib.rs b/futures-macro/src/lib.rs index 5f0c47ca89..98408ebfe6 100644 --- a/futures-macro/src/lib.rs +++ b/futures-macro/src/lib.rs @@ -13,31 +13,34 @@ extern crate proc_macro; use proc_macro::TokenStream; -use proc_macro_hack::proc_macro_hack; mod join; mod select; /// The `join!` macro. -#[proc_macro_hack] +#[cfg_attr(fn_like_proc_macro, proc_macro)] +#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack)] pub fn join_internal(input: TokenStream) -> TokenStream { crate::join::join(input) } /// The `try_join!` macro. -#[proc_macro_hack] +#[cfg_attr(fn_like_proc_macro, proc_macro)] +#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack)] pub fn try_join_internal(input: TokenStream) -> TokenStream { crate::join::try_join(input) } /// The `select!` macro. -#[proc_macro_hack] +#[cfg_attr(fn_like_proc_macro, proc_macro)] +#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack)] pub fn select_internal(input: TokenStream) -> TokenStream { crate::select::select(input) } /// The `select_biased!` macro. -#[proc_macro_hack] +#[cfg_attr(fn_like_proc_macro, proc_macro)] +#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack)] pub fn select_biased_internal(input: TokenStream) -> TokenStream { crate::select::select_biased(input) } diff --git a/futures-util/Cargo.toml b/futures-util/Cargo.toml index 263c4df85b..f2b3dc9d33 100644 --- a/futures-util/Cargo.toml +++ b/futures-util/Cargo.toml @@ -32,6 +32,9 @@ bilock = [] read-initializer = ["io", "futures-io/read-initializer", "futures-io/unstable"] write-all-vectored = ["io"] +[build-dependencies] +autocfg = "1" + [dependencies] futures-core = { path = "../futures-core", version = "=1.0.0-alpha.0", default-features = false } futures-task = { path = "../futures-task", version = "=0.4.0-alpha.0", default-features = false } diff --git a/futures-util/build.rs b/futures-util/build.rs new file mode 100644 index 0000000000..fec7b029eb --- /dev/null +++ b/futures-util/build.rs @@ -0,0 +1,26 @@ +#![warn(rust_2018_idioms, single_use_lifetimes)] + +use autocfg::AutoCfg; + +// The rustc-cfg strings below are *not* public API. Please let us know by +// opening a GitHub issue if your build environment requires some way to enable +// these cfgs other than by executing our build script. +fn main() { + let cfg = match AutoCfg::new() { + Ok(cfg) => cfg, + Err(e) => { + println!( + "cargo:warning={}: unable to determine rustc version: {}", + env!("CARGO_PKG_NAME"), + e + ); + return; + } + }; + + // Function like procedural macros in expressions patterns statements stabilized in Rust 1.45: + // https://blog.rust-lang.org/2020/07/16/Rust-1.45.0.html#stabilizing-function-like-procedural-macros-in-expressions-patterns-and-statements + if cfg.probe_rustc_version(1, 45) { + println!("cargo:rustc-cfg=fn_like_proc_macro"); + } +} diff --git a/futures-util/src/async_await/join_mod.rs b/futures-util/src/async_await/join_mod.rs index 965d9fb236..c5cdd9babc 100644 --- a/futures-util/src/async_await/join_mod.rs +++ b/futures-util/src/async_await/join_mod.rs @@ -1,7 +1,5 @@ //! The `join` macro. -use proc_macro_hack::proc_macro_hack; - macro_rules! document_join_macro { ($join:item $try_join:item) => { /// Polls multiple futures simultaneously, returning a tuple @@ -81,12 +79,14 @@ macro_rules! document_join_macro { } } +#[allow(unreachable_pub)] #[doc(hidden)] -#[proc_macro_hack(support_nested, only_hack_old_rustc)] +#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack(support_nested))] pub use futures_macro::join_internal; +#[allow(unreachable_pub)] #[doc(hidden)] -#[proc_macro_hack(support_nested, only_hack_old_rustc)] +#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack(support_nested))] pub use futures_macro::try_join_internal; document_join_macro! { diff --git a/futures-util/src/async_await/select_mod.rs b/futures-util/src/async_await/select_mod.rs index 59bca0840a..37e938da55 100644 --- a/futures-util/src/async_await/select_mod.rs +++ b/futures-util/src/async_await/select_mod.rs @@ -1,7 +1,5 @@ //! The `select` macro. -use proc_macro_hack::proc_macro_hack; - macro_rules! document_select_macro { // This branch is required for `futures 0.3.1`, from before select_biased was introduced ($select:item) => { @@ -309,12 +307,14 @@ macro_rules! document_select_macro { } #[cfg(feature = "std")] +#[allow(unreachable_pub)] #[doc(hidden)] -#[proc_macro_hack(support_nested, only_hack_old_rustc)] +#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack(support_nested))] pub use futures_macro::select_internal; +#[allow(unreachable_pub)] #[doc(hidden)] -#[proc_macro_hack(support_nested, only_hack_old_rustc)] +#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack(support_nested))] pub use futures_macro::select_biased_internal; document_select_macro! {