From 938b6dd0e1a8c7f1827ba00d8b4705fb4650d4ae Mon Sep 17 00:00:00 2001
From: gnzlbg <gonzalobg88@gmail.com>
Date: Tue, 23 Apr 2019 15:51:20 +0200
Subject: [PATCH 1/5] Add std_detect::detect::features() -> impl
 Iterator<Item=(&'static str, bool)> API

---
 crates/std_detect/src/detect/arch/aarch64.rs  | 114 +----
 crates/std_detect/src/detect/arch/arm.rs      |  46 +-
 crates/std_detect/src/detect/arch/mips.rs     |  32 +-
 crates/std_detect/src/detect/arch/mips64.rs   |  32 +-
 crates/std_detect/src/detect/arch/powerpc.rs  |  45 +-
 .../std_detect/src/detect/arch/powerpc64.rs   |  45 +-
 crates/std_detect/src/detect/arch/x86.rs      | 406 +++++-------------
 crates/std_detect/src/detect/macros.rs        |  74 ++++
 crates/std_detect/src/detect/mod.rs           |  36 ++
 crates/std_detect/src/detect/os/x86.rs        |  11 +-
 crates/std_detect/tests/cpu-detection.rs      |  31 +-
 11 files changed, 314 insertions(+), 558 deletions(-)
 create mode 100644 crates/std_detect/src/detect/macros.rs

diff --git a/crates/std_detect/src/detect/arch/aarch64.rs b/crates/std_detect/src/detect/arch/aarch64.rs
index ebae2bd285..73e54052b8 100644
--- a/crates/std_detect/src/detect/arch/aarch64.rs
+++ b/crates/std_detect/src/detect/arch/aarch64.rs
@@ -1,106 +1,36 @@
 //! Aarch64 run-time features.
 
-/// Checks if `aarch64` feature is enabled.
-#[macro_export]
-#[unstable(feature = "stdsimd", issue = "27731")]
-#[allow_internal_unstable(stdsimd_internal,stdsimd)]
-macro_rules! is_aarch64_feature_detected {
-    ("neon") => {
-        // FIXME: this should be removed once we rename Aarch64 neon to asimd
-        cfg!(target_feature = "neon") ||
-            $crate::detect::check_for($crate::detect::Feature::asimd)
-    };
-    ("asimd") => {
-        cfg!(target_feature = "neon") ||
-            $crate::detect::check_for($crate::detect::Feature::asimd)
-    };
-    ("pmull") => {
-        cfg!(target_feature = "pmull") ||
-            $crate::detect::check_for($crate::detect::Feature::pmull)
-    };
-    ("fp") => {
-        cfg!(target_feature = "fp") ||
-            $crate::detect::check_for($crate::detect::Feature::fp)
-    };
-    ("fp16") => {
-        cfg!(target_feature = "fp16") ||
-            $crate::detect::check_for($crate::detect::Feature::fp16)
-    };
-    ("sve") => {
-        cfg!(target_feature = "sve") ||
-            $crate::detect::check_for($crate::detect::Feature::sve)
-    };
-    ("crc") => {
-        cfg!(target_feature = "crc") ||
-            $crate::detect::check_for($crate::detect::Feature::crc)
-    };
-    ("crypto") => {
-        cfg!(target_feature = "crypto") ||
-            $crate::detect::check_for($crate::detect::Feature::crypto)
-    };
-    ("lse") => {
-        cfg!(target_feature = "lse") ||
-            $crate::detect::check_for($crate::detect::Feature::lse)
-    };
-    ("rdm") => {
-        cfg!(target_feature = "rdm") ||
-            $crate::detect::check_for($crate::detect::Feature::rdm)
-    };
-    ("rcpc") => {
-        cfg!(target_feature = "rcpc") ||
-            $crate::detect::check_for($crate::detect::Feature::rcpc)
-    };
-    ("dotprod") => {
-        cfg!(target_feature = "dotprod") ||
-            $crate::detect::check_for($crate::detect::Feature::dotprod)
-    };
-    ("ras") => {
-        compile_error!("\"ras\" feature cannot be detected at run-time")
-    };
-    ("v8.1a") => {
-        compile_error!("\"v8.1a\" feature cannot be detected at run-time")
-    };
-    ("v8.2a") => {
-        compile_error!("\"v8.2a\" feature cannot be detected at run-time")
-    };
-    ("v8.3a") => {
-        compile_error!("\"v8.3a\" feature cannot be detected at run-time")
-    };
-    ($t:tt,) => {
-        is_aarch64_feature_detected!($t);
-    };
-    ($t:tt) => { compile_error!(concat!("unknown aarch64 target feature: ", $t)) };
-}
-
-/// ARM Aarch64 CPU Feature enum. Each variant denotes a position in a bitset
-/// for a particular feature.
-///
-/// PLEASE: do not use this, it is an implementation detail subject to change.
-#[doc(hidden)]
-#[allow(non_camel_case_types)]
-#[repr(u8)]
-#[unstable(feature = "stdsimd_internal", issue = "0")]
-pub enum Feature {
+features! {
+    @TARGET: aarch64;
+    @MACRO_NAME: is_aarch64_feature_detected;
+    @MACRO_ATTRS:
+    /// Checks if `aarch64` feature is enabled.
+    #[unstable(feature = "stdsimd", issue = "27731")]
+    @BIND_FEATURE_NAME: "asimd"; "neon";
+    @NO_RUNTIME_DETECTION: "ras";
+    @NO_RUNTIME_DETECTION: "v8.1a";
+    @NO_RUNTIME_DETECTION: "v8.2a";
+    @NO_RUNTIME_DETECTION: "v8.3a";
+    @FEATURE: asimd: "neon";
     /// ARM Advanced SIMD (ASIMD)
-    asimd,
+    @FEATURE: pmull: "pmull";
     /// Polynomial Multiply
-    pmull,
+    @FEATURE: fp: "fp";
     /// Floating point support
-    fp,
+    @FEATURE: fp16: "fp16";
     /// Half-float support.
-    fp16,
+    @FEATURE: sve: "sve";
     /// Scalable Vector Extension (SVE)
-    sve,
+    @FEATURE: crc: "crc";
     /// CRC32 (Cyclic Redundancy Check)
-    crc,
+    @FEATURE: crypto: "crypto";
     /// Crypto: AES + PMULL + SHA1 + SHA2
-    crypto,
+    @FEATURE: lse: "lse";
     /// Atomics (Large System Extension)
-    lse,
+    @FEATURE: rdm: "rdm";
     /// Rounding Double Multiply (ASIMDRDM)
-    rdm,
+    @FEATURE: rcpc: "rcpc";
     /// Release consistent Processor consistent (RcPc)
-    rcpc,
+    @FEATURE: dotprod: "dotprod";
     /// Vector Dot-Product (ASIMDDP)
-    dotprod,
 }
diff --git a/crates/std_detect/src/detect/arch/arm.rs b/crates/std_detect/src/detect/arch/arm.rs
index b2626bf292..86dc6dbbf2 100644
--- a/crates/std_detect/src/detect/arch/arm.rs
+++ b/crates/std_detect/src/detect/arch/arm.rs
@@ -1,39 +1,17 @@
 //! Run-time feature detection on ARM Aarch32.
 
-/// Checks if `arm` feature is enabled.
-#[macro_export]
-#[unstable(feature = "stdsimd", issue = "27731")]
-#[allow_internal_unstable(stdsimd_internal,stdsimd)]
-macro_rules! is_arm_feature_detected {
-    ("neon") => {
-        cfg!(target_feature = "neon") ||
-            $crate::detect::check_for($crate::detect::Feature::neon)
-    };
-    ("pmull") => {
-        cfg!(target_feature = "pmull") ||
-            $crate::detect::check_for($crate::detect::Feature::pmull)
-    };
-    ("v7") => { compile_error!("\"v7\" feature cannot be detected at run-time") };
-    ("vfp2") => { compile_error!("\"vfp2\" feature cannot be detected at run-time") };
-    ("vfp3") => { compile_error!("\"vfp3\" feature cannot be detected at run-time") };
-    ("vfp4") => { compile_error!("\"vfp4\" feature cannot be detected at run-time") };
-    ($t:tt,) => {
-        is_arm_feature_detected!($t);
-    };
-    ($t:tt) => { compile_error!(concat!("unknown arm target feature: ", $t)) };
-}
-
-/// ARM CPU Feature enum. Each variant denotes a position in a bitset for a
-/// particular feature.
-///
-/// PLEASE: do not use this, it is an implementation detail subject to change.
-#[doc(hidden)]
-#[allow(non_camel_case_types)]
-#[repr(u8)]
-#[unstable(feature = "stdsimd_internal", issue = "0")]
-pub enum Feature {
+features! {
+    @TARGET: arm;
+    @MACRO_NAME: is_arm_feature_detected;
+    @MACRO_ATTRS:
+    /// Checks if `arm` feature is enabled.
+    #[unstable(feature = "stdsimd", issue = "27731")]
+    @NO_RUNTIME_DETECTION: "v7";
+    @NO_RUNTIME_DETECTION: "vfp2";
+    @NO_RUNTIME_DETECTION: "vfp3";
+    @NO_RUNTIME_DETECTION: "vfp4";
+    @FEATURE: neon: "neon";
     /// ARM Advanced SIMD (NEON) - Aarch32
-    neon,
+    @FEATURE: pmull: "pmull";
     /// Polynomial Multiply
-    pmull,
 }
diff --git a/crates/std_detect/src/detect/arch/mips.rs b/crates/std_detect/src/detect/arch/mips.rs
index f4381b811c..1ac540ef73 100644
--- a/crates/std_detect/src/detect/arch/mips.rs
+++ b/crates/std_detect/src/detect/arch/mips.rs
@@ -1,29 +1,11 @@
 //! Run-time feature detection on MIPS.
 
-/// Checks if `mips` feature is enabled.
-#[macro_export]
-#[unstable(feature = "stdsimd", issue = "27731")]
-#[allow_internal_unstable(stdsimd_internal,stdsimd)]
-macro_rules! is_mips_feature_detected {
-    ("msa") => {
-        cfg!(target_feature = "msa") ||
-            $crate::detect::check_for($crate::detect::Feature::msa)
-    };
-    ($t:tt,) => {
-        is_mips_feature_detected!($t);
-    };
-    ($t:tt) => { compile_error!(concat!("unknown mips target feature: ", $t)) };
-}
-
-/// MIPS CPU Feature enum. Each variant denotes a position in a bitset for a
-/// particular feature.
-///
-/// PLEASE: do not use this, it is an implementation detail subject to change.
-#[doc(hidden)]
-#[allow(non_camel_case_types)]
-#[repr(u8)]
-#[unstable(feature = "stdsimd_internal", issue = "0")]
-pub enum Feature {
+features! {
+    @TARGET: mips;
+    @MACRO_NAME: is_mips_feature_detected;
+    @MACRO_ATTRS:
+    /// Checks if `mips` feature is enabled.
+    #[unstable(feature = "stdsimd", issue = "27731")]
+    @FEATURE: msa: "msa";
     /// MIPS SIMD Architecture (MSA)
-    msa,
 }
diff --git a/crates/std_detect/src/detect/arch/mips64.rs b/crates/std_detect/src/detect/arch/mips64.rs
index 2663bc68ba..33ad3bca76 100644
--- a/crates/std_detect/src/detect/arch/mips64.rs
+++ b/crates/std_detect/src/detect/arch/mips64.rs
@@ -1,29 +1,11 @@
 //! Run-time feature detection on MIPS64.
 
-/// Checks if `mips64` feature is enabled.
-#[macro_export]
-#[unstable(feature = "stdsimd", issue = "27731")]
-#[allow_internal_unstable(stdsimd_internal,stdsimd)]
-macro_rules! is_mips64_feature_detected {
-    ("msa") => {
-        cfg!(target_feature = "msa") ||
-            $crate::detect::check_for($crate::detect::Feature::msa)
-    };
-    ($t:tt,) => {
-        is_mips64_feature_detected!($t);
-    };
-    ($t:tt) => { compile_error!(concat!("unknown mips64 target feature: ", $t)) };
-}
-
-/// MIPS64 CPU Feature enum. Each variant denotes a position in a bitset
-/// for a particular feature.
-///
-/// PLEASE: do not use this, it is an implementation detail subject to change.
-#[doc(hidden)]
-#[allow(non_camel_case_types)]
-#[repr(u8)]
-#[unstable(feature = "stdsimd_internal", issue = "0")]
-pub enum Feature {
+features! {
+    @TARGET: mips64;
+    @MACRO_NAME: is_mips64_feature_detected;
+    @MACRO_ATTRS:
+    /// Checks if `mips64` feature is enabled.
+    #[unstable(feature = "stdsimd", issue = "27731")]
+    @FEATURE: msa: "msa";
     /// MIPS SIMD Architecture (MSA)
-    msa,
 }
diff --git a/crates/std_detect/src/detect/arch/powerpc.rs b/crates/std_detect/src/detect/arch/powerpc.rs
index a342dc1aac..6cc35a2411 100644
--- a/crates/std_detect/src/detect/arch/powerpc.rs
+++ b/crates/std_detect/src/detect/arch/powerpc.rs
@@ -1,42 +1,15 @@
 //! Run-time feature detection on PowerPC.
 
-/// Checks if `powerpc` feature is enabled.
-#[macro_export]
-#[unstable(feature = "stdsimd", issue = "27731")]
-#[allow_internal_unstable(stdsimd_internal,stdsimd)]
-macro_rules! is_powerpc_feature_detected {
-    ("altivec") => {
-        cfg!(target_feature = "altivec") ||
-            $crate::detect::check_for($crate::detect::Feature::altivec)
-    };
-    ("vsx") => {
-        cfg!(target_feature = "vsx") ||
-            $crate::detect::check_for($crate::detect::Feature::vsx)
-    };
-    ("power8") => {
-        cfg!(target_feature = "power8") ||
-            $crate::detect::check_for($crate::detect::Feature::power8)
-    };
-    ($t:tt,) => {
-        is_powerpc_feature_detected!($t);
-    };
-    ($t:tt) => { compile_error!(concat!("unknown powerpc target feature: ", $t)) };
-}
-
-
-/// PowerPC CPU Feature enum. Each variant denotes a position in a bitset
-/// for a particular feature.
-///
-/// PLEASE: do not use this, it is an implementation detail subject to change.
-#[doc(hidden)]
-#[allow(non_camel_case_types)]
-#[repr(u8)]
-#[unstable(feature = "stdsimd_internal", issue = "0")]
-pub enum Feature {
+features! {
+    @TARGET: powerpc;
+    @MACRO_NAME: is_powerpc_feature_detected;
+    @MACRO_ATTRS:
+    /// Checks if `powerpc` feature is enabled.
+    #[unstable(feature = "stdsimd", issue = "27731")]
+    @FEATURE: altivec: "altivec";
     /// Altivec
-    altivec,
+    @FEATURE: vsx: "vsx";
     /// VSX
-    vsx,
+    @FEATURE: power8: "power8";
     /// Power8
-    power8,
 }
diff --git a/crates/std_detect/src/detect/arch/powerpc64.rs b/crates/std_detect/src/detect/arch/powerpc64.rs
index 2e82c56925..a075c94190 100644
--- a/crates/std_detect/src/detect/arch/powerpc64.rs
+++ b/crates/std_detect/src/detect/arch/powerpc64.rs
@@ -1,42 +1,15 @@
 //! Run-time feature detection on PowerPC64.
 
-/// Checks if `powerpc64` feature is enabled.
-#[macro_export]
-#[unstable(feature = "stdsimd", issue = "27731")]
-#[allow_internal_unstable(stdsimd_internal,stdsimd)]
-macro_rules! is_powerpc64_feature_detected {
-    ("altivec") => {
-        cfg!(target_feature = "altivec") ||
-            $crate::detect::check_for($crate::detect::Feature::altivec)
-    };
-    ("vsx") => {
-        cfg!(target_feature = "vsx") ||
-            $crate::detect::check_for($crate::detect::Feature::vsx)
-    };
-    ("power8") => {
-        cfg!(target_feature = "power8") ||
-            $crate::detect::check_for($crate::detect::Feature::power8)
-    };
-    ($t:tt,) => {
-        is_powerpc64_feature_detected!($t);
-    };
-    ($t:tt) => { compile_error!(concat!("unknown powerpc64 target feature: ", $t)) };
-}
-
-
-/// PowerPC64 CPU Feature enum. Each variant denotes a position in a bitset
-/// for a particular feature.
-///
-/// PLEASE: do not use this, it is an implementation detail subject to change.
-#[doc(hidden)]
-#[allow(non_camel_case_types)]
-#[repr(u8)]
-#[unstable(feature = "stdsimd_internal", issue = "0")]
-pub enum Feature {
+features! {
+    @TARGET: powerpc64;
+    @MACRO_NAME: is_powerpc64_feature_detected;
+    @MACRO_ATTRS:
+    /// Checks if `powerpc` feature is enabled.
+    #[unstable(feature = "stdsimd", issue = "27731")]
+    @FEATURE: altivec: "altivec";
     /// Altivec
-    altivec,
+    @FEATURE: vsx: "vsx";
     /// VSX
-    vsx,
+    @FEATURE: power8: "power8";
     /// Power8
-    power8,
 }
diff --git a/crates/std_detect/src/detect/arch/x86.rs b/crates/std_detect/src/detect/arch/x86.rs
index 50d5cfa87c..470b8978db 100644
--- a/crates/std_detect/src/detect/arch/x86.rs
+++ b/crates/std_detect/src/detect/arch/x86.rs
@@ -15,334 +15,154 @@
 //! in a global `AtomicUsize` variable. The query is performed by just checking
 //! whether the feature bit in this global variable is set or cleared.
 
-/// A macro to test at *runtime* whether a CPU feature is available on
-/// x86/x86-64 platforms.
-///
-/// This macro is provided in the standard library and will detect at runtime
-/// whether the specified CPU feature is detected. This does **not** resolve at
-/// compile time unless the specified feature is already enabled for the entire
-/// crate. Runtime detection currently relies mostly on the `cpuid` instruction.
-///
-/// This macro only takes one argument which is a string literal of the feature
-/// being tested for. The feature names supported are the lowercase versions of
-/// the ones defined by Intel in [their documentation][docs].
-///
-/// ## Supported arguments
-///
-/// This macro supports the same names that `#[target_feature]` supports. Unlike
-/// `#[target_feature]`, however, this macro does not support names separated
-/// with a comma. Instead testing for multiple features must be done through
-/// separate macro invocations for now.
-///
-/// Supported arguments are:
-///
-/// * `"aes"`
-/// * `"pclmulqdq"`
-/// * `"rdrand"`
-/// * `"rdseed"`
-/// * `"tsc"`
-/// * `"mmx"`
-/// * `"sse"`
-/// * `"sse2"`
-/// * `"sse3"`
-/// * `"ssse3"`
-/// * `"sse4.1"`
-/// * `"sse4.2"`
-/// * `"sse4a"`
-/// * `"sha"`
-/// * `"avx"`
-/// * `"avx2"`
-/// * `"avx512f"`
-/// * `"avx512cd"`
-/// * `"avx512er"`
-/// * `"avx512pf"`
-/// * `"avx512bw"`
-/// * `"avx512dq"`
-/// * `"avx512vl"`
-/// * `"avx512ifma"`
-/// * `"avx512vbmi"`
-/// * `"avx512vpopcntdq"`
-/// * `"f16c"`
-/// * `"fma"`
-/// * `"bmi1"`
-/// * `"bmi2"`
-/// * `"abm"`
-/// * `"lzcnt"`
-/// * `"tbm"`
-/// * `"popcnt"`
-/// * `"fxsr"`
-/// * `"xsave"`
-/// * `"xsaveopt"`
-/// * `"xsaves"`
-/// * `"xsavec"`
-/// * `"adx"`
-/// * `"rtm"`
-///
-/// [docs]: https://software.intel.com/sites/landingpage/IntrinsicsGuide
-#[macro_export]
-#[stable(feature = "simd_x86", since = "1.27.0")]
-#[allow_internal_unstable(stdsimd_internal,stdsimd)]
-macro_rules! is_x86_feature_detected {
-    ("aes") => {
-        cfg!(target_feature = "aes") || $crate::detect::check_for(
-            $crate::detect::Feature::aes)  };
-    ("pclmulqdq") => {
-        cfg!(target_feature = "pclmulqdq") || $crate::detect::check_for(
-            $crate::detect::Feature::pclmulqdq)  };
-    ("rdrand") => {
-        cfg!(target_feature = "rdrand") || $crate::detect::check_for(
-            $crate::detect::Feature::rdrand)  };
-    ("rdseed") => {
-        cfg!(target_feature = "rdseed") || $crate::detect::check_for(
-            $crate::detect::Feature::rdseed)  };
-    ("tsc") => {
-        cfg!(target_feature = "tsc") || $crate::detect::check_for(
-            $crate::detect::Feature::tsc)  };
-    ("mmx") => {
-        cfg!(target_feature = "mmx") || $crate::detect::check_for(
-            $crate::detect::Feature::mmx)  };
-    ("sse") => {
-        cfg!(target_feature = "sse") || $crate::detect::check_for(
-            $crate::detect::Feature::sse)  };
-    ("sse2") => {
-        cfg!(target_feature = "sse2") || $crate::detect::check_for(
-            $crate::detect::Feature::sse2)
-    };
-    ("sse3") => {
-        cfg!(target_feature = "sse3") || $crate::detect::check_for(
-            $crate::detect::Feature::sse3)
-    };
-    ("ssse3") => {
-        cfg!(target_feature = "ssse3") || $crate::detect::check_for(
-            $crate::detect::Feature::ssse3)
-    };
-    ("sse4.1") => {
-        cfg!(target_feature = "sse4.1") || $crate::detect::check_for(
-            $crate::detect::Feature::sse4_1)
-    };
-    ("sse4.2") => {
-        cfg!(target_feature = "sse4.2") || $crate::detect::check_for(
-            $crate::detect::Feature::sse4_2)
-    };
-    ("sse4a") => {
-        cfg!(target_feature = "sse4a") || $crate::detect::check_for(
-            $crate::detect::Feature::sse4a)
-    };
-    ("sha") => {
-        cfg!(target_feature = "sha") || $crate::detect::check_for(
-            $crate::detect::Feature::sha)
-    };
-    ("avx") => {
-        cfg!(target_feature = "avx") || $crate::detect::check_for(
-            $crate::detect::Feature::avx)
-    };
-    ("avx2") => {
-        cfg!(target_feature = "avx2") || $crate::detect::check_for(
-            $crate::detect::Feature::avx2)
-    };
-    ("avx512f") => {
-        cfg!(target_feature = "avx512f") || $crate::detect::check_for(
-            $crate::detect::Feature::avx512f)
-    };
-    ("avx512cd") => {
-        cfg!(target_feature = "avx512cd") || $crate::detect::check_for(
-            $crate::detect::Feature::avx512cd)
-    };
-    ("avx512er") => {
-        cfg!(target_feature = "avx512er") || $crate::detect::check_for(
-            $crate::detect::Feature::avx512er)
-    };
-    ("avx512pf") => {
-        cfg!(target_feature = "avx512pf") || $crate::detect::check_for(
-            $crate::detect::Feature::avx512pf)
-    };
-    ("avx512bw") => {
-        cfg!(target_feature = "avx512bw") || $crate::detect::check_for(
-            $crate::detect::Feature::avx512bw)
-    };
-    ("avx512dq") => {
-        cfg!(target_feature = "avx512dq") || $crate::detect::check_for(
-            $crate::detect::Feature::avx512dq)
-    };
-    ("avx512vl") => {
-        cfg!(target_Feature = "avx512vl") || $crate::detect::check_for(
-            $crate::detect::Feature::avx512vl)
-    };
-    ("avx512ifma") => {
-        cfg!(target_feature = "avx512ifma") || $crate::detect::check_for(
-            $crate::detect::Feature::avx512_ifma)
-    };
-    ("avx512vbmi") => {
-        cfg!(target_feature = "avx512vbmi") || $crate::detect::check_for(
-            $crate::detect::Feature::avx512_vbmi)
-    };
-    ("avx512vpopcntdq") => {
-        cfg!(target_feature = "avx512vpopcntdq") || $crate::detect::check_for(
-            $crate::detect::Feature::avx512_vpopcntdq)
-    };
-    ("f16c") => {
-        cfg!(target_feature = "f16c") || $crate::detect::check_for(
-            $crate::detect::Feature::f16c)
-    };
-    ("fma") => {
-        cfg!(target_feature = "fma") || $crate::detect::check_for(
-            $crate::detect::Feature::fma)
-    };
-    ("bmi1") => {
-        cfg!(target_feature = "bmi1") || $crate::detect::check_for(
-            $crate::detect::Feature::bmi)
-    };
-    ("bmi2") => {
-        cfg!(target_feature = "bmi2") || $crate::detect::check_for(
-            $crate::detect::Feature::bmi2)
-    };
-    ("abm") => {
-        cfg!(target_feature = "abm") || $crate::detect::check_for(
-            $crate::detect::Feature::abm)
-    };
-    ("lzcnt") => {
-        cfg!(target_feature = "lzcnt") || $crate::detect::check_for(
-            $crate::detect::Feature::abm)
-    };
-    ("tbm") => {
-        cfg!(target_feature = "tbm") || $crate::detect::check_for(
-            $crate::detect::Feature::tbm)
-    };
-    ("popcnt") => {
-        cfg!(target_feature = "popcnt") || $crate::detect::check_for(
-            $crate::detect::Feature::popcnt)
-    };
-    ("fxsr") => {
-        cfg!(target_feature = "fxsr") || $crate::detect::check_for(
-            $crate::detect::Feature::fxsr)
-    };
-    ("xsave") => {
-        cfg!(target_feature = "xsave") || $crate::detect::check_for(
-            $crate::detect::Feature::xsave)
-    };
-    ("xsaveopt") => {
-        cfg!(target_feature = "xsaveopt") || $crate::detect::check_for(
-            $crate::detect::Feature::xsaveopt)
-    };
-    ("xsaves") => {
-        cfg!(target_feature = "xsaves") || $crate::detect::check_for(
-            $crate::detect::Feature::xsaves)
-    };
-    ("xsavec") => {
-        cfg!(target_feature = "xsavec") || $crate::detect::check_for(
-            $crate::detect::Feature::xsavec)
-    };
-    ("cmpxchg16b") => {
-        cfg!(target_feature = "cmpxchg16b") || $crate::detect::check_for(
-            $crate::detect::Feature::cmpxchg16b)
-    };
-    ("adx") => {
-        cfg!(target_feature = "adx") || $crate::detect::check_for(
-            $crate::detect::Feature::adx)
-    };
-    ("rtm") => {
-        cfg!(target_feature = "rtm") || $crate::detect::check_for(
-            $crate::detect::Feature::rtm)
-    };
-    ($t:tt,) => {
-        is_x86_feature_detected!($t);
-    };
-    ($t:tt) => {
-        compile_error!(concat!("unknown target feature: ", $t))
-    };
-}
-
-/// X86 CPU Feature enum. Each variant denotes a position in a bitset for a
-/// particular feature.
-///
-/// This is an unstable implementation detail subject to change.
-#[allow(non_camel_case_types)]
-#[repr(u8)]
-#[doc(hidden)]
-#[unstable(feature = "stdsimd_internal", issue = "0")]
-pub enum Feature {
+features! {
+    @TARGET: x86;
+    @MACRO_NAME: is_x86_feature_detected;
+    @MACRO_ATTRS:
+    /// A macro to test at *runtime* whether a CPU feature is available on
+    /// x86/x86-64 platforms.
+    ///
+    /// This macro is provided in the standard library and will detect at runtime
+    /// whether the specified CPU feature is detected. This does **not** resolve at
+    /// compile time unless the specified feature is already enabled for the entire
+    /// crate. Runtime detection currently relies mostly on the `cpuid` instruction.
+    ///
+    /// This macro only takes one argument which is a string literal of the feature
+    /// being tested for. The feature names supported are the lowercase versions of
+    /// the ones defined by Intel in [their documentation][docs].
+    ///
+    /// ## Supported arguments
+    ///
+    /// This macro supports the same names that `#[target_feature]` supports. Unlike
+    /// `#[target_feature]`, however, this macro does not support names separated
+    /// with a comma. Instead testing for multiple features must be done through
+    /// separate macro invocations for now.
+    ///
+    /// Supported arguments are:
+    ///
+    /// * `"aes"`
+    /// * `"pclmulqdq"`
+    /// * `"rdrand"`
+    /// * `"rdseed"`
+    /// * `"tsc"`
+    /// * `"mmx"`
+    /// * `"sse"`
+    /// * `"sse2"`
+    /// * `"sse3"`
+    /// * `"ssse3"`
+    /// * `"sse4.1"`
+    /// * `"sse4.2"`
+    /// * `"sse4a"`
+    /// * `"sha"`
+    /// * `"avx"`
+    /// * `"avx2"`
+    /// * `"avx512f"`
+    /// * `"avx512cd"`
+    /// * `"avx512er"`
+    /// * `"avx512pf"`
+    /// * `"avx512bw"`
+    /// * `"avx512dq"`
+    /// * `"avx512vl"`
+    /// * `"avx512ifma"`
+    /// * `"avx512vbmi"`
+    /// * `"avx512vpopcntdq"`
+    /// * `"fma"`
+    /// * `"bmi1"`
+    /// * `"bmi2"`
+    /// * `"abm"`
+    /// * `"lzcnt"`
+    /// * `"tbm"`
+    /// * `"popcnt"`
+    /// * `"fxsr"`
+    /// * `"xsave"`
+    /// * `"xsaveopt"`
+    /// * `"xsaves"`
+    /// * `"xsavec"`
+    ///
+    /// [docs]: https://software.intel.com/sites/landingpage/IntrinsicsGuide
+    #[stable(feature = "simd_x86", since = "1.27.0")]
+    @BIND_FEATURE_NAME: "abm"; "lzcnt"; // abm is a synonym for lzcnt
+    @FEATURE: aes: "aes";
     /// AES (Advanced Encryption Standard New Instructions AES-NI)
-    aes,
+    @FEATURE: pclmulqdq: "pclmulqdq";
     /// CLMUL (Carry-less Multiplication)
-    pclmulqdq,
+    @FEATURE: rdrand: "rdrand";
     /// RDRAND
-    rdrand,
+    @FEATURE: rdseed: "rdseed";
     /// RDSEED
-    rdseed,
+    @FEATURE: tsc: "tsc";
     /// TSC (Time Stamp Counter)
-    tsc,
-    /// MMX
-    mmx,
+    @FEATURE: mmx: "mmx";
+    /// MMX (MultiMedia eXtensions)
+    @FEATURE: sse: "sse";
     /// SSE (Streaming SIMD Extensions)
-    sse,
+    @FEATURE: sse2: "sse2";
     /// SSE2 (Streaming SIMD Extensions 2)
-    sse2,
+    @FEATURE: sse3: "sse3";
     /// SSE3 (Streaming SIMD Extensions 3)
-    sse3,
+    @FEATURE: ssse3: "ssse3";
     /// SSSE3 (Supplemental Streaming SIMD Extensions 3)
-    ssse3,
+    @FEATURE: sse4_1: "sse4.1";
     /// SSE4.1 (Streaming SIMD Extensions 4.1)
-    sse4_1,
+    @FEATURE: sse4_2: "sse4.2";
     /// SSE4.2 (Streaming SIMD Extensions 4.2)
-    sse4_2,
+    @FEATURE: sse4a: "sse4a";
     /// SSE4a (Streaming SIMD Extensions 4a)
-    sse4a,
+    @FEATURE: sha: "sha";
     /// SHA
-    sha,
+    @FEATURE: avx: "avx";
     /// AVX (Advanced Vector Extensions)
-    avx,
+    @FEATURE: avx2: "avx2";
     /// AVX2 (Advanced Vector Extensions 2)
-    avx2,
+    @FEATURE: avx512f: "avx512f" ;
     /// AVX-512 F (Foundation)
-    avx512f,
+    @FEATURE: avx512cd: "avx512cd" ;
     /// AVX-512 CD (Conflict Detection Instructions)
-    avx512cd,
-    /// AVX-512 ER (Exponential and Reciprocal Instructions)
-    avx512er,
+    @FEATURE: avx512er: "avx512er";
+    /// AVX-512 ER (Expo nential and Reciprocal Instructions)
+    @FEATURE: avx512pf: "avx512pf";
     /// AVX-512 PF (Prefetch Instructions)
-    avx512pf,
+    @FEATURE: avx512bw: "avx512bw";
     /// AVX-512 BW (Byte and Word Instructions)
-    avx512bw,
+    @FEATURE: avx512dq: "avx512dq";
     /// AVX-512 DQ (Doubleword and Quadword)
-    avx512dq,
+    @FEATURE: avx512vl: "avx512vl";
     /// AVX-512 VL (Vector Length Extensions)
-    avx512vl,
+    @FEATURE: avx512ifma: "avx512ifma";
     /// AVX-512 IFMA (Integer Fused Multiply Add)
-    avx512_ifma,
+    @FEATURE: avx512vbmi: "avx512vbmi";
     /// AVX-512 VBMI (Vector Byte Manipulation Instructions)
-    avx512_vbmi,
+    @FEATURE: avx512vpopcntdq: "avx512vpopcntdq";
     /// AVX-512 VPOPCNTDQ (Vector Population Count Doubleword and
     /// Quadword)
-    avx512_vpopcntdq,
+    @FEATURE: f16c: "f16c";
     /// F16C (Conversions between IEEE-754 `binary16` and `binary32` formats)
-    f16c,
+    @FEATURE: fma: "fma";
     /// FMA (Fused Multiply Add)
-    fma,
+    @FEATURE: bmi1: "bmi1" ;
     /// BMI1 (Bit Manipulation Instructions 1)
-    bmi,
-    /// BMI1 (Bit Manipulation Instructions 2)
-    bmi2,
-    /// ABM (Advanced Bit Manipulation) on AMD / LZCNT (Leading Zero
-    /// Count) on Intel
-    abm,
+    @FEATURE: bmi2: "bmi2" ;
+    /// BMI2 (Bit Manipulation Instructions 2)
+    @FEATURE: lzcnt: "lzcnt";
+    /// ABM (Advanced Bit Manipulation) / LZCNT (Leading Zero Count)
+    @FEATURE: tbm: "tbm";
     /// TBM (Trailing Bit Manipulation)
-    tbm,
+    @FEATURE: popcnt: "popcnt";
     /// POPCNT (Population Count)
-    popcnt,
+    @FEATURE: fxsr: "fxsr";
     /// FXSR (Floating-point context fast save and restor)
-    fxsr,
+    @FEATURE: xsave: "xsave";
     /// XSAVE (Save Processor Extended States)
-    xsave,
+    @FEATURE: xsaveopt: "xsaveopt";
     /// XSAVEOPT (Save Processor Extended States Optimized)
-    xsaveopt,
+    @FEATURE: xsaves: "xsaves";
     /// XSAVES (Save Processor Extended States Supervisor)
-    xsaves,
+    @FEATURE: xsavec: "xsavec";
     /// XSAVEC (Save Processor Extended States Compacted)
-    xsavec,
-    /// CMPXCH16B, a 16-byte compare-and-swap instruction
-    cmpxchg16b,
+    @FEATURE: cmpxchg16b: "cmpxchg16b";
+    /// CMPXCH16B (16-byte compare-and-swap instruction)
+    @FEATURE: adx: "adx";
     /// ADX, Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
-    adx,
+    @FEATURE: rtm: "rtm";
     /// RTM, Intel (Restricted Transactional Memory)
-    rtm,
 }
diff --git a/crates/std_detect/src/detect/macros.rs b/crates/std_detect/src/detect/macros.rs
new file mode 100644
index 0000000000..09f9f524b5
--- /dev/null
+++ b/crates/std_detect/src/detect/macros.rs
@@ -0,0 +1,74 @@
+macro_rules! features {
+    (
+      @TARGET: $target:ident;
+      @MACRO_NAME: $macro_name:ident;
+      @MACRO_ATTRS: $(#[$macro_attrs:meta])*
+      $(@BIND_FEATURE_NAME: $bind_feature:tt; $feature_impl:tt; )*
+      $(@NO_RUNTIME_DETECTION: $nort_feature:tt; )*
+      $(@FEATURE: $feature:ident: $feature_lit:tt; $(#[$feature_comment:meta])*)*
+    ) => {
+        #[macro_export]
+        $(#[$macro_attrs])*
+        #[allow_internal_unstable(stdsimd_internal,stdsimd)]
+        macro_rules! $macro_name {
+            $(
+                ($feature_lit) => {
+                    cfg!(target_feature = $feature_lit) ||
+                        $crate::detect::check_for($crate::detect::Feature::$feature)
+                };
+            )*
+            $(
+                ($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
+        /// to change.
+        #[doc(hidden)]
+        #[allow(non_camel_case_types)]
+        #[derive(Copy, Clone)]
+        #[repr(u8)]
+        #[unstable(feature = "stdsimd_internal", issue = "0")]
+        pub enum Feature {
+            $(
+                $(#[$feature_comment])*
+                $feature,
+            )*
+
+            // Do not add variants after last:
+            _last
+        }
+
+        impl Feature {
+            pub fn to_str(self) -> &'static str {
+                match self {
+                    $(Feature::$feature => $feature_lit,)*
+                    Feature::_last => unreachable!(),
+                }
+            }
+        }
+    };
+}
diff --git a/crates/std_detect/src/detect/mod.rs b/crates/std_detect/src/detect/mod.rs
index 3e00c20554..21062782b7 100644
--- a/crates/std_detect/src/detect/mod.rs
+++ b/crates/std_detect/src/detect/mod.rs
@@ -20,6 +20,9 @@
 #[macro_use]
 mod error_macros;
 
+#[macro_use]
+mod macros;
+
 cfg_if! {
     if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
         #[path = "arch/x86.rs"]
@@ -96,3 +99,36 @@ cfg_if! {
 pub fn check_for(x: Feature) -> bool {
     cache::test(x as u32, self::os::detect_features)
 }
+
+/// Returns an `Iterator<Item=(&'static str, bool)>` where
+/// `Item.0` is the feature name, and `Item.1` is a `bool` which
+/// is `true` if the feature is supported by the host and `false` otherwise.
+#[unstable(feature = "stdsimd", issue = "27731")]
+pub fn features() -> impl Iterator<Item = (&'static str, bool)> {
+    cfg_if! {
+        if #[cfg(any(
+            target_arch = "x86",
+            target_arch = "x86_64",
+            target_arch = "arm",
+            target_arch = "aarch64",
+            target_arch = "powerpc",
+            target_arch = "powerpc64",
+            target_arch = "mips",
+            target_arch = "mips64",
+        ))] {
+            fn impl_() -> impl Iterator<Item=(&'static str, bool)> {
+                (0_u8..Feature::_last as u8).map(|discriminant: u8| {
+                    let f: Feature = unsafe { crate::mem::transmute(discriminant) };
+                    let name: &'static str = f.to_str();
+                    let enabled: bool = check_for(f);
+                    (name, enabled)
+                })
+            }
+        } else {
+            fn impl_() -> impl Iterator<Item=(&'static str, bool)> {
+                (0_u8..0_u8).map(|_x: u8| ("", false))
+            }
+        }
+    }
+    impl_()
+}
diff --git a/crates/std_detect/src/detect/os/x86.rs b/crates/std_detect/src/detect/os/x86.rs
index d9d286071a..6daeb2d1a1 100644
--- a/crates/std_detect/src/detect/os/x86.rs
+++ b/crates/std_detect/src/detect/os/x86.rs
@@ -126,7 +126,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
         enable(proc_info_edx, 26, Feature::sse2);
         enable(extended_features_ebx, 29, Feature::sha);
 
-        enable(extended_features_ebx, 3, Feature::bmi);
+        enable(extended_features_ebx, 3, Feature::bmi1);
         enable(extended_features_ebx, 8, Feature::bmi2);
 
         // `XSAVE` and `AVX` support:
@@ -203,17 +203,17 @@ pub(crate) fn detect_features() -> cache::Initializer {
                     if os_avx512_support {
                         enable(extended_features_ebx, 16, Feature::avx512f);
                         enable(extended_features_ebx, 17, Feature::avx512dq);
-                        enable(extended_features_ebx, 21, Feature::avx512_ifma);
+                        enable(extended_features_ebx, 21, Feature::avx512ifma);
                         enable(extended_features_ebx, 26, Feature::avx512pf);
                         enable(extended_features_ebx, 27, Feature::avx512er);
                         enable(extended_features_ebx, 28, Feature::avx512cd);
                         enable(extended_features_ebx, 30, Feature::avx512bw);
                         enable(extended_features_ebx, 31, Feature::avx512vl);
-                        enable(extended_features_ecx, 1, Feature::avx512_vbmi);
+                        enable(extended_features_ecx, 1, Feature::avx512vbmi);
                         enable(
                             extended_features_ecx,
                             14,
-                            Feature::avx512_vpopcntdq,
+                            Feature::avx512vpopcntdq,
                         );
                     }
                 }
@@ -227,7 +227,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
         //
         // The `is_x86_feature_detected!("lzcnt")` macro then
         // internally maps to Feature::abm.
-        enable(extended_proc_info_ecx, 5, Feature::abm);
+        enable(extended_proc_info_ecx, 5, Feature::lzcnt);
+
         // As Hygon Dhyana originates from AMD technology and shares most of the architecture with
         // AMD's family 17h, but with different CPU Vendor ID("HygonGenuine")/Family series
         // number(Family 18h).
diff --git a/crates/std_detect/tests/cpu-detection.rs b/crates/std_detect/tests/cpu-detection.rs
index d0c9901c4c..d441f4e1ef 100644
--- a/crates/std_detect/tests/cpu-detection.rs
+++ b/crates/std_detect/tests/cpu-detection.rs
@@ -1,7 +1,6 @@
 #![feature(stdsimd)]
 #![allow(clippy::option_unwrap_used, clippy::use_debug, clippy::print_stdout)]
-
-#[cfg(any(
+#![cfg(any(
     target_arch = "arm",
     target_arch = "aarch64",
     target_arch = "x86",
@@ -9,9 +8,17 @@
     target_arch = "powerpc",
     target_arch = "powerpc64"
 ))]
+
 #[macro_use]
 extern crate std_detect;
 
+#[test]
+fn all() {
+    for (f, e) in std_detect::detect::features() {
+        println!("{}: {}", f, e);
+    }
+}
+
 #[test]
 #[cfg(all(target_arch = "arm", any(target_os = "linux", target_os = "android")))]
 fn arm_linux() {
@@ -73,17 +80,17 @@ fn x86_all() {
     println!("sha: {:?}", is_x86_feature_detected!("sha"));
     println!("avx: {:?}", is_x86_feature_detected!("avx"));
     println!("avx2: {:?}", is_x86_feature_detected!("avx2"));
-    println!("avx512f {:?}", is_x86_feature_detected!("avx512f"));
-    println!("avx512cd {:?}", is_x86_feature_detected!("avx512cd"));
-    println!("avx512er {:?}", is_x86_feature_detected!("avx512er"));
-    println!("avx512pf {:?}", is_x86_feature_detected!("avx512pf"));
-    println!("avx512bw {:?}", is_x86_feature_detected!("avx512bw"));
-    println!("avx512dq {:?}", is_x86_feature_detected!("avx512dq"));
-    println!("avx512vl {:?}", is_x86_feature_detected!("avx512vl"));
-    println!("avx512_ifma {:?}", is_x86_feature_detected!("avx512ifma"));
-    println!("avx512_vbmi {:?}", is_x86_feature_detected!("avx512vbmi"));
+    println!("avx512f: {:?}", is_x86_feature_detected!("avx512f"));
+    println!("avx512cd: {:?}", is_x86_feature_detected!("avx512cd"));
+    println!("avx512er: {:?}", is_x86_feature_detected!("avx512er"));
+    println!("avx512pf: {:?}", is_x86_feature_detected!("avx512pf"));
+    println!("avx512bw: {:?}", is_x86_feature_detected!("avx512bw"));
+    println!("avx512dq: {:?}", is_x86_feature_detected!("avx512dq"));
+    println!("avx512vl: {:?}", is_x86_feature_detected!("avx512vl"));
+    println!("avx512ifma: {:?}", is_x86_feature_detected!("avx512ifma"));
+    println!("avx512vbmi: {:?}", is_x86_feature_detected!("avx512vbmi"));
     println!(
-        "avx512_vpopcntdq {:?}",
+        "avx512vpopcntdq: {:?}",
         is_x86_feature_detected!("avx512vpopcntdq")
     );
     println!("f16c: {:?}", is_x86_feature_detected!("f16c"));

From 6166128ab506b6646170e9763629aeae9939618b Mon Sep 17 00:00:00 2001
From: gnzlbg <gonzalobg88@gmail.com>
Date: Mon, 16 Sep 2019 16:56:12 +0200
Subject: [PATCH 2/5] Enforce staged_api on a per-feature basis

---
 crates/std_detect/src/detect/arch/aarch64.rs  | 22 ++---
 crates/std_detect/src/detect/arch/arm.rs      |  4 +-
 crates/std_detect/src/detect/arch/mips.rs     |  2 +-
 crates/std_detect/src/detect/arch/mips64.rs   |  2 +-
 crates/std_detect/src/detect/arch/powerpc.rs  |  6 +-
 .../std_detect/src/detect/arch/powerpc64.rs   |  6 +-
 crates/std_detect/src/detect/arch/x86.rs      | 82 +++++++++----------
 crates/std_detect/src/detect/macros.rs        | 28 ++++++-
 crates/std_detect/src/detect/mod.rs           |  2 +-
 9 files changed, 87 insertions(+), 67 deletions(-)

diff --git a/crates/std_detect/src/detect/arch/aarch64.rs b/crates/std_detect/src/detect/arch/aarch64.rs
index 73e54052b8..154207e5ad 100644
--- a/crates/std_detect/src/detect/arch/aarch64.rs
+++ b/crates/std_detect/src/detect/arch/aarch64.rs
@@ -11,26 +11,26 @@ features! {
     @NO_RUNTIME_DETECTION: "v8.1a";
     @NO_RUNTIME_DETECTION: "v8.2a";
     @NO_RUNTIME_DETECTION: "v8.3a";
-    @FEATURE: asimd: "neon";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] asimd: "neon";
     /// ARM Advanced SIMD (ASIMD)
-    @FEATURE: pmull: "pmull";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] pmull: "pmull";
     /// Polynomial Multiply
-    @FEATURE: fp: "fp";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] fp: "fp";
     /// Floating point support
-    @FEATURE: fp16: "fp16";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] fp16: "fp16";
     /// Half-float support.
-    @FEATURE: sve: "sve";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sve: "sve";
     /// Scalable Vector Extension (SVE)
-    @FEATURE: crc: "crc";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] crc: "crc";
     /// CRC32 (Cyclic Redundancy Check)
-    @FEATURE: crypto: "crypto";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] crypto: "crypto";
     /// Crypto: AES + PMULL + SHA1 + SHA2
-    @FEATURE: lse: "lse";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] lse: "lse";
     /// Atomics (Large System Extension)
-    @FEATURE: rdm: "rdm";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] rdm: "rdm";
     /// Rounding Double Multiply (ASIMDRDM)
-    @FEATURE: rcpc: "rcpc";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] rcpc: "rcpc";
     /// Release consistent Processor consistent (RcPc)
-    @FEATURE: dotprod: "dotprod";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] dotprod: "dotprod";
     /// Vector Dot-Product (ASIMDDP)
 }
diff --git a/crates/std_detect/src/detect/arch/arm.rs b/crates/std_detect/src/detect/arch/arm.rs
index 86dc6dbbf2..02bf654945 100644
--- a/crates/std_detect/src/detect/arch/arm.rs
+++ b/crates/std_detect/src/detect/arch/arm.rs
@@ -10,8 +10,8 @@ features! {
     @NO_RUNTIME_DETECTION: "vfp2";
     @NO_RUNTIME_DETECTION: "vfp3";
     @NO_RUNTIME_DETECTION: "vfp4";
-    @FEATURE: neon: "neon";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] neon: "neon";
     /// ARM Advanced SIMD (NEON) - Aarch32
-    @FEATURE: pmull: "pmull";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] pmull: "pmull";
     /// Polynomial Multiply
 }
diff --git a/crates/std_detect/src/detect/arch/mips.rs b/crates/std_detect/src/detect/arch/mips.rs
index 1ac540ef73..ada81b83ec 100644
--- a/crates/std_detect/src/detect/arch/mips.rs
+++ b/crates/std_detect/src/detect/arch/mips.rs
@@ -6,6 +6,6 @@ features! {
     @MACRO_ATTRS:
     /// Checks if `mips` feature is enabled.
     #[unstable(feature = "stdsimd", issue = "27731")]
-    @FEATURE: msa: "msa";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] msa: "msa";
     /// MIPS SIMD Architecture (MSA)
 }
