Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/bindgen/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 8 kB image not shown  

Quelle  features.rs

  Sprache: Rust
 

//! Contains code for selecting features

#![deny(unused_extern_crates)]
#![deny(clippy::missing_docs_in_private_items)]
#![allow(deprecated)]

use std::cmp::Ordering;
use std::io;
use std::str::FromStr;

/// This macro defines the [`RustTarget`] and [`RustFeatures`] types.
macro_rules! define_rust_targets {
    (
        Nightly => {$($nightly_feature:ident $(: #$issue:literal)?),* $(,)?} $(,)?
        $(
            $(#[$attrs:meta])*
            $variant:ident($minor:literal) => {$($feature:ident $(: #$pull:literal)?),* $(,)?},
        )*
        $(,)?
    ) => {
        /// Represents the version of the Rust language to target.
        ///
        /// To support a beta release, use the corresponding stable release.
        ///
        /// This enum will have more variants added as necessary.
        #[allow(non_camel_case_types)]
        #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
        pub enum RustTarget {
            /// Rust Nightly
            $(#[doc = concat!(
                "- [`", stringify!($nightly_feature), "`]",
                "(", $("https://github.com/rust-lang/rust/pull/", stringify!($issue),)* ")",
            )])*
            Nightly,
            $(
                #[doc = concat!("Rust 1.", stringify!($minor))]
                $(#[doc = concat!(
                    "- [`", stringify!($feature), "`]",
                    "(", $("https://github.com/rust-lang/rust/pull/", stringify!($pull),)* ")",
                )])*
                $(#[$attrs])*
                $variant,
            )*
        }

        impl RustTarget {
            fn minor(self) -> Option<u64> {
                match self {
                    $( Self::$variant => Some($minor),)*
                    Self::Nightly => None
                }
            }

            const fn stable_releases() -> [(Self, u64); [$($minor,)*].len()] {
                [$((Self::$variant, $minor),)*]
            }
        }

        #[cfg(feature = "__cli")]
        /// Strings of allowed `RustTarget` values
        pub const RUST_TARGET_STRINGS: &[&str] = &[$(concat!("1.", stringify!($minor)),)*];

        #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
        pub(cratestruct RustFeatures {
            $($(pub(crate) $feature: bool,)*)*
            $(pub(crate) $nightly_feature: bool,)*
        }

        impl From<RustTarget> for RustFeatures {
            fn from(target: RustTarget) -> Self {
                if target == RustTarget::Nightly {
                    return Self {
                        $($($feature: true,)*)*
                        $($nightly_feature: true,)*
                    };
                }

                let mut features = Self {
                    $($($feature: false,)*)*
                    $($nightly_feature: false,)*
                };

                $(if target >= RustTarget::$variant {
                    $(features.$feature = true;)*
                })*

                features
            }
        }
    };
}

// NOTE: When adding or removing features here, make sure to add the stabilization PR
// number for the feature if it has been stabilized or the tracking issue number if the feature is
// not stable.
define_rust_targets! {
    Nightly => {
        vectorcall_abi,
    },
    Stable_1_73(73) => { thiscall_abi: #42202 },
    Stable_1_71(71) => { c_unwind_abi: #106075 },
    Stable_1_68(68) => { abi_efiapi: #105795 },
    Stable_1_64(64) => { core_ffi_c: #94503 },
    Stable_1_59(59) => { const_cstr: #54745 },
    Stable_1_47(47) => { larger_arrays: #74060 },
    Stable_1_40(40) => { non_exhaustive: #44109 },
    Stable_1_36(36) => { maybe_uninit: #60445 },
    Stable_1_33(33) => { repr_packed_n: #57049 },
    #[deprecated]
    Stable_1_30(30) => {
        core_ffi_c_void: #53910,
        min_const_fn: #54835,
    },
    #[deprecated]
    Stable_1_28(28) => { repr_transparent: #51562 },
    #[deprecated]
    Stable_1_27(27) => { must_use_function: #48925 },
    #[deprecated]
    Stable_1_26(26) => { i128_and_u128: #49101 },
    #[deprecated]
    Stable_1_25(25) => { repr_align: #47006 },
    #[deprecated]
    Stable_1_21(21) => { builtin_clone_impls: #43690 },
    #[deprecated]
    Stable_1_20(20) => { associated_const: #42809 },
    #[deprecated]
    Stable_1_19(19) => { untagged_union: #42068 },
    #[deprecated]
    Stable_1_17(17) => { static_lifetime_elision: #39265 },
    #[deprecated]
    Stable_1_0(0) => {},
}

/// Latest stable release of Rust
pub const LATEST_STABLE_RUST: RustTarget = {
    // FIXME: replace all this code by
    // ```
    // RustTarget::stable_releases()
    //     .into_iter()
    //     .max_by_key(|(_, m)| m)
    //     .map(|(t, _)| t)
    //     .unwrap_or(RustTarget::Nightly)
    // ```
    // once those operations can be used in constants.
    let targets = RustTarget::stable_releases();

    let mut i = 0;
    let mut latest_target = None;
    let mut latest_minor = 0;

    while i < targets.len() {
        let (target, minor) = targets[i];

        if latest_minor < minor {
            latest_minor = minor;
            latest_target = Some(target);
        }

        i += 1;
    }

    match latest_target {
        Some(target) => target,
        None => unreachable!(),
    }
};

impl Default for RustTarget {
    fn default() -> Self {
        LATEST_STABLE_RUST
    }
}

impl PartialOrd for RustTarget {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for RustTarget {
    fn cmp(&self, other: &Self) -> Ordering {
        match (self.minor(), other.minor()) {
            (Some(a), Some(b)) => a.cmp(&b),
            (Some(_), None) => Ordering::Less,
            (None, Some(_)) => Ordering::Greater,
            (None, None) => Ordering::Equal,
        }
    }
}

impl FromStr for RustTarget {
    type Err = io::Error;

    fn from_str(s: &str) -> Result<SelfSelf::Err> {
        if s == "nightly" {
            return Ok(Self::Nightly);
        }

        if let Some(("1", str_minor)) = s.split_once('.') {
            if let Ok(minor) = str_minor.parse::<u64>() {
                for (target, target_minor) in Self::stable_releases() {
                    if minor == target_minor {
                        return Ok(target);
                    }
                }
            }
        }

        Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            "Got an invalid Rust target. Accepted values are of the form \"1.71\" or \"nightly\"."
        ))
    }
}

impl std::fmt::Display for RustTarget {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self.minor() {
            Some(minor) => write!(f, "1.{}", minor),
            None => "nightly".fmt(f),
        }
    }
}

impl Default for RustFeatures {
    fn default() -> Self {
        RustTarget::default().into()
    }
}

#[cfg(test)]
mod test {
    #![allow(unused_imports)]
    use super::*;

    #[test]
    fn target_features() {
        let f_1_0 = RustFeatures::from(RustTarget::Stable_1_0);
        assert!(
            !f_1_0.static_lifetime_elision &&
                !f_1_0.core_ffi_c_void &&
                !f_1_0.untagged_union &&
                !f_1_0.associated_const &&
                !f_1_0.builtin_clone_impls &&
                !f_1_0.repr_align &&
                !f_1_0.thiscall_abi &&
                !f_1_0.vectorcall_abi
        );
        let f_1_21 = RustFeatures::from(RustTarget::Stable_1_21);
        assert!(
            f_1_21.static_lifetime_elision &&
                !f_1_21.core_ffi_c_void &&
                f_1_21.untagged_union &&
                f_1_21.associated_const &&
                f_1_21.builtin_clone_impls &&
                !f_1_21.repr_align &&
                !f_1_21.thiscall_abi &&
                !f_1_21.vectorcall_abi
        );
        let features = RustFeatures::from(RustTarget::Stable_1_71);
        assert!(
            features.c_unwind_abi &&
                features.abi_efiapi &&
                !features.thiscall_abi
        );
        let f_nightly = RustFeatures::from(RustTarget::Nightly);
        assert!(
            f_nightly.static_lifetime_elision &&
                f_nightly.core_ffi_c_void &&
                f_nightly.untagged_union &&
                f_nightly.associated_const &&
                f_nightly.builtin_clone_impls &&
                f_nightly.maybe_uninit &&
                f_nightly.repr_align &&
                f_nightly.thiscall_abi &&
                f_nightly.vectorcall_abi
        );
    }

    fn test_target(target_str: &str, target: RustTarget) {
        let target_string = target.to_string();
        assert_eq!(target_str, target_string);
        assert_eq!(target, RustTarget::from_str(target_str).unwrap());
    }

    #[test]
    fn str_to_target() {
        test_target("1.0", RustTarget::Stable_1_0);
        test_target("1.17", RustTarget::Stable_1_17);
        test_target("1.19", RustTarget::Stable_1_19);
        test_target("1.21", RustTarget::Stable_1_21);
        test_target("1.25", RustTarget::Stable_1_25);
        test_target("1.71", RustTarget::Stable_1_71);
        test_target("nightly", RustTarget::Nightly);
    }
}

Messung V0.5 in Prozent
C=92 H=99 G=95

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet am  2026-06-18) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.