diff --git a/crates/std_detect/src/detect/arch/aarch64.rs b/crates/std_detect/src/detect/arch/aarch64.rs index 5d2fb6d4d5..f32f961ae5 100644 --- a/crates/std_detect/src/detect/arch/aarch64.rs +++ b/crates/std_detect/src/detect/arch/aarch64.rs @@ -2,6 +2,7 @@ features! { @TARGET: aarch64; + @CFG: target_arch = "aarch64"; @MACRO_NAME: is_aarch64_feature_detected; @MACRO_ATTRS: /// This macro tests, at runtime, whether an `aarch64` feature is enabled on aarch64 platforms. diff --git a/crates/std_detect/src/detect/arch/arm.rs b/crates/std_detect/src/detect/arch/arm.rs index 9e7dda094f..897dc314c7 100644 --- a/crates/std_detect/src/detect/arch/arm.rs +++ b/crates/std_detect/src/detect/arch/arm.rs @@ -2,6 +2,7 @@ features! { @TARGET: arm; + @CFG: target_arch = "arm"; @MACRO_NAME: is_arm_feature_detected; @MACRO_ATTRS: /// Checks if `arm` feature is enabled. diff --git a/crates/std_detect/src/detect/arch/mips.rs b/crates/std_detect/src/detect/arch/mips.rs index ada81b83ec..ae27d0093c 100644 --- a/crates/std_detect/src/detect/arch/mips.rs +++ b/crates/std_detect/src/detect/arch/mips.rs @@ -2,6 +2,7 @@ features! { @TARGET: mips; + @CFG: target_arch = "mips"; @MACRO_NAME: is_mips_feature_detected; @MACRO_ATTRS: /// Checks if `mips` feature is enabled. diff --git a/crates/std_detect/src/detect/arch/mips64.rs b/crates/std_detect/src/detect/arch/mips64.rs index 6a0bb159ba..7182ec2da4 100644 --- a/crates/std_detect/src/detect/arch/mips64.rs +++ b/crates/std_detect/src/detect/arch/mips64.rs @@ -2,6 +2,7 @@ features! { @TARGET: mips64; + @CFG: target_arch = "mips64"; @MACRO_NAME: is_mips64_feature_detected; @MACRO_ATTRS: /// Checks if `mips64` feature is enabled. diff --git a/crates/std_detect/src/detect/arch/mod.rs b/crates/std_detect/src/detect/arch/mod.rs new file mode 100644 index 0000000000..81a1f23e87 --- /dev/null +++ b/crates/std_detect/src/detect/arch/mod.rs @@ -0,0 +1,56 @@ +#![allow(dead_code)] + +use cfg_if::cfg_if; + +// Export the macros for all supported architectures. +#[macro_use] +mod x86; +#[macro_use] +mod arm; +#[macro_use] +mod aarch64; +#[macro_use] +mod riscv; +#[macro_use] +mod powerpc; +#[macro_use] +mod powerpc64; +#[macro_use] +mod mips; +#[macro_use] +mod mips64; + +cfg_if! { + if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + pub use x86::*; + } else if #[cfg(target_arch = "arm")] { + pub use arm::*; + } else if #[cfg(target_arch = "aarch64")] { + pub use aarch64::*; + } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { + pub use riscv::*; + } else if #[cfg(target_arch = "powerpc")] { + pub use powerpc::*; + } else if #[cfg(target_arch = "powerpc64")] { + pub use powerpc64::*; + } else if #[cfg(target_arch = "mips")] { + pub use mips::*; + } else if #[cfg(target_arch = "mips64")] { + pub use mips64::*; + } else { + // Unimplemented architecture: + #[doc(hidden)] + pub(crate) enum Feature { + Null + } + #[doc(hidden)] + pub mod __is_feature_detected {} + + impl Feature { + #[doc(hidden)] + pub(crate) fn from_str(_s: &str) -> Result { Err(()) } + #[doc(hidden)] + pub(crate) fn to_str(self) -> &'static str { "" } + } + } +} diff --git a/crates/std_detect/src/detect/arch/powerpc.rs b/crates/std_detect/src/detect/arch/powerpc.rs index 44bd7f337f..d135cd95de 100644 --- a/crates/std_detect/src/detect/arch/powerpc.rs +++ b/crates/std_detect/src/detect/arch/powerpc.rs @@ -2,6 +2,7 @@ features! { @TARGET: powerpc; + @CFG: target_arch = "powerpc"; @MACRO_NAME: is_powerpc_feature_detected; @MACRO_ATTRS: /// Checks if `powerpc` feature is enabled. diff --git a/crates/std_detect/src/detect/arch/powerpc64.rs b/crates/std_detect/src/detect/arch/powerpc64.rs index 17e4d958bf..773afd6ceb 100644 --- a/crates/std_detect/src/detect/arch/powerpc64.rs +++ b/crates/std_detect/src/detect/arch/powerpc64.rs @@ -2,6 +2,7 @@ features! { @TARGET: powerpc64; + @CFG: target_arch = "powerpc64"; @MACRO_NAME: is_powerpc64_feature_detected; @MACRO_ATTRS: /// Checks if `powerpc` feature is enabled. diff --git a/crates/std_detect/src/detect/arch/riscv.rs b/crates/std_detect/src/detect/arch/riscv.rs index ac43b2c4dd..5ea36e7c1c 100644 --- a/crates/std_detect/src/detect/arch/riscv.rs +++ b/crates/std_detect/src/detect/arch/riscv.rs @@ -2,6 +2,7 @@ features! { @TARGET: riscv; + @CFG: any(target_arch = "riscv32", target_arch = "riscv64"); @MACRO_NAME: is_riscv_feature_detected; @MACRO_ATTRS: /// A macro to test at *runtime* whether instruction sets are available on diff --git a/crates/std_detect/src/detect/arch/x86.rs b/crates/std_detect/src/detect/arch/x86.rs index 22dbb98412..893e1a887f 100644 --- a/crates/std_detect/src/detect/arch/x86.rs +++ b/crates/std_detect/src/detect/arch/x86.rs @@ -17,6 +17,7 @@ features! { @TARGET: x86; + @CFG: any(target_arch = "x86", target_arch = "x86_64"); @MACRO_NAME: is_x86_feature_detected; @MACRO_ATTRS: /// A macro to test at *runtime* whether a CPU feature is available on diff --git a/crates/std_detect/src/detect/error_macros.rs b/crates/std_detect/src/detect/error_macros.rs deleted file mode 100644 index 1e70da486f..0000000000 --- a/crates/std_detect/src/detect/error_macros.rs +++ /dev/null @@ -1,171 +0,0 @@ -//! The `is_{target_arch}_feature_detected!` macro are only available on their -//! architecture. These macros provide a better error messages when the user -//! attempts to call them in a different architecture. - -/// Prevents compilation if `is_x86_feature_detected` is used somewhere -/// else than `x86` and `x86_64` targets. -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -#[macro_export] -#[unstable(feature = "stdsimd", issue = "27731")] -macro_rules! is_x86_feature_detected { - ($t: tt) => { - compile_error!( - r#" - is_x86_feature_detected can only be used on x86 and x86_64 targets. - You can prevent it from being used in other architectures by - guarding it behind a cfg(target_arch) as follows: - - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { - if is_x86_feature_detected(...) { ... } - } - "# - ) - }; -} - -/// Prevents compilation if `is_arm_feature_detected` is used somewhere else -/// than `ARM` targets. -#[cfg(not(target_arch = "arm"))] -#[macro_export] -#[unstable(feature = "stdsimd", issue = "27731")] -macro_rules! is_arm_feature_detected { - ($t:tt) => { - compile_error!( - r#" - is_arm_feature_detected can only be used on ARM targets. - You can prevent it from being used in other architectures by - guarding it behind a cfg(target_arch) as follows: - - #[cfg(target_arch = "arm")] { - if is_arm_feature_detected(...) { ... } - } - "# - ) - }; -} - -/// Prevents compilation if `is_aarch64_feature_detected` is used somewhere else -/// than `aarch64` targets. -#[cfg(not(target_arch = "aarch64"))] -#[macro_export] -#[unstable(feature = "stdsimd", issue = "27731")] -macro_rules! is_aarch64_feature_detected { - ($t: tt) => { - compile_error!( - r#" - is_aarch64_feature_detected can only be used on AArch64 targets. - You can prevent it from being used in other architectures by - guarding it behind a cfg(target_arch) as follows: - - #[cfg(target_arch = "aarch64")] { - if is_aarch64_feature_detected(...) { ... } - } - "# - ) - }; -} - -/// Prevents compilation if `is_riscv_feature_detected` is used somewhere else -/// than `riscv32` or `riscv64` targets. -#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] -#[macro_export] -#[unstable(feature = "stdsimd", issue = "27731")] -macro_rules! is_riscv_feature_detected { - ($t: tt) => { - compile_error!( - r#" - is_riscv_feature_detected can only be used on RISC-V targets. - You can prevent it from being used in other architectures by - guarding it behind a cfg(target_arch) as follows: - - #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { - if is_riscv_feature_detected(...) { ... } - } - "# - ) - }; -} - -/// Prevents compilation if `is_powerpc_feature_detected` is used somewhere else -/// than `PowerPC` targets. -#[cfg(not(target_arch = "powerpc"))] -#[macro_export] -#[unstable(feature = "stdsimd", issue = "27731")] -macro_rules! is_powerpc_feature_detected { - ($t:tt) => { - compile_error!( - r#" -is_powerpc_feature_detected can only be used on PowerPC targets. -You can prevent it from being used in other architectures by -guarding it behind a cfg(target_arch) as follows: - - #[cfg(target_arch = "powerpc")] { - if is_powerpc_feature_detected(...) { ... } - } -"# - ) - }; -} - -/// Prevents compilation if `is_powerpc64_feature_detected` is used somewhere -/// else than `PowerPC64` targets. -#[cfg(not(target_arch = "powerpc64"))] -#[macro_export] -#[unstable(feature = "stdsimd", issue = "27731")] -macro_rules! is_powerpc64_feature_detected { - ($t:tt) => { - compile_error!( - r#" -is_powerpc64_feature_detected can only be used on PowerPC64 targets. -You can prevent it from being used in other architectures by -guarding it behind a cfg(target_arch) as follows: - - #[cfg(target_arch = "powerpc64")] { - if is_powerpc64_feature_detected(...) { ... } - } -"# - ) - }; -} - -/// Prevents compilation if `is_mips_feature_detected` is used somewhere else -/// than `MIPS` targets. -#[cfg(not(target_arch = "mips"))] -#[macro_export] -#[unstable(feature = "stdsimd", issue = "27731")] -macro_rules! is_mips_feature_detected { - ($t:tt) => { - compile_error!( - r#" - is_mips_feature_detected can only be used on MIPS targets. - You can prevent it from being used in other architectures by - guarding it behind a cfg(target_arch) as follows: - - #[cfg(target_arch = "mips")] { - if is_mips_feature_detected(...) { ... } - } - "# - ) - }; -} - -/// Prevents compilation if `is_mips64_feature_detected` is used somewhere else -/// than `MIPS64` targets. -#[cfg(not(target_arch = "mips64"))] -#[macro_export] -#[unstable(feature = "stdsimd", issue = "27731")] -macro_rules! is_mips64_feature_detected { - ($t:tt) => { - compile_error!( - r#" - is_mips64_feature_detected can only be used on MIPS64 targets. - You can prevent it from being used in other architectures by - guarding it behind a cfg(target_arch) as follows: - - #[cfg(target_arch = "mips64")] { - if is_mips64_feature_detected(...) { ... } - } - "# - ) - }; -} diff --git a/crates/std_detect/src/detect/macros.rs b/crates/std_detect/src/detect/macros.rs index b83fe71c41..fa7189336a 100644 --- a/crates/std_detect/src/detect/macros.rs +++ b/crates/std_detect/src/detect/macros.rs @@ -2,6 +2,7 @@ macro_rules! features { ( @TARGET: $target:ident; + @CFG: $cfg:meta; @MACRO_NAME: $macro_name:ident; @MACRO_ATTRS: $(#[$macro_attrs:meta])* $(@BIND_FEATURE_NAME: $bind_feature:tt; $feature_impl:tt; )* @@ -11,6 +12,8 @@ macro_rules! features { #[macro_export] $(#[$macro_attrs])* #[allow_internal_unstable(stdsimd_internal)] + #[cfg($cfg)] + #[doc(cfg($cfg))] macro_rules! $macro_name { $( ($feature_lit) => { @@ -44,6 +47,50 @@ macro_rules! features { }; } + $(#[$macro_attrs])* + #[macro_export] + #[cfg(not($cfg))] + #[doc(cfg($cfg))] + macro_rules! $macro_name { + $( + ($feature_lit) => { + compile_error!( + concat!( + r#"This macro cannot be used on the current target. + You can prevent it from being used in other architectures by + guarding it behind a cfg("#, + stringify!($cfg), + ")." + ) + ) + }; + )* + $( + ($bind_feature) => { $macro_name!($feature_impl) }; + )* + $( + ($nort_feature) => { + compile_error!( + concat!( + stringify!($nort_feature), + " feature cannot be detected at run-time" + ) + ) + }; + )* + ($t:tt,) => { + $macro_name!($t); + }; + ($t:tt) => { + compile_error!( + concat!( + concat!("unknown ", stringify!($target)), + concat!(" target feature: ", $t) + ) + ) + }; + } + /// Each variant denotes a position in a bitset for a particular feature. /// /// PLEASE: do not use this, it is an implementation detail subject @@ -53,6 +100,7 @@ macro_rules! features { #[derive(Copy, Clone)] #[repr(u8)] #[unstable(feature = "stdsimd_internal", issue = "none")] + #[cfg($cfg)] pub(crate) enum Feature { $( $(#[$feature_comment])* @@ -63,6 +111,7 @@ macro_rules! features { _last } + #[cfg($cfg)] impl Feature { pub(crate) fn to_str(self) -> &'static str { match self { @@ -86,6 +135,7 @@ macro_rules! features { /// PLEASE: do not use this, it is an implementation detail subject /// to change. #[doc(hidden)] + #[cfg($cfg)] pub mod __is_feature_detected { $( diff --git a/crates/std_detect/src/detect/mod.rs b/crates/std_detect/src/detect/mod.rs index 7937417f52..2bca84ca12 100644 --- a/crates/std_detect/src/detect/mod.rs +++ b/crates/std_detect/src/detect/mod.rs @@ -19,109 +19,10 @@ use cfg_if::cfg_if; -#[cfg(not(doc))] -#[macro_use] -mod error_macros; - #[macro_use] mod macros; -cfg_if! { - if #[cfg(doc)] { - // When building docs, emit the full macro for all supported arches. - #[allow(dead_code)] - mod arch { - #[path = "x86.rs"] - #[macro_use] - mod x86; - #[path = "arm.rs"] - #[macro_use] - mod arm; - #[path = "aarch64.rs"] - #[macro_use] - mod aarch64; - #[path = "riscv.rs"] - #[macro_use] - mod riscv; - #[path = "powerpc.rs"] - #[macro_use] - mod powerpc; - #[path = "powerpc64.rs"] - #[macro_use] - mod powerpc64; - #[path = "mips.rs"] - #[macro_use] - mod mips; - #[path = "mips64.rs"] - #[macro_use] - mod mips64; - - #[doc(hidden)] - pub(crate) enum Feature { - Null - } - #[doc(hidden)] - pub mod __is_feature_detected {} - - impl Feature { - #[doc(hidden)] - pub(crate) fn from_str(_s: &str) -> Result { Err(()) } - #[doc(hidden)] - pub(crate) fn to_str(self) -> &'static str { "" } - } - } - } else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { - #[path = "arch/x86.rs"] - #[macro_use] - mod arch; - } else if #[cfg(target_arch = "arm")] { - #[path = "arch/arm.rs"] - #[macro_use] - mod arch; - } else if #[cfg(target_arch = "aarch64")] { - #[path = "arch/aarch64.rs"] - #[macro_use] - mod arch; - } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { - #[path = "arch/riscv.rs"] - #[macro_use] - mod arch; - } else if #[cfg(target_arch = "powerpc")] { - #[path = "arch/powerpc.rs"] - #[macro_use] - mod arch; - } else if #[cfg(target_arch = "powerpc64")] { - #[path = "arch/powerpc64.rs"] - #[macro_use] - mod arch; - } else if #[cfg(target_arch = "mips")] { - #[path = "arch/mips.rs"] - #[macro_use] - mod arch; - } else if #[cfg(target_arch = "mips64")] { - #[path = "arch/mips64.rs"] - #[macro_use] - mod arch; - } else { - // Unimplemented architecture: - #[allow(dead_code)] - mod arch { - #[doc(hidden)] - pub(crate) enum Feature { - Null - } - #[doc(hidden)] - pub mod __is_feature_detected {} - - impl Feature { - #[doc(hidden)] - pub(crate) fn from_str(_s: &str) -> Result { Err(()) } - #[doc(hidden)] - pub(crate) fn to_str(self) -> &'static str { "" } - } - } - } -} +mod arch; // This module needs to be public because the `is_{arch}_feature_detected!` // macros expand calls to items within it in user crates.