diff --git a/crates/std_detect/src/detect/arch/mips64.rs b/crates/std_detect/src/detect/arch/mips64.rs
index 33ad3bca76..6a0bb159ba 100644
--- a/crates/std_detect/src/detect/arch/mips64.rs
+++ b/crates/std_detect/src/detect/arch/mips64.rs
@@ -6,6 +6,6 @@ features! {
     @MACRO_ATTRS:
     /// Checks if `mips64` feature is enabled.
     #[unstable(feature = "stdsimd", issue = "27731")]
-    @FEATURE: msa: "msa";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] msa: "msa";
     /// MIPS SIMD Architecture (MSA)
 }
diff --git a/crates/std_detect/src/detect/arch/powerpc.rs b/crates/std_detect/src/detect/arch/powerpc.rs
index 6cc35a2411..44bd7f337f 100644
--- a/crates/std_detect/src/detect/arch/powerpc.rs
+++ b/crates/std_detect/src/detect/arch/powerpc.rs
@@ -6,10 +6,10 @@ features! {
     @MACRO_ATTRS:
     /// Checks if `powerpc` feature is enabled.
     #[unstable(feature = "stdsimd", issue = "27731")]
-    @FEATURE: altivec: "altivec";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] altivec: "altivec";
     /// Altivec
