Nicholas Nethercote ddf10db1a3 Fix the features macro.
The first rule of the `features` macro looks like this:
```
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; $(#[$deprecate_attr:meta];)?)*
      $(@NO_RUNTIME_DETECTION: $nort_feature:tt; )*
      $(@FEATURE: #[$stability_attr:meta] $feature:ident: $feature_lit:tt;
          $(without cfg check: $feature_cfg_check:literal;)?
          $(implied by target_features: [$($target_feature_lit:tt),*];)?
          $(#[$feature_comment:meta])*)*
    ) => {
```
Notice all the `tt` specifiers. They are used because they are forwarded
to another macro. Only `ident`, `lifetime`, and `tt` specifiers can be
forwarded this way.

But there is an exception: `$feature_lit:tt`, which was added recently.
In theory it should cause an error like this:
```
error: no rules expected `literal` metavariable
   --> /home/njn/dev/rust3/library/stdarch/crates/std_detect/src/detect/macros.rs:54:91
    |
51  | /         macro_rules! $macro_name {
52  | |             $(
53  | |                 ($feature_lit) => {
54  | |                     $crate::detect_feature!($feature, $feature_lit $(, without cfg check: $feature_cfg_check)? ...
    | |                                                                                           ^^^^^^^^^^^^^^^^^^ no rules expected this token in macro call
...   |
88  | |             };
89  | |         }
    | |_________- in this expansion of `is_x86_feature_detected!`
    |
   ::: std/tests/run-time-detect.rs:145:27
    |
145 |       println!("tsc: {:?}", is_x86_feature_detected!("tsc"));
    |                             ------------------------------- in this macro invocation
    |
note: while trying to match keyword `true`
   --> /home/njn/dev/rust3/library/stdarch/crates/std_detect/src/detect/macros.rs:12:55
    |
12  |     ($feature:tt, $feature_lit:tt, without cfg check: true) => {
    |                                                       ^^^^
    = note: captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens
    = note: see <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment> for more information
```
(The URL at the end of the error has more details about this forwarding
limitation.)

In practice it doesn't cause this error. I'm not sure why, but the
existing macro implementation in rustc is far from perfect, so it's
believable that it does the wrong thing here.

Why does this matter? Because https://github.com/rust-lang/rust/pull/124141
is modifying the macro implementation, and when that PR is applied the
error *does* occur. (It's one of several cases I have found where the
existing compiler accepts code it shouldn't, but #124141 causes that
code to be rejected.)

Fortunately the fix is simple: replace the `literal` specifier with `tt`.
2024-11-30 21:32:50 +00:00
..
2024-11-30 21:32:50 +00:00
2019-01-22 18:49:24 +01:00
2019-01-22 18:49:24 +01:00

std::detect - Rust's standard library run-time CPU feature detection

The private std::detect module implements run-time feature detection in Rust's standard library. This allows detecting whether the CPU the binary runs on supports certain features, like SIMD instructions.

Usage

std::detect APIs are available as part of libstd. Prefer using it via the standard library than through this crate. Unstable features of std::detect are available on nightly Rust behind various feature-gates.

If you need run-time feature detection in #[no_std] environments, Rust core library cannot help you. By design, Rust core is platform independent, but performing run-time feature detection requires a certain level of cooperation from the platform.

You can then manually include std_detect as a dependency to get similar run-time feature detection support than the one offered by Rust's standard library. We intend to make std_detect more flexible and configurable in this regard to better serve the needs of #[no_std] targets.

Features

  • std_detect_dlsym_getauxval (enabled by default, requires libc): Enable to use libc::dlsym to query whether getauxval is linked into the binary. When this is not the case, this feature allows other fallback methods to perform run-time feature detection. When this feature is disabled, std_detect assumes that getauxval is linked to the binary. If that is not the case the behavior is undefined.

    Note: This feature is ignored on *-linux-gnu* and *-android* targets because we can safely assume getauxval is linked to the binary.

  • std_detect_file_io (enabled by default, requires std): Enable to perform run-time feature detection using file APIs (e.g. /proc/cpuinfo, etc.) if other more performant methods fail. This feature requires libstd as a dependency, preventing the crate from working on applications in which std is not available.

Platform support

  • All x86/x86_64 targets are supported on all platforms by querying the cpuid instruction directly for the features supported by the hardware and the operating system. std_detect assumes that the binary is an user-space application. If you need raw support for querying cpuid, consider using the cupid crate.

  • Linux/Android:

    • arm{32, 64}, mips{32,64}{,el}, powerpc{32,64}{,le}, riscv{32,64}, loongarch64: std_detect supports these on Linux by querying ELF auxiliary vectors (using getauxval when available), and if that fails, by querying /proc/cpuinfo.
    • arm64: partial support for doing run-time feature detection by directly querying mrs is implemented for Linux >= 4.11, but not enabled by default.
  • FreeBSD:

    • arm32, powerpc64: std_detect supports these on FreeBSD by querying ELF auxiliary vectors using sysctl.
    • arm64: run-time feature detection is implemented by directly querying mrs.
  • OpenBSD:

    • arm64: run-time feature detection is implemented by querying sysctl.
  • Windows:

    • arm64: run-time feature detection is implemented by querying IsProcessorFeaturePresent.

License

This project is licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in std_detect by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.