-    @FEATURE: vsx: "vsx";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] vsx: "vsx";
     /// VSX
-    @FEATURE: power8: "power8";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] power8: "power8";
     /// Power8
 }
diff --git a/crates/std_detect/src/detect/arch/powerpc64.rs b/crates/std_detect/src/detect/arch/powerpc64.rs
index a075c94190..17e4d958bf 100644
--- a/crates/std_detect/src/detect/arch/powerpc64.rs
+++ b/crates/std_detect/src/detect/arch/powerpc64.rs
@@ -6,10 +6,10 @@ features! {
     @MACRO_ATTRS:
     /// Checks if `powerpc` feature is enabled.
     #[unstable(feature = "stdsimd", issue = "27731")]
-    @FEATURE: altivec: "altivec";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] altivec: "altivec";
     /// Altivec
-    @FEATURE: vsx: "vsx";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] vsx: "vsx";
     /// VSX
-    @FEATURE: power8: "power8";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] power8: "power8";
     /// Power8
 }
diff --git a/crates/std_detect/src/detect/arch/x86.rs b/crates/std_detect/src/detect/arch/x86.rs
index 470b8978db..ae0bebdae5 100644
--- a/crates/std_detect/src/detect/arch/x86.rs
+++ b/crates/std_detect/src/detect/arch/x86.rs
@@ -82,87 +82,87 @@ features! {
     /// [docs]: https://software.intel.com/sites/landingpage/IntrinsicsGuide
     #[stable(feature = "simd_x86", since = "1.27.0")]
     @BIND_FEATURE_NAME: "abm"; "lzcnt"; // abm is a synonym for lzcnt
-    @FEATURE: aes: "aes";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] aes: "aes";
     /// AES (Advanced Encryption Standard New Instructions AES-NI)
-    @FEATURE: pclmulqdq: "pclmulqdq";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] pclmulqdq: "pclmulqdq";
     /// CLMUL (Carry-less Multiplication)
-    @FEATURE: rdrand: "rdrand";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")]  rdrand: "rdrand";
     /// RDRAND
-    @FEATURE: rdseed: "rdseed";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] rdseed: "rdseed";
     /// RDSEED
-    @FEATURE: tsc: "tsc";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] tsc: "tsc";
     /// TSC (Time Stamp Counter)
-    @FEATURE: mmx: "mmx";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] mmx: "mmx";
     /// MMX (MultiMedia eXtensions)
-    @FEATURE: sse: "sse";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sse: "sse";
     /// SSE (Streaming SIMD Extensions)
-    @FEATURE: sse2: "sse2";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sse2: "sse2";
     /// SSE2 (Streaming SIMD Extensions 2)
-    @FEATURE: sse3: "sse3";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sse3: "sse3";
     /// SSE3 (Streaming SIMD Extensions 3)
-    @FEATURE: ssse3: "ssse3";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] ssse3: "ssse3";
     /// SSSE3 (Supplemental Streaming SIMD Extensions 3)
-    @FEATURE: sse4_1: "sse4.1";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sse4_1: "sse4.1";
     /// SSE4.1 (Streaming SIMD Extensions 4.1)
-    @FEATURE: sse4_2: "sse4.2";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sse4_2: "sse4.2";
     /// SSE4.2 (Streaming SIMD Extensions 4.2)
-    @FEATURE: sse4a: "sse4a";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sse4a: "sse4a";
     /// SSE4a (Streaming SIMD Extensions 4a)
-    @FEATURE: sha: "sha";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sha: "sha";
     /// SHA
-    @FEATURE: avx: "avx";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx: "avx";
     /// AVX (Advanced Vector Extensions)
-    @FEATURE: avx2: "avx2";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx2: "avx2";
     /// AVX2 (Advanced Vector Extensions 2)
-    @FEATURE: avx512f: "avx512f" ;
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] avx512f: "avx512f" ;
     /// AVX-512 F (Foundation)
-    @FEATURE: avx512cd: "avx512cd" ;
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] avx512cd: "avx512cd" ;
     /// AVX-512 CD (Conflict Detection Instructions)
-    @FEATURE: avx512er: "avx512er";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] avx512er: "avx512er";
     /// AVX-512 ER (Expo nential and Reciprocal Instructions)
-    @FEATURE: avx512pf: "avx512pf";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] avx512pf: "avx512pf";
     /// AVX-512 PF (Prefetch Instructions)
-    @FEATURE: avx512bw: "avx512bw";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] avx512bw: "avx512bw";
     /// AVX-512 BW (Byte and Word Instructions)
-    @FEATURE: avx512dq: "avx512dq";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] avx512dq: "avx512dq";
     /// AVX-512 DQ (Doubleword and Quadword)
-    @FEATURE: avx512vl: "avx512vl";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] avx512vl: "avx512vl";
     /// AVX-512 VL (Vector Length Extensions)
-    @FEATURE: avx512ifma: "avx512ifma";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] avx512ifma: "avx512ifma";
     /// AVX-512 IFMA (Integer Fused Multiply Add)
-    @FEATURE: avx512vbmi: "avx512vbmi";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] avx512vbmi: "avx512vbmi";
     /// AVX-512 VBMI (Vector Byte Manipulation Instructions)
-    @FEATURE: avx512vpopcntdq: "avx512vpopcntdq";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] avx512vpopcntdq: "avx512vpopcntdq";
     /// AVX-512 VPOPCNTDQ (Vector Population Count Doubleword and
     /// Quadword)
-    @FEATURE: f16c: "f16c";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] f16c: "f16c";
     /// F16C (Conversions between IEEE-754 `binary16` and `binary32` formats)
-    @FEATURE: fma: "fma";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] fma: "fma";
     /// FMA (Fused Multiply Add)
-    @FEATURE: bmi1: "bmi1" ;
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] bmi1: "bmi1" ;
     /// BMI1 (Bit Manipulation Instructions 1)
-    @FEATURE: bmi2: "bmi2" ;
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] bmi2: "bmi2" ;
     /// BMI2 (Bit Manipulation Instructions 2)
-    @FEATURE: lzcnt: "lzcnt";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] lzcnt: "lzcnt";
     /// ABM (Advanced Bit Manipulation) / LZCNT (Leading Zero Count)
-    @FEATURE: tbm: "tbm";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] tbm: "tbm";
     /// TBM (Trailing Bit Manipulation)
-    @FEATURE: popcnt: "popcnt";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] popcnt: "popcnt";
     /// POPCNT (Population Count)
-    @FEATURE: fxsr: "fxsr";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] fxsr: "fxsr";
     /// FXSR (Floating-point context fast save and restor)
-    @FEATURE: xsave: "xsave";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] xsave: "xsave";
     /// XSAVE (Save Processor Extended States)
-    @FEATURE: xsaveopt: "xsaveopt";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] xsaveopt: "xsaveopt";
     /// XSAVEOPT (Save Processor Extended States Optimized)
-    @FEATURE: xsaves: "xsaves";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] xsaves: "xsaves";
     /// XSAVES (Save Processor Extended States Supervisor)
-    @FEATURE: xsavec: "xsavec";
+    @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] xsavec: "xsavec";
     /// XSAVEC (Save Processor Extended States Compacted)
-    @FEATURE: cmpxchg16b: "cmpxchg16b";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] cmpxchg16b: "cmpxchg16b";
     /// CMPXCH16B (16-byte compare-and-swap instruction)
-    @FEATURE: adx: "adx";
+    @FEATURE: #[stable(feature = "simd_x86_adx", since = "1.33.0")] adx: "adx";
     /// ADX, Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
-    @FEATURE: rtm: "rtm";
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] rtm: "rtm";
     /// RTM, Intel (Restricted Transactional Memory)
 }
diff --git a/crates/std_detect/src/detect/macros.rs b/crates/std_detect/src/detect/macros.rs
index 09f9f524b5..8fc8b2b406 100644
--- a/crates/std_detect/src/detect/macros.rs
+++ b/crates/std_detect/src/detect/macros.rs
@@ -5,16 +5,15 @@ macro_rules! features {
       @MACRO_ATTRS: $(#[$macro_attrs:meta])*
       $(@BIND_FEATURE_NAME: $bind_feature:tt; $feature_impl:tt; )*
       $(@NO_RUNTIME_DETECTION: $nort_feature:tt; )*
-      $(@FEATURE: $feature:ident: $feature_lit:tt; $(#[$feature_comment:meta])*)*
+      $(@FEATURE: #[$stability_attr:meta] $feature:ident: $feature_lit:tt; $(#[$feature_comment:meta])*)*
     ) => {
         #[macro_export]
         $(#[$macro_attrs])*
-        #[allow_internal_unstable(stdsimd_internal,stdsimd)]
+        #[allow_internal_unstable(stdsimd_internal,stdsimd,staged_api)]
         macro_rules! $macro_name {
             $(
                 ($feature_lit) => {
-                    cfg!(target_feature = $feature_lit) ||
-                        $crate::detect::check_for($crate::detect::Feature::$feature)
+                    $crate::detect::__is_feature_detected::$feature()
                 };
             )*
             $(
@@ -70,5 +69,26 @@ macro_rules! features {
                 }
             }
         }
+
+        /// Each function performs run-time feature detection for a single
+        /// feature. This allow us to use stability attributes on a per feature
+        /// basis.
+        ///
+        /// PLEASE: do not use this, it is an implementation detail subject
+        /// to change.
+        #[doc(hidden)]
+        pub mod __is_feature_detected {
+            $(
+
+                /// PLEASE: do not use this, it is an implementation detail
+                /// subject to change.
+                #[doc(hidden)]
+                #[$stability_attr]
+                pub fn $feature() -> bool {
+                    cfg!(target_feature = $feature_lit) ||
+                        $crate::detect::check_for($crate::detect::Feature::$feature)
+                }
+            )*
+        }
     };
 }
diff --git a/crates/std_detect/src/detect/mod.rs b/crates/std_detect/src/detect/mod.rs
index 21062782b7..04db5c402e 100644
--- a/crates/std_detect/src/detect/mod.rs
+++ b/crates/std_detect/src/detect/mod.rs
@@ -61,7 +61,7 @@ cfg_if! {
         }
     }
 }
-pub use self::arch::Feature;
+pub use self::arch::{Feature, __is_feature_detected};
 
 mod bit;
 mod cache;

From ed03c6093515c5273f4a0421c0b078d9d7d40bc5 Mon Sep 17 00:00:00 2001
From: gnzlbg <gonzalobg88@gmail.com>
Date: Mon, 16 Sep 2019 17:42:00 +0200
Subject: [PATCH 3/5] Format

---
 crates/core_arch/src/mips/msa.rs              |   6 +-
 crates/std_detect/src/detect/os/aarch64.rs    |  19 ++-
 .../std_detect/src/detect/os/freebsd/arm.rs   |   4 +-
 .../src/detect/os/freebsd/auxvec.rs           |  36 +++--
 .../src/detect/os/freebsd/powerpc.rs          |   4 +-
 .../std_detect/src/detect/os/linux/aarch64.rs |  21 +--
 crates/std_detect/src/detect/os/linux/arm.rs  |   9 +-
 .../std_detect/src/detect/os/linux/auxvec.rs  |  33 ++---
 .../std_detect/src/detect/os/linux/cpuinfo.rs |   5 +-
 crates/std_detect/src/detect/os/linux/mips.rs |   2 +-
 .../std_detect/src/detect/os/linux/powerpc.rs |   2 +-
 crates/std_detect/src/detect/os/x86.rs        |  26 ++--
 crates/stdarch-test/src/disassembly.rs        | 139 ++++++++----------
 crates/stdarch-test/src/wasm.rs               |   3 +-
 14 files changed, 155 insertions(+), 154 deletions(-)

diff --git a/crates/core_arch/src/mips/msa.rs b/crates/core_arch/src/mips/msa.rs
index f93bcdbae7..29009b5d7c 100644
--- a/crates/core_arch/src/mips/msa.rs
+++ b/crates/core_arch/src/mips/msa.rs
@@ -13531,7 +13531,7 @@ mod tests {
     #[simd_test(enable = "msa")]
     unsafe fn test_msa_frint_w() {
         #[rustfmt::skip]
-        let a = f32x4::new(2.6, -2.7, 1.3, -1.7);;
+        let a = f32x4::new(2.6, -2.7, 1.3, -1.7);
         #[rustfmt::skip]
         let r = f32x4::new(3.0, -3.0, 1.0, -2.0);
 
@@ -13551,7 +13551,7 @@ mod tests {
     #[simd_test(enable = "msa")]
     unsafe fn test_msa_frcp_w() {
         #[rustfmt::skip]
-        let a = f32x4::new(2.6, -2.7, 1.3, -1.7);;
+        let a = f32x4::new(2.6, -2.7, 1.3, -1.7);
         #[rustfmt::skip]
         let r = f32x4::new(
             0.3846154, -0.37037036, 
@@ -13574,7 +13574,7 @@ mod tests {
     #[simd_test(enable = "msa")]
     unsafe fn test_msa_frsqrt_w() {
         #[rustfmt::skip]
-        let a = f32x4::new(2.6, 2.7, 1.3, 1.7);;
+        let a = f32x4::new(2.6, 2.7, 1.3, 1.7);
         #[rustfmt::skip]
         let r = f32x4::new(
             0.6201737, 0.6085806, 
diff --git a/crates/std_detect/src/detect/os/aarch64.rs b/crates/std_detect/src/detect/os/aarch64.rs
index dfb8c87707..9adc938a26 100644
--- a/crates/std_detect/src/detect/os/aarch64.rs
+++ b/crates/std_detect/src/detect/os/aarch64.rs
@@ -16,7 +16,7 @@
 //! - [Zircon implementation](https://fuchsia.googlesource.com/zircon/+/master/kernel/arch/arm64/feature.cpp)
 //! - [Linux documentation](https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt)
 
-use crate::detect::{Feature, cache};
+use crate::detect::{cache, Feature};
 
 /// Try to read the features from the system registers.
 ///
@@ -33,7 +33,9 @@ pub(crate) fn detect_features() -> cache::Initializer {
 
         // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0
         let aa64isar0: u64;
-        unsafe { asm!("mrs $0, ID_AA64ISAR0_EL1" : "=r"(aa64isar0)); }
+        unsafe {
+            asm!("mrs $0, ID_AA64ISAR0_EL1" : "=r"(aa64isar0));
+        }
 
         let aes = bits_shift(aa64isar0, 7, 4) >= 1;
         let pmull = bits_shift(aa64isar0, 7, 4) >= 2;
@@ -47,7 +49,9 @@ pub(crate) fn detect_features() -> cache::Initializer {
 
         // ID_AA64PFR0_EL1 - Processor Feature Register 0
         let aa64pfr0: u64;
-        unsafe { asm!("mrs $0, ID_AA64PFR0_EL1" : "=r"(aa64pfr0)); }
+        unsafe {
+            asm!("mrs $0, ID_AA64PFR0_EL1" : "=r"(aa64pfr0));
+        }
 
         let fp = bits_shift(aa64pfr0, 19, 16) < 0xF;
         let fphp = bits_shift(aa64pfr0, 19, 16) >= 1;
@@ -60,12 +64,17 @@ pub(crate) fn detect_features() -> cache::Initializer {
         enable_feature(Feature::asimd, fp && asimd && (!fphp | asimdhp));
         // SIMD extensions require SIMD support:
         enable_feature(Feature::rdm, asimd && bits_shift(aa64isar0, 31, 28) >= 1);
-        enable_feature(Feature::dotprod, asimd && bits_shift(aa64isar0, 47, 44) >= 1);
+        enable_feature(
+            Feature::dotprod,
+            asimd && bits_shift(aa64isar0, 47, 44) >= 1,
+        );
         enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1);
 
         // ID_AA64ISAR1_EL1 - Instruction Set Attribute Register 1
         let aa64isar1: u64;
-        unsafe { asm!("mrs $0, ID_AA64ISAR1_EL1" : "=r"(aa64isar1)); }
+        unsafe {
+            asm!("mrs $0, ID_AA64ISAR1_EL1" : "=r"(aa64isar1));
+        }
 
         enable_feature(Feature::rcpc, bits_shift(aa64isar1, 23, 20) >= 1);
     }
diff --git a/crates/std_detect/src/detect/os/freebsd/arm.rs b/crates/std_detect/src/detect/os/freebsd/arm.rs
index 38e37721ef..4c9d763b44 100644
--- a/crates/std_detect/src/detect/os/freebsd/arm.rs
+++ b/crates/std_detect/src/detect/os/freebsd/arm.rs
@@ -1,7 +1,7 @@
 //! Run-time feature detection for ARM on FreeBSD
 
-use crate::detect::{Feature, cache};
-use super::{auxvec};
+use super::auxvec;
+use crate::detect::{cache, Feature};
 
 /// Try to read the features from the auxiliary vector
 pub(crate) fn detect_features() -> cache::Initializer {
diff --git a/crates/std_detect/src/detect/os/freebsd/auxvec.rs b/crates/std_detect/src/detect/os/freebsd/auxvec.rs
index a2bac76760..c595ec459b 100644
--- a/crates/std_detect/src/detect/os/freebsd/auxvec.rs
+++ b/crates/std_detect/src/detect/os/freebsd/auxvec.rs
@@ -44,13 +44,13 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> {
 fn archauxv(key: usize) -> Result<usize, ()> {
     use crate::mem;
 
-    #[derive (Copy, Clone)]
+    #[derive(Copy, Clone)]
     #[repr(C)]
     pub struct Elf_Auxinfo {
         pub a_type: usize,
         pub a_un: unnamed,
     }
-    #[derive (Copy, Clone)]
+    #[derive(Copy, Clone)]
     #[repr(C)]
     pub union unnamed {
         pub a_val: libc::c_long,
@@ -58,22 +58,30 @@ fn archauxv(key: usize) -> Result<usize, ()> {
         pub a_fcn: Option<unsafe extern "C" fn() -> ()>,
     }
 
-    let mut auxv: [Elf_Auxinfo; 27] =
-        [Elf_Auxinfo{a_type: 0, a_un: unnamed{a_val: 0,},}; 27];
+    let mut auxv: [Elf_Auxinfo; 27] = [Elf_Auxinfo {
+        a_type: 0,
+        a_un: unnamed { a_val: 0 },
+    }; 27];
 
     let mut len: libc::c_uint = mem::size_of_val(&auxv) as libc::c_uint;
 
     unsafe {
-        let mut mib = [libc::CTL_KERN, libc::KERN_PROC, libc::KERN_PROC_AUXV, libc::getpid()];
-    
-        let ret = libc::sysctl(mib.as_mut_ptr(),
-                       mib.len() as u32,
-                       &mut auxv as *mut _ as *mut _,
-                       &mut len as *mut _ as *mut _,
-                       0 as *mut libc::c_void,
-                       0,
-                );
-    
+        let mut mib = [
+            libc::CTL_KERN,
+            libc::KERN_PROC,
+            libc::KERN_PROC_AUXV,
+            libc::getpid(),
+        ];
+
+        let ret = libc::sysctl(
+            mib.as_mut_ptr(),
+            mib.len() as u32,
+            &mut auxv as *mut _ as *mut _,
+            &mut len as *mut _ as *mut _,
+            0 as *mut libc::c_void,
+            0,
+        );
+
         if ret != -1 {
             for i in 0..auxv.len() {
                 if auxv[i].a_type == key {
diff --git a/crates/std_detect/src/detect/os/freebsd/powerpc.rs b/crates/std_detect/src/detect/os/freebsd/powerpc.rs
index 52a71e672a..6bfab631a9 100644
--- a/crates/std_detect/src/detect/os/freebsd/powerpc.rs
+++ b/crates/std_detect/src/detect/os/freebsd/powerpc.rs
@@ -1,7 +1,7 @@
 //! Run-time feature detection for PowerPC on FreeBSD.
 
-use crate::detect::{Feature, cache};
-use super::{auxvec};
+use super::auxvec;
+use crate::detect::{cache, Feature};
 
 pub(crate) fn detect_features() -> cache::Initializer {
     let mut value = cache::Initializer::default();
diff --git a/crates/std_detect/src/detect/os/linux/aarch64.rs b/crates/std_detect/src/detect/os/linux/aarch64.rs
index 43c0976daf..b1b68f763e 100644
--- a/crates/std_detect/src/detect/os/linux/aarch64.rs
+++ b/crates/std_detect/src/detect/os/linux/aarch64.rs
@@ -1,7 +1,7 @@
 //! Run-time feature detection for Aarch64 on Linux.
 
-use crate::detect::{Feature, cache, bit};
 use super::{auxvec, cpuinfo};
+use crate::detect::{bit, cache, Feature};
 
 /// Try to read the features from the auxiliary vector, and if that fails, try
 /// to read them from /proc/cpuinfo.
@@ -21,16 +21,16 @@ pub(crate) fn detect_features() -> cache::Initializer {
 ///
 /// [hwcap]: https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h
 struct AtHwcap {
-    fp: bool, // 0
+    fp: bool,    // 0
     asimd: bool, // 1
     // evtstrm: bool, // 2
-    aes: bool, // 3
-    pmull: bool, // 4
-    sha1: bool, // 5
-    sha2: bool, // 6
-    crc32: bool, // 7
+    aes: bool,     // 3
+    pmull: bool,   // 4
+    sha1: bool,    // 5
+    sha2: bool,    // 6
+    crc32: bool,   // 7
     atomics: bool, // 8
-    fphp: bool, // 9
+    fphp: bool,    // 9
     asimdhp: bool, // 10
     // cpuid: bool, // 11
     asimdrdm: bool, // 12
@@ -144,7 +144,10 @@ impl AtHwcap {
             enable_feature(Feature::sve, self.sve && asimd);
 
             // Crypto is specified as AES + PMULL + SHA1 + SHA2 per LLVM/hosts.cpp
-            enable_feature(Feature::crypto, self.aes && self.pmull && self.sha1 && self.sha2);
+            enable_feature(
+                Feature::crypto,
+                self.aes && self.pmull && self.sha1 && self.sha2,
+            );
         }
         value
     }
diff --git a/crates/std_detect/src/detect/os/linux/arm.rs b/crates/std_detect/src/detect/os/linux/arm.rs
index 95624e1285..a1b28dad70 100644
--- a/crates/std_detect/src/detect/os/linux/arm.rs
+++ b/crates/std_detect/src/detect/os/linux/arm.rs
@@ -1,7 +1,7 @@
 //! Run-time feature detection for ARM on Linux.
 
-use crate::detect::{Feature, cache, bit};
 use super::{auxvec, cpuinfo};
+use crate::detect::{bit, cache, Feature};
 
 /// Try to read the features from the auxiliary vector, and if that fails, try
 /// to read them from /proc/cpuinfo.
@@ -23,8 +23,11 @@ pub(crate) fn detect_features() -> cache::Initializer {
     }
 
     if let Ok(c) = cpuinfo::CpuInfo::new() {
-        enable_feature(&mut value, Feature::neon, c.field("Features").has("neon") &&
-            !has_broken_neon(&c));
+        enable_feature(
+            &mut value,
+            Feature::neon,
+            c.field("Features").has("neon") && !has_broken_neon(&c),
+        );
         enable_feature(&mut value, Feature::pmull, c.field("Features").has("pmull"));
         return value;
     }
diff --git a/crates/std_detect/src/detect/os/linux/auxvec.rs b/crates/std_detect/src/detect/os/linux/auxvec.rs
index 07b6432eaf..6ebae67fbf 100644
--- a/crates/std_detect/src/detect/os/linux/auxvec.rs
+++ b/crates/std_detect/src/detect/os/linux/auxvec.rs
@@ -51,12 +51,12 @@ pub(crate) struct AuxVec {
 /// [auxvec_h]: https://github.com/torvalds/linux/blob/master/include/uapi/linux/auxvec.h
 /// [auxv_docs]: https://docs.rs/auxv/0.3.3/auxv/
 pub(crate) fn auxv() -> Result<AuxVec, ()> {
-    #[cfg(feature = "std_detect_dlsym_getauxval")] {
+    #[cfg(feature = "std_detect_dlsym_getauxval")]
+    {
         // Try to call a dynamically-linked getauxval function.
         if let Ok(hwcap) = getauxval(AT_HWCAP) {
             // Targets with only AT_HWCAP:
-            #[cfg(any(target_arch = "aarch64", target_arch = "mips",
-                      target_arch = "mips64"))]
+            #[cfg(any(target_arch = "aarch64", target_arch = "mips", target_arch = "mips64"))]
             {
                 if hwcap != 0 {
                     return Ok(AuxVec { hwcap });
@@ -74,22 +74,24 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> {
             }
             drop(hwcap);
         }
-        #[cfg(feature = "std_detect_file_io")] {
+        #[cfg(feature = "std_detect_file_io")]
+        {
             // If calling getauxval fails, try to read the auxiliary vector from
             // its file:
             auxv_from_file("/proc/self/auxv")
         }
-        #[cfg(not(feature = "std_detect_file_io"))] {
+        #[cfg(not(feature = "std_detect_file_io"))]
+        {
             Err(())
         }
     }
 
-    #[cfg(not(feature = "std_detect_dlsym_getauxval"))] {
+    #[cfg(not(feature = "std_detect_dlsym_getauxval"))]
+    {
         let hwcap = unsafe { ffi_getauxval(AT_HWCAP) };
 
         // Targets with only AT_HWCAP:
-        #[cfg(any(target_arch = "aarch64", target_arch = "mips",
-                  target_arch = "mips64"))]
+        #[cfg(any(target_arch = "aarch64", target_arch = "mips", target_arch = "mips64"))]
         {
             if hwcap != 0 {
                 return Ok(AuxVec { hwcap });
@@ -115,10 +117,7 @@ fn getauxval(key: usize) -> Result<usize, ()> {
     use libc;
     pub type F = unsafe extern "C" fn(usize) -> usize;
     unsafe {
-        let ptr = libc::dlsym(
-            libc::RTLD_DEFAULT,
-            "getauxval\0".as_ptr() as *const _,
-        );
+        let ptr = libc::dlsym(libc::RTLD_DEFAULT, "getauxval\0".as_ptr() as *const _);
         if ptr.is_null() {
             return Err(());
         }
@@ -141,8 +140,7 @@ fn auxv_from_file(file: &str) -> Result<AuxVec, ()> {
     // 2*32 `usize` elements is enough to read the whole vector.
     let mut buf = [0_usize; 64];
     {
-        let raw: &mut [u8; 64 * mem::size_of::<usize>()] =
-            unsafe { mem::transmute(&mut buf) };
+        let raw: &mut [u8; 64 * mem::size_of::<usize>()] = unsafe { mem::transmute(&mut buf) };
         file.read(raw).map_err(|_| ())?;
     }
     auxv_from_buf(&buf)
@@ -153,8 +151,7 @@ fn auxv_from_file(file: &str) -> Result<AuxVec, ()> {
 #[cfg(feature = "std_detect_file_io")]
 fn auxv_from_buf(buf: &[usize; 64]) -> Result<AuxVec, ()> {
     // Targets with only AT_HWCAP:
-    #[cfg(any(target_arch = "aarch64", target_arch = "mips",
-              target_arch = "mips64"))]
+    #[cfg(any(target_arch = "aarch64", target_arch = "mips", target_arch = "mips64"))]
     {
         for el in buf.chunks(2) {
             match el[0] {
@@ -193,8 +190,8 @@ mod tests {
     // using the auxv crate.
     #[cfg(feature = "std_detect_file_io")]
     fn auxv_crate_getprocfs(key: usize) -> Option<usize> {
-        use self::auxv_crate::AuxvType;
         use self::auxv_crate::procfs::search_procfs_auxv;
+        use self::auxv_crate::AuxvType;
         let k = key as AuxvType;
         match search_procfs_auxv(&[k]) {
             Ok(v) => Some(v[&k] as usize),
@@ -206,8 +203,8 @@ mod tests {
     // using the auxv crate.
     #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))]
     fn auxv_crate_getauxval(key: usize) -> Option<usize> {
-        use self::auxv_crate::AuxvType;
         use self::auxv_crate::getauxval::Getauxval;
+        use self::auxv_crate::AuxvType;
         let q = auxv_crate::getauxval::NativeGetauxval {};
         match q.getauxval(key as AuxvType) {
             Ok(v) => Some(v as usize),
diff --git a/crates/std_detect/src/detect/os/linux/cpuinfo.rs b/crates/std_detect/src/detect/os/linux/cpuinfo.rs
index b316857853..f76c48a4b1 100644
--- a/crates/std_detect/src/detect/os/linux/cpuinfo.rs
+++ b/crates/std_detect/src/detect/os/linux/cpuinfo.rs
@@ -2,7 +2,7 @@
 #![cfg_attr(not(target_arch = "arm"), allow(dead_code))]
 
 extern crate std;
-use self::std::{prelude::v1::*, fs::File, io, io::Read};
+use self::std::{fs::File, io, io::Read, prelude::v1::*};
 
 /// cpuinfo
 pub(crate) struct CpuInfo {
@@ -150,8 +150,7 @@ power management:
         assert!(!cpuinfo.field("flags").has("avx"));
     }
 
-    const ARM_CORTEX_A53: &str =
-        r"Processor   : AArch64 Processor rev 3 (aarch64)
+    const ARM_CORTEX_A53: &str = r"Processor   : AArch64 Processor rev 3 (aarch64)
         processor   : 0
         processor   : 1
         processor   : 2
diff --git a/crates/std_detect/src/detect/os/linux/mips.rs b/crates/std_detect/src/detect/os/linux/mips.rs
index 6486673f80..9c030f41a0 100644
--- a/crates/std_detect/src/detect/os/linux/mips.rs
+++ b/crates/std_detect/src/detect/os/linux/mips.rs
@@ -1,7 +1,7 @@
 //! Run-time feature detection for MIPS on Linux.
 
-use crate::detect::{Feature, cache, bit};
 use super::auxvec;
+use crate::detect::{bit, cache, Feature};
 
 /// Try to read the features from the auxiliary vector, and if that fails, try
 /// to read them from `/proc/cpuinfo`.
diff --git a/crates/std_detect/src/detect/os/linux/powerpc.rs b/crates/std_detect/src/detect/os/linux/powerpc.rs
index 5be35b96dd..97afe49fe5 100644
--- a/crates/std_detect/src/detect/os/linux/powerpc.rs
+++ b/crates/std_detect/src/detect/os/linux/powerpc.rs
@@ -1,7 +1,7 @@
 //! Run-time feature detection for PowerPC on Linux.
 
-use crate::detect::{Feature, cache};
 use super::{auxvec, cpuinfo};
+use crate::detect::{cache, Feature};
 
 /// Try to read the features from the auxiliary vector, and if that fails, try
 /// to read them from /proc/cpuinfo.
diff --git a/crates/std_detect/src/detect/os/x86.rs b/crates/std_detect/src/detect/os/x86.rs
index 6daeb2d1a1..c653771c43 100644
--- a/crates/std_detect/src/detect/os/x86.rs
+++ b/crates/std_detect/src/detect/os/x86.rs
@@ -7,7 +7,7 @@ use crate::arch::x86_64::*;
 
 use crate::mem;
 
-use crate::detect::{Feature, cache, bit};
+use crate::detect::{bit, cache, Feature};
 
 /// Run-time feature detection on x86 works by using the CPUID instruction.
 ///
@@ -73,8 +73,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
 
     // EAX = 7, ECX = 0: Queries "Extended Features";
     // Contains information about bmi,bmi2, and avx2 support.
-    let (extended_features_ebx, extended_features_ecx) = if max_basic_leaf >= 7
-    {
+    let (extended_features_ebx, extended_features_ecx) = if max_basic_leaf >= 7 {
         let CpuidResult { ebx, ecx, .. } = unsafe { __cpuid(0x0000_0007_u32) };
         (ebx, ecx)
     } else {
@@ -210,11 +209,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
                         enable(extended_features_ebx, 30, Feature::avx512bw);
                         enable(extended_features_ebx, 31, Feature::avx512vl);
                         enable(extended_features_ecx, 1, Feature::avx512vbmi);
-                        enable(
-                            extended_features_ecx,
-                            14,
-                            Feature::avx512vpopcntdq,
-                        );
+                        enable(extended_features_ecx, 14, Feature::avx512vpopcntdq);
                     }
                 }
             }
@@ -304,7 +299,10 @@ mod tests {
     fn compare_with_cupid() {
         let information = cupid::master().unwrap();
         assert_eq!(is_x86_feature_detected!("aes"), information.aesni());
-        assert_eq!(is_x86_feature_detected!("pclmulqdq"), information.pclmulqdq());
+        assert_eq!(
+            is_x86_feature_detected!("pclmulqdq"),
+            information.pclmulqdq()
+        );
         assert_eq!(is_x86_feature_detected!("rdrand"), information.rdrand());
         assert_eq!(is_x86_feature_detected!("rdseed"), information.rdseed());
         assert_eq!(is_x86_feature_detected!("tsc"), information.tsc());
@@ -358,13 +356,7 @@ mod tests {
             is_x86_feature_detected!("cmpxchg16b"),
             information.cmpxchg16b(),
         );
-        assert_eq!(
-            is_x86_feature_detected!("adx"),
-            information.adx(),
-        );
-        assert_eq!(
-            is_x86_feature_detected!("rtm"),
-            information.rtm(),
-        );
+        assert_eq!(is_x86_feature_detected!("adx"), information.adx(),);
+        assert_eq!(is_x86_feature_detected!("rtm"), information.rtm(),);
     }
 }
diff --git a/crates/stdarch-test/src/disassembly.rs b/crates/stdarch-test/src/disassembly.rs
index 0decd889d2..d82b07d0a8 100644
--- a/crates/stdarch-test/src/disassembly.rs
+++ b/crates/stdarch-test/src/disassembly.rs
@@ -1,7 +1,7 @@
 //! Disassembly calling function for most targets.
 
-use std::{env, collections::HashSet, process::Command, str};
 use crate::Function;
+use std::{collections::HashSet, env, process::Command, str};
 
 // Extracts the "shim" name from the `symbol`.
 fn normalize(mut symbol: &str) -> String {
@@ -38,63 +38,56 @@ fn normalize(mut symbol: &str) -> String {
 pub(crate) fn disassemble_myself() -> HashSet<Function> {
     let me = env::current_exe().expect("failed to get current exe");
 
-    let disassembly = if cfg!(target_arch = "x86_64")
-        && cfg!(target_os = "windows")
-        && cfg!(target_env = "msvc")
-    {
-        let mut cmd = cc::windows_registry::find(
-            "x86_64-pc-windows-msvc",
-            "dumpbin.exe",
-        ).expect("failed to find `dumpbin` tool");
-        let output = cmd
-            .arg("/DISASM")
-            .arg(&me)
-            .output()
-            .expect("failed to execute dumpbin");
-        println!(
-            "{}\n{}",
-            output.status,
-            String::from_utf8_lossy(&output.stderr)
-        );
-        assert!(output.status.success());
-        // Windows does not return valid UTF-8 output:
-        String::from_utf8_lossy(Vec::leak(output.stdout))
-    } else if cfg!(target_os = "windows") {
-        panic!("disassembly unimplemented")
-    } else if cfg!(target_os = "macos") {
-        let output = Command::new("otool")
-            .arg("-vt")
-            .arg(&me)
-            .output()
-            .expect("failed to execute otool");
-        println!(
-            "{}\n{}",
-            output.status,
-            String::from_utf8_lossy(&output.stderr)
-        );
-        assert!(output.status.success());
-
-        String::from_utf8_lossy(Vec::leak(output.stdout))
-    } else {
-        let objdump =
-            env::var("OBJDUMP").unwrap_or_else(|_| "objdump".to_string());
-        let output = Command::new(objdump.clone())
-            .arg("--disassemble")
-            .arg(&me)
-            .output()
-            .unwrap_or_else(|_| panic!(
-                "failed to execute objdump. OBJDUMP={}",
-                objdump
-            ));
-        println!(
-            "{}\n{}",
-            output.status,
-            String::from_utf8_lossy(&output.stderr)
-        );
-        assert!(output.status.success());
-
-        String::from_utf8_lossy(Vec::leak(output.stdout))
-    };
+    let disassembly =
+        if cfg!(target_arch = "x86_64") && cfg!(target_os = "windows") && cfg!(target_env = "msvc")
+        {
+            let mut cmd = cc::windows_registry::find("x86_64-pc-windows-msvc", "dumpbin.exe")
+                .expect("failed to find `dumpbin` tool");
+            let output = cmd
+                .arg("/DISASM")
+                .arg(&me)
+                .output()
+                .expect("failed to execute dumpbin");
+            println!(
+                "{}\n{}",
+                output.status,
+                String::from_utf8_lossy(&output.stderr)
+            );
+            assert!(output.status.success());
+            // Windows does not return valid UTF-8 output:
+            String::from_utf8_lossy(Vec::leak(output.stdout))
+        } else if cfg!(target_os = "windows") {
+            panic!("disassembly unimplemented")
+        } else if cfg!(target_os = "macos") {
+            let output = Command::new("otool")
+                .arg("-vt")
+                .arg(&me)
+                .output()
+                .expect("failed to execute otool");
+            println!(
+                "{}\n{}",
+                output.status,
+                String::from_utf8_lossy(&output.stderr)
+            );
+            assert!(output.status.success());
+
+            String::from_utf8_lossy(Vec::leak(output.stdout))
+        } else {
+            let objdump = env::var("OBJDUMP").unwrap_or_else(|_| "objdump".to_string());
+            let output = Command::new(objdump.clone())
+                .arg("--disassemble")
+                .arg(&me)
+                .output()
+                .unwrap_or_else(|_| panic!("failed to execute objdump. OBJDUMP={}", objdump));
+            println!(
+                "{}\n{}",
+                output.status,
+                String::from_utf8_lossy(&output.stderr)
+            );
+            assert!(output.status.success());
+
+            String::from_utf8_lossy(Vec::leak(output.stdout))
+        };
 
     parse(&disassembly)
 }
@@ -102,7 +95,10 @@ pub(crate) fn disassemble_myself() -> HashSet<Function> {
 fn parse(output: &str) -> HashSet<Function> {
     let mut lines = output.lines();
 
-    println!("First 100 lines of the disassembly input containing {} lines:", lines.clone().count());
+    println!(
+        "First 100 lines of the disassembly input containing {} lines:",
+        lines.clone().count()
+    );
     for line in output.lines().take(100) {
         println!("{}", line);
     }
@@ -111,7 +107,7 @@ fn parse(output: &str) -> HashSet<Function> {
     let mut cached_header = None;
     while let Some(header) = cached_header.take().or_else(|| lines.next()) {
         if !header.ends_with(':') || !header.contains("stdarch_test_shim") {
-            continue
+            continue;
         }
         eprintln!("header: {}", header);
         let symbol = normalize(header);
@@ -146,9 +142,8 @@ fn parse(output: &str) -> HashSet<Function> {
                 instruction
                     .split_whitespace()
                     .skip(1)
-                    .skip_while(|s| {
-                        s.len() == 2 && usize::from_str_radix(s, 16).is_ok()
-                    }).map(std::string::ToString::to_string)
+                    .skip_while(|s| s.len() == 2 && usize::from_str_radix(s, 16).is_ok())
+                    .map(std::string::ToString::to_string)
                     .skip_while(|s| *s == "lock") // skip x86-specific prefix
                     .collect::<Vec<String>>()
             } else {
@@ -156,20 +151,16 @@ fn parse(output: &str) -> HashSet<Function> {
                 // Each line of instructions should look like:
                 //
                 //      $rel_offset: ab cd ef 00    $instruction...
-                let expected_len
-                    = if cfg!(target_arch = "arm") || cfg!(target_arch = "aarch64") {
-                        8
-                    } else {
-                        2
-                    };
+                let expected_len = if cfg!(target_arch = "arm") || cfg!(target_arch = "aarch64") {
+                    8
+                } else {
+                    2
+                };
 
                 instruction
                     .split_whitespace()
                     .skip(1)
-                    .skip_while(|s| {
-                        s.len() == expected_len
-                            && usize::from_str_radix(s, 16).is_ok()
-                    })
+                    .skip_while(|s| s.len() == expected_len && usize::from_str_radix(s, 16).is_ok())
                     .skip_while(|s| *s == "lock") // skip x86-specific prefix
                     .map(std::string::ToString::to_string)
                     .collect::<Vec<String>>()
@@ -178,7 +169,7 @@ fn parse(output: &str) -> HashSet<Function> {
         }
         let function = Function {
             name: symbol,
-            instrs: instructions
+            instrs: instructions,
         };
         assert!(functions.insert(function));
     }
diff --git a/crates/stdarch-test/src/wasm.rs b/crates/stdarch-test/src/wasm.rs
index b31051bc68..fc4ced6282 100644
--- a/crates/stdarch-test/src/wasm.rs
+++ b/crates/stdarch-test/src/wasm.rs
@@ -42,8 +42,7 @@ pub(crate) fn disassemble_myself() -> HashSet<Function> {
     args.push(&js_shim.display().to_string().into());
     args.push(&"--enable-simd".into());
     let opts = js_sys::Object::new();
-    js_sys::Reflect::set(&opts, &"maxBuffer".into(), &(200 * 1024 * 1024).into())
-        .unwrap();
+    js_sys::Reflect::set(&opts, &"maxBuffer".into(), &(200 * 1024 * 1024).into()).unwrap();
     let output = exec_file_sync("wasm2wat", &args, &opts).to_string();
 
     let mut ret: HashSet<Function> = HashSet::new();

From ac41b05547f88db124b8e55d675a084f6bbfde83 Mon Sep 17 00:00:00 2001
From: gnzlbg <gonzalobg88@gmail.com>
Date: Mon, 16 Sep 2019 17:43:09 +0200
Subject: [PATCH 4/5] Fix windows build jobs

---
 ci/azure-install-rust.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ci/azure-install-rust.yml b/ci/azure-install-rust.yml
index feb06588f3..65743d1d46 100644
--- a/ci/azure-install-rust.yml
+++ b/ci/azure-install-rust.yml
@@ -17,7 +17,7 @@ steps:
   - script: |
       @echo on
       if not defined TOOLCHAIN set TOOLCHAIN=nightly
-      rustup update %TOOLCHAIN%-%TARGET%
+      rustup update --no-self-update %TOOLCHAIN%-%TARGET%
       rustup default %TOOLCHAIN%-%TARGET%
     displayName: Install rust (windows)
     condition: eq( variables['Agent.OS'], 'Windows_NT' )

From 28dbdb266357a2a4bf6e11d8d757651f205aa911 Mon Sep 17 00:00:00 2001
From: gnzlbg <gonzalobg88@gmail.com>
Date: Mon, 16 Sep 2019 17:58:36 +0200
Subject: [PATCH 5/5] Fix std_detect on targets without feature detection

---
 crates/std_detect/src/detect/macros.rs | 1 +
 crates/std_detect/src/detect/mod.rs    | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/crates/std_detect/src/detect/macros.rs b/crates/std_detect/src/detect/macros.rs
index 8fc8b2b406..7285f59548 100644
--- a/crates/std_detect/src/detect/macros.rs
+++ b/crates/std_detect/src/detect/macros.rs
@@ -1,3 +1,4 @@
+#[allow(unused)]
 macro_rules! features {
     (
       @TARGET: $target:ident;
diff --git a/crates/std_detect/src/detect/mod.rs b/crates/std_detect/src/detect/mod.rs
index 04db5c402e..6389a3fd75 100644
--- a/crates/std_detect/src/detect/mod.rs
+++ b/crates/std_detect/src/detect/mod.rs
@@ -55,9 +55,12 @@ cfg_if! {
     } else {
         // Unimplemented architecture:
         mod arch {
+            #[doc(hidden)]
             pub enum Feature {
                 Null
             }
+            #[doc(hidden)]
+            pub mod __is_feature_detected {}
         }
     }
 }