diff options
Diffstat (limited to 'library')
85 files changed, 1473 insertions, 1010 deletions
diff --git a/library/Cargo.lock b/library/Cargo.lock index 4b06f14c7ee..656576d2d8e 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -337,7 +337,6 @@ name = "std_detect" version = "0.1.5" dependencies = [ "alloc", - "cfg-if", "core", "libc", ] @@ -376,7 +375,6 @@ dependencies = [ name = "unwind" version = "0.0.0" dependencies = [ - "cfg-if", "libc", "rustc-std-workspace-core", "unwinding", diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 7d41ae45093..605ba42c541 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -3,164 +3,78 @@ use crate::fmt::NumBuffer; use crate::mem::MaybeUninit; use crate::num::fmt as numfmt; -use crate::ops::{Div, Rem, Sub}; use crate::{fmt, ptr, slice, str}; -#[doc(hidden)] -trait DisplayInt: - PartialEq + PartialOrd + Div<Output = Self> + Rem<Output = Self> + Sub<Output = Self> + Copy -{ - fn zero() -> Self; - fn from_u8(u: u8) -> Self; - fn to_u8(&self) -> u8; - #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] - fn to_u32(&self) -> u32; - fn to_u64(&self) -> u64; - fn to_u128(&self) -> u128; -} +/// Formatting of integers with a non-decimal radix. +macro_rules! radix_integer { + (fmt::$Trait:ident for $Signed:ident and $Unsigned:ident, $prefix:literal, $dig_tab:literal) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl fmt::$Trait for $Unsigned { + /// Format unsigned integers in the radix. + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Check macro arguments at compile time. + const { + assert!($Unsigned::MIN == 0, "need unsigned"); + assert!($dig_tab.is_ascii(), "need single-byte entries"); + } -macro_rules! impl_int { - ($($t:ident)*) => ( - $(impl DisplayInt for $t { - fn zero() -> Self { 0 } - fn from_u8(u: u8) -> Self { u as Self } - fn to_u8(&self) -> u8 { *self as u8 } - #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] - fn to_u32(&self) -> u32 { *self as u32 } - fn to_u64(&self) -> u64 { *self as u64 } - fn to_u128(&self) -> u128 { *self as u128 } - })* - ) -} + // ASCII digits in ascending order are used as a lookup table. + const DIG_TAB: &[u8] = $dig_tab; + const BASE: $Unsigned = DIG_TAB.len() as $Unsigned; + const MAX_DIG_N: usize = $Unsigned::MAX.ilog(BASE) as usize + 1; -impl_int! { - i8 i16 i32 i64 i128 isize - u8 u16 u32 u64 u128 usize -} + // Buffer digits of self with right alignment. + let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DIG_N]; + // Count the number of bytes in buf that are not initialized. + let mut offset = buf.len(); -/// A type that represents a specific radix -/// -/// # Safety -/// -/// `digit` must return an ASCII character. -#[doc(hidden)] -unsafe trait GenericRadix: Sized { - /// The number of digits. - const BASE: u8; - - /// A radix-specific prefix string. - const PREFIX: &'static str; - - /// Converts an integer to corresponding radix digit. - fn digit(x: u8) -> u8; - - /// Format an integer using the radix using a formatter. - fn fmt_int<T: DisplayInt>(&self, mut x: T, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // The radix can be as low as 2, so we need a buffer of at least 128 - // characters for a base 2 number. - let zero = T::zero(); - let is_nonnegative = x >= zero; - let mut buf = [MaybeUninit::<u8>::uninit(); 128]; - let mut offset = buf.len(); - let base = T::from_u8(Self::BASE); - if is_nonnegative { - // Accumulate each digit of the number from the least significant - // to the most significant figure. - loop { - let n = x % base; // Get the current place value. - x = x / base; // Deaccumulate the number. - offset -= 1; - buf[offset].write(Self::digit(n.to_u8())); // Store the digit in the buffer. - if x == zero { - // No more digits left to accumulate. - break; - }; - } - } else { - // Do the same as above, but accounting for two's complement. - loop { - let n = zero - (x % base); // Get the current place value. - x = x / base; // Deaccumulate the number. - offset -= 1; - buf[offset].write(Self::digit(n.to_u8())); // Store the digit in the buffer. - if x == zero { - // No more digits left to accumulate. - break; - }; - } - } - // SAFETY: Starting from `offset`, all elements of the slice have been set. - let buf_slice = unsafe { slice_buffer_to_str(&buf, offset) }; - f.pad_integral(is_nonnegative, Self::PREFIX, buf_slice) - } -} + // Accumulate each digit of the number from the least + // significant to the most significant figure. + let mut remain = *self; + loop { + let digit = remain % BASE; + remain /= BASE; -/// A binary (base 2) radix -#[derive(Clone, PartialEq)] -struct Binary; - -/// An octal (base 8) radix -#[derive(Clone, PartialEq)] -struct Octal; - -/// A hexadecimal (base 16) radix, formatted with lower-case characters -#[derive(Clone, PartialEq)] -struct LowerHex; - -/// A hexadecimal (base 16) radix, formatted with upper-case characters -#[derive(Clone, PartialEq)] -struct UpperHex; - -macro_rules! radix { - ($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => { - unsafe impl GenericRadix for $T { - const BASE: u8 = $base; - const PREFIX: &'static str = $prefix; - fn digit(x: u8) -> u8 { - match x { - $($x => $conv,)+ - x => panic!("number not in the range 0..={}: {}", Self::BASE - 1, x), + offset -= 1; + // SAFETY: `remain` will reach 0 and we will break before `offset` wraps + unsafe { core::hint::assert_unchecked(offset < buf.len()) } + buf[offset].write(DIG_TAB[digit as usize]); + if remain == 0 { + break; + } } + + // SAFETY: Starting from `offset`, all elements of the slice have been set. + let digits = unsafe { slice_buffer_to_str(&buf, offset) }; + f.pad_integral(true, $prefix, digits) } } - } -} -radix! { Binary, 2, "0b", x @ 0 ..= 1 => b'0' + x } -radix! { Octal, 8, "0o", x @ 0 ..= 7 => b'0' + x } -radix! { LowerHex, 16, "0x", x @ 0 ..= 9 => b'0' + x, x @ 10 ..= 15 => b'a' + (x - 10) } -radix! { UpperHex, 16, "0x", x @ 0 ..= 9 => b'0' + x, x @ 10 ..= 15 => b'A' + (x - 10) } - -macro_rules! int_base { - (fmt::$Trait:ident for $T:ident as $U:ident -> $Radix:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - impl fmt::$Trait for $T { + impl fmt::$Trait for $Signed { + /// Format signed integers in the two’s-complement form. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - $Radix.fmt_int(*self as $U, f) + fmt::$Trait::fmt(&self.cast_unsigned(), f) } } }; } -macro_rules! integer { - ($Int:ident, $Uint:ident) => { - int_base! { fmt::Binary for $Int as $Uint -> Binary } - int_base! { fmt::Octal for $Int as $Uint -> Octal } - int_base! { fmt::LowerHex for $Int as $Uint -> LowerHex } - int_base! { fmt::UpperHex for $Int as $Uint -> UpperHex } - - int_base! { fmt::Binary for $Uint as $Uint -> Binary } - int_base! { fmt::Octal for $Uint as $Uint -> Octal } - int_base! { fmt::LowerHex for $Uint as $Uint -> LowerHex } - int_base! { fmt::UpperHex for $Uint as $Uint -> UpperHex } +/// Formatting of integers with a non-decimal radix. +macro_rules! radix_integers { + ($Signed:ident, $Unsigned:ident) => { + radix_integer! { fmt::Binary for $Signed and $Unsigned, "0b", b"01" } + radix_integer! { fmt::Octal for $Signed and $Unsigned, "0o", b"01234567" } + radix_integer! { fmt::LowerHex for $Signed and $Unsigned, "0x", b"0123456789abcdef" } + radix_integer! { fmt::UpperHex for $Signed and $Unsigned, "0x", b"0123456789ABCDEF" } }; } -integer! { isize, usize } -integer! { i8, u8 } -integer! { i16, u16 } -integer! { i32, u32 } -integer! { i64, u64 } -integer! { i128, u128 } +radix_integers! { isize, usize } +radix_integers! { i8, u8 } +radix_integers! { i16, u16 } +radix_integers! { i32, u32 } +radix_integers! { i64, u64 } +radix_integers! { i128, u128 } macro_rules! impl_Debug { ($($T:ident)*) => { @@ -205,16 +119,21 @@ unsafe fn slice_buffer_to_str(buf: &[MaybeUninit<u8>], offset: usize) -> &str { } macro_rules! impl_Display { - ($($signed:ident, $unsigned:ident,)* ; as $u:ident via $conv_fn:ident named $gen_name:ident) => { + ($($Signed:ident, $Unsigned:ident),* ; as $T:ident into $fmt_fn:ident) => { $( + const _: () = { + assert!($Signed::BITS <= $T::BITS, "need lossless conversion"); + assert!($Unsigned::BITS <= $T::BITS, "need lossless conversion"); + }; + #[stable(feature = "rust1", since = "1.0.0")] - impl fmt::Display for $unsigned { + impl fmt::Display for $Unsigned { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { #[cfg(not(feature = "optimize_for_size"))] { - const MAX_DEC_N: usize = $unsigned::MAX.ilog10() as usize + 1; - // Buffer decimals for $unsigned with right alignment. + const MAX_DEC_N: usize = $Unsigned::MAX.ilog10() as usize + 1; + // Buffer decimals for self with right alignment. let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N]; // SAFETY: `buf` is always big enough to contain all the digits. @@ -222,18 +141,20 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] { - $gen_name(self.$conv_fn(), true, f) + // Lossless conversion (with as) is asserted at the top of + // this macro. + ${concat($fmt_fn, _small)}(*self as $T, true, f) } } } #[stable(feature = "rust1", since = "1.0.0")] - impl fmt::Display for $signed { + impl fmt::Display for $Signed { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { #[cfg(not(feature = "optimize_for_size"))] { - const MAX_DEC_N: usize = $unsigned::MAX.ilog10() as usize + 1; - // Buffer decimals for $unsigned with right alignment. + const MAX_DEC_N: usize = $Unsigned::MAX.ilog10() as usize + 1; + // Buffer decimals for self with right alignment. let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N]; // SAFETY: `buf` is always big enough to contain all the digits. @@ -241,13 +162,15 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] { - return $gen_name(self.unsigned_abs().$conv_fn(), *self >= 0, f); + // Lossless conversion (with as) is asserted at the top of + // this macro. + return ${concat($fmt_fn, _small)}(self.unsigned_abs() as $T, *self >= 0, f); } } } #[cfg(not(feature = "optimize_for_size"))] - impl $unsigned { + impl $Unsigned { #[doc(hidden)] #[unstable( feature = "fmt_internals", @@ -268,7 +191,7 @@ macro_rules! impl_Display { let mut remain = self; // Format per four digits from the lookup table. - // Four digits need a 16-bit $unsigned or wider. + // Four digits need a 16-bit $Unsigned or wider. while size_of::<Self>() > 1 && remain > 999.try_into().expect("branch is not hit for types that cannot fit 999 (u8)") { // SAFETY: All of the decimals fit in buf due to MAX_DEC_N // and the while condition ensures at least 4 more decimals. @@ -327,7 +250,7 @@ macro_rules! impl_Display { } } - impl $signed { + impl $Signed { /// Allows users to write an integer (in signed decimal format) into a variable `buf` of /// type [`NumBuffer`] that is passed by the caller by mutable reference. /// @@ -337,15 +260,15 @@ macro_rules! impl_Display { /// #![feature(int_format_into)] /// use core::fmt::NumBuffer; /// - #[doc = concat!("let n = 0", stringify!($signed), ";")] + #[doc = concat!("let n = 0", stringify!($Signed), ";")] /// let mut buf = NumBuffer::new(); /// assert_eq!(n.format_into(&mut buf), "0"); /// - #[doc = concat!("let n1 = 32", stringify!($signed), ";")] + #[doc = concat!("let n1 = 32", stringify!($Signed), ";")] /// assert_eq!(n1.format_into(&mut buf), "32"); /// - #[doc = concat!("let n2 = ", stringify!($signed::MAX), ";")] - #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($signed::MAX), ".to_string());")] + #[doc = concat!("let n2 = ", stringify!($Signed::MAX), ";")] + #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($Signed::MAX), ".to_string());")] /// ``` #[unstable(feature = "int_format_into", issue = "138215")] pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str { @@ -358,7 +281,9 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] { - offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(self.unsigned_abs().$conv_fn(), &mut buf.buf); + // Lossless conversion (with as) is asserted at the top of + // this macro. + offset = ${concat($fmt_fn, _in_buf_small)}(self.unsigned_abs() as $T, &mut buf.buf); } // Only difference between signed and unsigned are these 4 lines. if self < 0 { @@ -370,7 +295,7 @@ macro_rules! impl_Display { } } - impl $unsigned { + impl $Unsigned { /// Allows users to write an integer (in signed decimal format) into a variable `buf` of /// type [`NumBuffer`] that is passed by the caller by mutable reference. /// @@ -380,15 +305,15 @@ macro_rules! impl_Display { /// #![feature(int_format_into)] /// use core::fmt::NumBuffer; /// - #[doc = concat!("let n = 0", stringify!($unsigned), ";")] + #[doc = concat!("let n = 0", stringify!($Unsigned), ";")] /// let mut buf = NumBuffer::new(); /// assert_eq!(n.format_into(&mut buf), "0"); /// - #[doc = concat!("let n1 = 32", stringify!($unsigned), ";")] + #[doc = concat!("let n1 = 32", stringify!($Unsigned), ";")] /// assert_eq!(n1.format_into(&mut buf), "32"); /// - #[doc = concat!("let n2 = ", stringify!($unsigned::MAX), ";")] - #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($unsigned::MAX), ".to_string());")] + #[doc = concat!("let n2 = ", stringify!($Unsigned::MAX), ";")] + #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($Unsigned::MAX), ".to_string());")] /// ``` #[unstable(feature = "int_format_into", issue = "138215")] pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str { @@ -401,7 +326,9 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] { - offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(self.$conv_fn(), &mut buf.buf); + // Lossless conversion (with as) is asserted at the top of + // this macro. + offset = ${concat($fmt_fn, _in_buf_small)}(self as $T, &mut buf.buf); } // SAFETY: Starting from `offset`, all elements of the slice have been set. unsafe { slice_buffer_to_str(&buf.buf, offset) } @@ -412,7 +339,7 @@ macro_rules! impl_Display { )* #[cfg(feature = "optimize_for_size")] - fn ${concat(_inner_slow_integer_to_str, $gen_name)}(mut n: $u, buf: &mut [MaybeUninit::<u8>]) -> usize { + fn ${concat($fmt_fn, _in_buf_small)}(mut n: $T, buf: &mut [MaybeUninit::<u8>]) -> usize { let mut curr = buf.len(); // SAFETY: To show that it's OK to copy into `buf_ptr`, notice that at the beginning @@ -433,11 +360,11 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] - fn $gen_name(n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { - const MAX_DEC_N: usize = $u::MAX.ilog(10) as usize + 1; + fn ${concat($fmt_fn, _small)}(n: $T, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { + const MAX_DEC_N: usize = $T::MAX.ilog(10) as usize + 1; let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N]; - let offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(n, &mut buf); + let offset = ${concat($fmt_fn, _in_buf_small)}(n, &mut buf); // SAFETY: Starting from `offset`, all elements of the slice have been set. let buf_slice = unsafe { slice_buffer_to_str(&buf, offset) }; f.pad_integral(is_nonnegative, "", buf_slice) @@ -446,9 +373,9 @@ macro_rules! impl_Display { } macro_rules! impl_Exp { - ($($t:ident),* as $u:ident via $conv_fn:ident named $name:ident) => { - fn $name( - mut n: $u, + ($($Signed:ident, $Unsigned:ident),* ; as $T:ident into $fmt_fn:ident) => { + fn $fmt_fn( + mut n: $T, is_nonnegative: bool, upper: bool, f: &mut fmt::Formatter<'_> @@ -582,32 +509,41 @@ macro_rules! impl_Exp { $( #[stable(feature = "integer_exp_format", since = "1.42.0")] - impl fmt::LowerExp for $t { - #[allow(unused_comparisons)] + impl fmt::LowerExp for $Signed { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let is_nonnegative = *self >= 0; let n = if is_nonnegative { - self.$conv_fn() + *self as $T } else { - // convert the negative num to positive by summing 1 to its 2s complement - (!self.$conv_fn()).wrapping_add(1) + self.unsigned_abs() as $T }; - $name(n, is_nonnegative, false, f) + $fmt_fn(n, is_nonnegative, false, f) + } + } + #[stable(feature = "integer_exp_format", since = "1.42.0")] + impl fmt::LowerExp for $Unsigned { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + $fmt_fn(*self as $T, true, false, f) } })* + $( #[stable(feature = "integer_exp_format", since = "1.42.0")] - impl fmt::UpperExp for $t { - #[allow(unused_comparisons)] + impl fmt::UpperExp for $Signed { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let is_nonnegative = *self >= 0; let n = if is_nonnegative { - self.$conv_fn() + *self as $T } else { - // convert the negative num to positive by summing 1 to its 2s complement - (!self.$conv_fn()).wrapping_add(1) + self.unsigned_abs() as $T }; - $name(n, is_nonnegative, true, f) + $fmt_fn(n, is_nonnegative, true, f) + } + } + #[stable(feature = "integer_exp_format", since = "1.42.0")] + impl fmt::UpperExp for $Unsigned { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + $fmt_fn(*self as $T, true, true, f) } })* }; @@ -623,37 +559,20 @@ impl_Debug! { #[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] mod imp { use super::*; - impl_Display!( - i8, u8, - i16, u16, - i32, u32, - i64, u64, - isize, usize, - ; as u64 via to_u64 named fmt_u64 - ); - impl_Exp!( - i8, u8, i16, u16, i32, u32, i64, u64, usize, isize - as u64 via to_u64 named exp_u64 - ); + impl_Display!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize; as u64 into display_u64); + impl_Exp!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize; as u64 into exp_u64); } #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] mod imp { use super::*; - impl_Display!( - i8, u8, - i16, u16, - i32, u32, - isize, usize, - ; as u32 via to_u32 named fmt_u32); - impl_Display!( - i64, u64, - ; as u64 via to_u64 named fmt_u64); - - impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize as u32 via to_u32 named exp_u32); - impl_Exp!(i64, u64 as u64 via to_u64 named exp_u64); + impl_Display!(i8, u8, i16, u16, i32, u32, isize, usize; as u32 into display_u32); + impl_Display!(i64, u64; as u64 into display_u64); + + impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize; as u32 into exp_u32); + impl_Exp!(i64, u64; as u64 into exp_u64); } -impl_Exp!(i128, u128 as u128 via to_u128 named exp_u128); +impl_Exp!(i128, u128; as u128 into exp_u128); const U128_MAX_DEC_N: usize = u128::MAX.ilog10() as usize + 1; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 6396b8524f2..71abd707374 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -226,6 +226,13 @@ pub mod assert_matches { pub use crate::macros::{assert_matches, debug_assert_matches}; } +#[unstable(feature = "derive_from", issue = "144889")] +/// Unstable module containing the unstable `From` derive macro. +pub mod from { + #[unstable(feature = "derive_from", issue = "144889")] + pub use crate::macros::builtin::From; +} + // We don't export this through #[macro_export] for now, to avoid breakage. #[unstable(feature = "autodiff", issue = "124509")] /// Unstable module containing the unstable `autodiff` macro. diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index 87f2110034c..3bf113d017c 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -626,13 +626,13 @@ impl Ipv4Addr { /// # Examples /// /// ``` - /// #![feature(ip_from)] /// use std::net::Ipv4Addr; /// /// let addr = Ipv4Addr::from_octets([13u8, 12u8, 11u8, 10u8]); /// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr); /// ``` - #[unstable(feature = "ip_from", issue = "131360")] + #[stable(feature = "ip_from", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ip_from", since = "CURRENT_RUSTC_VERSION")] #[must_use] #[inline] pub const fn from_octets(octets: [u8; 4]) -> Ipv4Addr { @@ -1464,7 +1464,6 @@ impl Ipv6Addr { /// # Examples /// /// ``` - /// #![feature(ip_from)] /// use std::net::Ipv6Addr; /// /// let addr = Ipv6Addr::from_segments([ @@ -1479,7 +1478,8 @@ impl Ipv6Addr { /// addr /// ); /// ``` - #[unstable(feature = "ip_from", issue = "131360")] + #[stable(feature = "ip_from", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ip_from", since = "CURRENT_RUSTC_VERSION")] #[must_use] #[inline] pub const fn from_segments(segments: [u16; 8]) -> Ipv6Addr { @@ -2029,7 +2029,6 @@ impl Ipv6Addr { /// # Examples /// /// ``` - /// #![feature(ip_from)] /// use std::net::Ipv6Addr; /// /// let addr = Ipv6Addr::from_octets([ @@ -2044,7 +2043,8 @@ impl Ipv6Addr { /// addr /// ); /// ``` - #[unstable(feature = "ip_from", issue = "131360")] + #[stable(feature = "ip_from", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ip_from", since = "CURRENT_RUSTC_VERSION")] #[must_use] #[inline] pub const fn from_octets(octets: [u8; 16]) -> Ipv6Addr { diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index 1844cd98082..3118a6e5ca6 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -124,6 +124,8 @@ macro_rules! from_str_float_impl { /// * '2.5E-10' /// * '5.' /// * '.5', or, equivalently, '0.5' + /// * '7' + /// * '007' /// * 'inf', '-inf', '+infinity', 'NaN' /// /// Note that alphabetical characters are not case-sensitive. diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 560d20ce617..e83e77344cf 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2095,9 +2095,9 @@ impl<T> Option<&mut T> { impl<T, E> Option<Result<T, E>> { /// Transposes an `Option` of a [`Result`] into a [`Result`] of an `Option`. /// - /// [`None`] will be mapped to <code>[Ok]\([None])</code>. - /// <code>[Some]\([Ok]\(\_))</code> and <code>[Some]\([Err]\(\_))</code> will be mapped to - /// <code>[Ok]\([Some]\(\_))</code> and <code>[Err]\(\_)</code>. + /// <code>[Some]\([Ok]\(\_))</code> is mapped to <code>[Ok]\([Some]\(\_))</code>, + /// <code>[Some]\([Err]\(\_))</code> is mapped to <code>[Err]\(\_)</code>, + /// and [`None`] will be mapped to <code>[Ok]\([None])</code>. /// /// # Examples /// @@ -2105,9 +2105,9 @@ impl<T, E> Option<Result<T, E>> { /// #[derive(Debug, Eq, PartialEq)] /// struct SomeErr; /// - /// let x: Result<Option<i32>, SomeErr> = Ok(Some(5)); - /// let y: Option<Result<i32, SomeErr>> = Some(Ok(5)); - /// assert_eq!(x, y.transpose()); + /// let x: Option<Result<i32, SomeErr>> = Some(Ok(5)); + /// let y: Result<Option<i32>, SomeErr> = Ok(Some(5)); + /// assert_eq!(x.transpose(), y); /// ``` #[inline] #[stable(feature = "transpose_result", since = "1.33.0")] diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index d8d82afb0e6..a4be66b90ca 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -117,10 +117,3 @@ pub use crate::macros::builtin::deref; reason = "`type_alias_impl_trait` has open design concerns" )] pub use crate::macros::builtin::define_opaque; - -#[unstable( - feature = "derive_from", - issue = "144889", - reason = "`derive(From)` is unstable" -)] -pub use crate::macros::builtin::From; diff --git a/library/core/src/unicode/mod.rs b/library/core/src/unicode/mod.rs index 49dbdeb1a6d..191fe7711f9 100644 --- a/library/core/src/unicode/mod.rs +++ b/library/core/src/unicode/mod.rs @@ -1,5 +1,6 @@ +//! Unicode internals used in liballoc and libstd. Not public API. #![unstable(feature = "unicode_internals", issue = "none")] -#![allow(missing_docs)] +#![doc(hidden)] // for use in alloc, not re-exported in std. #[rustfmt::skip] @@ -31,5 +32,4 @@ mod unicode_data; /// /// The version numbering scheme is explained in /// [Unicode 11.0 or later, Section 3.1 Versions of the Unicode Standard](https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf#page=4). -#[stable(feature = "unicode_version", since = "1.45.0")] pub const UNICODE_VERSION: (u8, u8, u8) = unicode_data::UNICODE_VERSION; diff --git a/library/coretests/benches/fmt.rs b/library/coretests/benches/fmt.rs index ee8e981b46b..f45b921b939 100644 --- a/library/coretests/benches/fmt.rs +++ b/library/coretests/benches/fmt.rs @@ -162,3 +162,183 @@ fn write_u8_min(bh: &mut Bencher) { black_box(format!("{}", black_box(u8::MIN))); }); } + +#[bench] +fn write_i8_bin(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:b}", black_box(0_i8)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(100_i8)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(-100_i8)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(1_i8 << 4)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i16_bin(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:b}", black_box(0_i16)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(100_i16)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(-100_i16)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(1_i16 << 8)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i32_bin(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:b}", black_box(0_i32)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(100_i32)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(-100_i32)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(1_i32 << 16)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i64_bin(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:b}", black_box(0_i64)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(100_i64)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(-100_i64)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(1_i64 << 32)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i128_bin(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:b}", black_box(0_i128)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(100_i128)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(-100_i128)).unwrap(); + write!(black_box(&mut buf), "{:b}", black_box(1_i128 << 64)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i8_oct(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:o}", black_box(0_i8)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(100_i8)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(-100_i8)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(1_i8 << 4)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i16_oct(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:o}", black_box(0_i16)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(100_i16)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(-100_i16)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(1_i16 << 8)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i32_oct(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:o}", black_box(0_i32)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(100_i32)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(-100_i32)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(1_i32 << 16)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i64_oct(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:o}", black_box(0_i64)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(100_i64)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(-100_i64)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(1_i64 << 32)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i128_oct(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:o}", black_box(0_i128)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(100_i128)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(-100_i128)).unwrap(); + write!(black_box(&mut buf), "{:o}", black_box(1_i128 << 64)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i8_hex(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:x}", black_box(0_i8)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(100_i8)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(-100_i8)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(1_i8 << 4)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i16_hex(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:x}", black_box(0_i16)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(100_i16)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(-100_i16)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(1_i16 << 8)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i32_hex(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:x}", black_box(0_i32)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(100_i32)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(-100_i32)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(1_i32 << 16)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i64_hex(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:x}", black_box(0_i64)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(100_i64)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(-100_i64)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(1_i64 << 32)).unwrap(); + black_box(&mut buf).clear(); + }); +} + +#[bench] +fn write_i128_hex(bh: &mut Bencher) { + let mut buf = String::with_capacity(256); + bh.iter(|| { + write!(black_box(&mut buf), "{:x}", black_box(0_i128)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(100_i128)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(-100_i128)).unwrap(); + write!(black_box(&mut buf), "{:x}", black_box(1_i128 << 64)).unwrap(); + black_box(&mut buf).clear(); + }); +} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index ecda8a7fec6..b128acfc000 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -56,7 +56,6 @@ #![feature(hashmap_internals)] #![feature(int_roundings)] #![feature(ip)] -#![feature(ip_from)] #![feature(is_ascii_octdigit)] #![feature(isolate_most_least_significant_one)] #![feature(iter_advance_by)] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 7bc52976500..eff2562f031 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -14,6 +14,7 @@ crate-type = ["dylib", "rlib"] [dependencies] alloc = { path = "../alloc", public = true } +# std no longer uses cfg-if directly, but the included copy of backtrace does. cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 8d7edc732af..1214490caad 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -137,7 +137,7 @@ impl OsString { #[stable(feature = "rust1", since = "1.0.0")] #[must_use] #[inline] - #[rustc_const_unstable(feature = "const_pathbuf_osstring_new", issue = "141520")] + #[rustc_const_stable(feature = "const_pathbuf_osstring_new", since = "CURRENT_RUSTC_VERSION")] pub const fn new() -> OsString { OsString { inner: Buf::from_string(String::new()) } } diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index a220a3f56e9..1ed4f2f9f0c 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -3119,7 +3119,7 @@ pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> { /// On UNIX-like systems, this function will update the permission bits /// of the file pointed to by the symlink. /// -/// Note that this behavior can lead to privalage escalation vulnerabilities, +/// Note that this behavior can lead to privilege escalation vulnerabilities, /// where the ability to create a symlink in one directory allows you to /// cause the permissions of another file or directory to be modified. /// @@ -3156,6 +3156,25 @@ pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result fs_imp::set_permissions(path.as_ref(), perm.0) } +/// Set the permissions of a file, unless it is a symlink. +/// +/// Note that the non-final path elements are allowed to be symlinks. +/// +/// # Platform-specific behavior +/// +/// Currently unimplemented on Windows. +/// +/// On Unix platforms, this results in a [`FilesystemLoop`] error if the last element is a symlink. +/// +/// This behavior may change in the future. +/// +/// [`FilesystemLoop`]: crate::io::ErrorKind::FilesystemLoop +#[doc(alias = "chmod", alias = "SetFileAttributes")] +#[unstable(feature = "set_permissions_nofollow", issue = "141607")] +pub fn set_permissions_nofollow<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result<()> { + fs_imp::set_permissions_nofollow(path.as_ref(), perm) +} + impl DirBuilder { /// Creates a new set of options with default mode/security settings for all /// platforms and also non-recursive. diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs index 574288e579e..9b600cd5575 100644 --- a/library/std/src/io/buffered/bufreader/buffer.rs +++ b/library/std/src/io/buffered/bufreader/buffer.rs @@ -122,7 +122,7 @@ impl Buffer { /// Remove bytes that have already been read from the buffer. pub fn backshift(&mut self) { - self.buf.copy_within(self.pos.., 0); + self.buf.copy_within(self.pos..self.filled, 0); self.filled -= self.pos; self.pos = 0; } diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs index 15e962924ac..d060ad52897 100644 --- a/library/std/src/io/copy.rs +++ b/library/std/src/io/copy.rs @@ -63,10 +63,11 @@ where R: Read, W: Write, { - cfg_if::cfg_if! { - if #[cfg(any(target_os = "linux", target_os = "android"))] { + cfg_select! { + any(target_os = "linux", target_os = "android") => { crate::sys::kernel_copy::copy_spec(reader, writer) - } else { + } + _ => { generic_copy(reader, writer) } } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index f111fcb4a47..ab417b6c72f 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -330,6 +330,7 @@ #![feature(bstr)] #![feature(bstr_internals)] #![feature(cast_maybe_uninit)] +#![feature(cfg_select)] #![feature(char_internals)] #![feature(clone_to_uninit)] #![feature(const_cmp)] @@ -737,6 +738,14 @@ pub use core::{ unreachable, write, writeln, }; +// Re-export unstable derive macro defined through core. +#[unstable(feature = "derive_from", issue = "144889")] +/// Unstable module containing the unstable `From` derive macro. +pub mod from { + #[unstable(feature = "derive_from", issue = "144889")] + pub use core::from::From; +} + // Include a number of private modules that exist solely to provide // the rustdoc documentation for primitive types. Using `include!` // because rustdoc only looks for these modules at the crate level. diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 035768a6fab..768fa77a5f8 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -1,14 +1,16 @@ -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( target_os = "linux", target_os = "android", target_os = "hurd", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "solaris", target_os = "illumos", target_os = "haiku", target_os = "nto", - target_os = "cygwin"))] { + target_os = "cygwin", + ) => { use libc::MSG_NOSIGNAL; - } else { + } + _ => { const MSG_NOSIGNAL: core::ffi::c_int = 0x0; } } diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 76e63a69e45..09429af06e3 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -4,8 +4,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use cfg_if::cfg_if; - use crate::ffi::OsStr; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::path::Path; @@ -13,17 +11,19 @@ use crate::sealed::Sealed; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::{io, process, sys}; -cfg_if! { - if #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon", target_os = "vita"))] { +cfg_select! { + any(target_os = "vxworks", target_os = "espidf", target_os = "horizon", target_os = "vita") => { type UserId = u16; type GroupId = u16; - } else if #[cfg(target_os = "nto")] { + } + target_os = "nto" => { // Both IDs are signed, see `sys/target_nto.h` of the QNX Neutrino SDP. // Only positive values should be used, see e.g. // https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/s/setuid.html type UserId = i32; type GroupId = i32; - } else { + } + _ => { type UserId = u32; type GroupId = u32; } diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 3b52804d6be..3899fbf86db 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1191,7 +1191,7 @@ impl PathBuf { #[stable(feature = "rust1", since = "1.0.0")] #[must_use] #[inline] - #[rustc_const_unstable(feature = "const_pathbuf_osstring_new", issue = "141520")] + #[rustc_const_stable(feature = "const_pathbuf_osstring_new", since = "CURRENT_RUSTC_VERSION")] pub const fn new() -> PathBuf { PathBuf { inner: OsString::new() } } @@ -2105,6 +2105,38 @@ impl PartialEq for PathBuf { } } +#[stable(feature = "eq_str_for_path", since = "CURRENT_RUSTC_VERSION")] +impl cmp::PartialEq<str> for PathBuf { + #[inline] + fn eq(&self, other: &str) -> bool { + &*self == other + } +} + +#[stable(feature = "eq_str_for_path", since = "CURRENT_RUSTC_VERSION")] +impl cmp::PartialEq<PathBuf> for str { + #[inline] + fn eq(&self, other: &PathBuf) -> bool { + other == self + } +} + +#[stable(feature = "eq_str_for_path", since = "CURRENT_RUSTC_VERSION")] +impl cmp::PartialEq<String> for PathBuf { + #[inline] + fn eq(&self, other: &String) -> bool { + **self == **other + } +} + +#[stable(feature = "eq_str_for_path", since = "CURRENT_RUSTC_VERSION")] +impl cmp::PartialEq<PathBuf> for String { + #[inline] + fn eq(&self, other: &PathBuf) -> bool { + other == self + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Hash for PathBuf { fn hash<H: Hasher>(&self, h: &mut H) { @@ -3366,6 +3398,39 @@ impl PartialEq for Path { } } +#[stable(feature = "eq_str_for_path", since = "CURRENT_RUSTC_VERSION")] +impl cmp::PartialEq<str> for Path { + #[inline] + fn eq(&self, other: &str) -> bool { + let other: &OsStr = other.as_ref(); + self == other + } +} + +#[stable(feature = "eq_str_for_path", since = "CURRENT_RUSTC_VERSION")] +impl cmp::PartialEq<Path> for str { + #[inline] + fn eq(&self, other: &Path) -> bool { + other == self + } +} + +#[stable(feature = "eq_str_for_path", since = "CURRENT_RUSTC_VERSION")] +impl cmp::PartialEq<String> for Path { + #[inline] + fn eq(&self, other: &String) -> bool { + self == &*other + } +} + +#[stable(feature = "eq_str_for_path", since = "CURRENT_RUSTC_VERSION")] +impl cmp::PartialEq<Path> for String { + #[inline] + fn eq(&self, other: &Path) -> bool { + other == self + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Hash for Path { fn hash<H: Hasher>(&self, h: &mut H) { diff --git a/library/std/src/sync/nonpoison/mutex.rs b/library/std/src/sync/nonpoison/mutex.rs index b6861c78f00..fd1e671d7a3 100644 --- a/library/std/src/sync/nonpoison/mutex.rs +++ b/library/std/src/sync/nonpoison/mutex.rs @@ -100,7 +100,7 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> { lock: &'a Mutex<T>, } -/// A [`MutexGuard`] is not `Send` to maximize platform portablity. +/// A [`MutexGuard`] is not `Send` to maximize platform portability. /// /// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to /// release mutex locks on the same thread they were acquired. diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs index 6205c4fa4ca..720c212c65c 100644 --- a/library/std/src/sync/poison/mutex.rs +++ b/library/std/src/sync/poison/mutex.rs @@ -279,7 +279,7 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> { poison: poison::Guard, } -/// A [`MutexGuard`] is not `Send` to maximize platform portablity. +/// A [`MutexGuard`] is not `Send` to maximize platform portability. /// /// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to /// release mutex locks on the same thread they were acquired. diff --git a/library/std/src/sync/reentrant_lock.rs b/library/std/src/sync/reentrant_lock.rs index 727252f03a2..4140718560c 100644 --- a/library/std/src/sync/reentrant_lock.rs +++ b/library/std/src/sync/reentrant_lock.rs @@ -1,5 +1,3 @@ -use cfg_if::cfg_if; - use crate::cell::UnsafeCell; use crate::fmt; use crate::ops::Deref; @@ -87,8 +85,8 @@ pub struct ReentrantLock<T: ?Sized> { data: T, } -cfg_if!( - if #[cfg(target_has_atomic = "64")] { +cfg_select!( + target_has_atomic = "64" => { use crate::sync::atomic::{Atomic, AtomicU64, Ordering::Relaxed}; struct Tid(Atomic<u64>); @@ -110,7 +108,8 @@ cfg_if!( self.0.store(value, Relaxed); } } - } else { + } + _ => { /// Returns the address of a TLS variable. This is guaranteed to /// be unique across all currently alive threads. fn tls_addr() -> usize { diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs index f3af1f7f599..6d4b09494a3 100644 --- a/library/std/src/sys/alloc/mod.rs +++ b/library/std/src/sys/alloc/mod.rs @@ -68,29 +68,37 @@ unsafe fn realloc_fallback( } } -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( target_family = "unix", target_os = "wasi", target_os = "teeos", target_os = "trusty", - ))] { + ) => { mod unix; - } else if #[cfg(target_os = "windows")] { + } + target_os = "windows" => { mod windows; - } else if #[cfg(target_os = "hermit")] { + } + target_os = "hermit" => { mod hermit; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod sgx; - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod solid; - } else if #[cfg(target_os = "uefi")] { + } + target_os = "uefi" => { mod uefi; - } else if #[cfg(target_family = "wasm")] { + } + target_family = "wasm" => { mod wasm; - } else if #[cfg(target_os = "xous")] { + } + target_os = "xous" => { mod xous; - } else if #[cfg(target_os = "zkvm")] { + } + target_os = "zkvm" => { mod zkvm; } } diff --git a/library/std/src/sys/alloc/unix.rs b/library/std/src/sys/alloc/unix.rs index a7ac4117ec9..3d369b08abc 100644 --- a/library/std/src/sys/alloc/unix.rs +++ b/library/std/src/sys/alloc/unix.rs @@ -58,18 +58,16 @@ unsafe impl GlobalAlloc for System { } } -cfg_if::cfg_if! { +cfg_select! { // We use posix_memalign wherever possible, but some targets have very incomplete POSIX coverage // so we need a fallback for those. - if #[cfg(any( - target_os = "horizon", - target_os = "vita", - ))] { + any(target_os = "horizon", target_os = "vita") => { #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { unsafe { libc::memalign(layout.align(), layout.size()) as *mut u8 } } - } else { + } + _ => { #[inline] #[cfg_attr(target_os = "vxworks", allow(unused_unsafe))] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { diff --git a/library/std/src/sys/anonymous_pipe/mod.rs b/library/std/src/sys/anonymous_pipe/mod.rs index aa14c8b650d..b6f464161ee 100644 --- a/library/std/src/sys/anonymous_pipe/mod.rs +++ b/library/std/src/sys/anonymous_pipe/mod.rs @@ -1,13 +1,15 @@ #![forbid(unsafe_op_in_unsafe_fn)] -cfg_if::cfg_if! { - if #[cfg(unix)] { +cfg_select! { + unix => { mod unix; pub use unix::{AnonPipe, pipe}; - } else if #[cfg(windows)] { + } + windows => { mod windows; pub use windows::{AnonPipe, pipe}; - } else { + } + _ => { mod unsupported; pub use unsupported::{AnonPipe, pipe}; } diff --git a/library/std/src/sys/args/mod.rs b/library/std/src/sys/args/mod.rs index 0011f55dc14..c9627322276 100644 --- a/library/std/src/sys/args/mod.rs +++ b/library/std/src/sys/args/mod.rs @@ -12,32 +12,39 @@ ))] mod common; -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))), target_os = "hermit", - ))] { + ) => { mod unix; pub use unix::*; - } else if #[cfg(target_family = "windows")] { + } + target_family = "windows" => { mod windows; pub use windows::*; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod sgx; pub use sgx::*; - } else if #[cfg(target_os = "uefi")] { + } + target_os = "uefi" => { mod uefi; pub use uefi::*; - } else if #[cfg(target_os = "wasi")] { + } + target_os = "wasi" => { mod wasi; pub use wasi::*; - } else if #[cfg(target_os = "xous")] { + } + target_os = "xous" => { mod xous; pub use xous::*; - } else if #[cfg(target_os = "zkvm")] { + } + target_os = "zkvm" => { mod zkvm; pub use zkvm::*; - } else { + } + _ => { mod unsupported; pub use unsupported::*; } diff --git a/library/std/src/sys/cmath.rs b/library/std/src/sys/cmath.rs index 299ce1a6ff0..1592218ead8 100644 --- a/library/std/src/sys/cmath.rs +++ b/library/std/src/sys/cmath.rs @@ -45,69 +45,70 @@ unsafe extern "C" { pub safe fn lgammaf128_r(n: f128, s: &mut i32) -> f128; pub safe fn erff128(n: f128) -> f128; pub safe fn erfcf128(n: f128) -> f128; - - cfg_if::cfg_if! { - if #[cfg(not(all(target_os = "windows", target_env = "msvc", target_arch = "x86")))] { - pub safe fn acosf(n: f32) -> f32; - pub safe fn asinf(n: f32) -> f32; - pub safe fn atan2f(a: f32, b: f32) -> f32; - pub safe fn atanf(n: f32) -> f32; - pub safe fn coshf(n: f32) -> f32; - pub safe fn sinhf(n: f32) -> f32; - pub safe fn tanf(n: f32) -> f32; - pub safe fn tanhf(n: f32) -> f32; - }} } -// On AIX, we don't have lgammaf_r only the f64 version, so we can -// use the f64 version lgamma_r -#[cfg(target_os = "aix")] -pub fn lgammaf_r(n: f32, s: &mut i32) -> f32 { - lgamma_r(n.into(), s) as f32 -} +cfg_select! { + all(target_os = "windows", target_env = "msvc", target_arch = "x86") => { + // On 32-bit x86 MSVC these functions aren't defined, so we just define shims + // which promote everything to f64, perform the calculation, and then demote + // back to f32. While not precisely correct should be "correct enough" for now. + #[inline] + pub fn acosf(n: f32) -> f32 { + f64::acos(n as f64) as f32 + } -// On 32-bit x86 MSVC these functions aren't defined, so we just define shims -// which promote everything to f64, perform the calculation, and then demote -// back to f32. While not precisely correct should be "correct enough" for now. -cfg_if::cfg_if! { -if #[cfg(all(target_os = "windows", target_env = "msvc", target_arch = "x86"))] { - #[inline] - pub fn acosf(n: f32) -> f32 { - f64::acos(n as f64) as f32 - } + #[inline] + pub fn asinf(n: f32) -> f32 { + f64::asin(n as f64) as f32 + } - #[inline] - pub fn asinf(n: f32) -> f32 { - f64::asin(n as f64) as f32 - } + #[inline] + pub fn atan2f(n: f32, b: f32) -> f32 { + f64::atan2(n as f64, b as f64) as f32 + } - #[inline] - pub fn atan2f(n: f32, b: f32) -> f32 { - f64::atan2(n as f64, b as f64) as f32 - } + #[inline] + pub fn atanf(n: f32) -> f32 { + f64::atan(n as f64) as f32 + } - #[inline] - pub fn atanf(n: f32) -> f32 { - f64::atan(n as f64) as f32 - } + #[inline] + pub fn coshf(n: f32) -> f32 { + f64::cosh(n as f64) as f32 + } - #[inline] - pub fn coshf(n: f32) -> f32 { - f64::cosh(n as f64) as f32 - } + #[inline] + pub fn sinhf(n: f32) -> f32 { + f64::sinh(n as f64) as f32 + } - #[inline] - pub fn sinhf(n: f32) -> f32 { - f64::sinh(n as f64) as f32 - } + #[inline] + pub fn tanf(n: f32) -> f32 { + f64::tan(n as f64) as f32 + } - #[inline] - pub fn tanf(n: f32) -> f32 { - f64::tan(n as f64) as f32 + #[inline] + pub fn tanhf(n: f32) -> f32 { + f64::tanh(n as f64) as f32 + } } - - #[inline] - pub fn tanhf(n: f32) -> f32 { - f64::tanh(n as f64) as f32 + _ => { + unsafe extern "C" { + pub safe fn acosf(n: f32) -> f32; + pub safe fn asinf(n: f32) -> f32; + pub safe fn atan2f(a: f32, b: f32) -> f32; + pub safe fn atanf(n: f32) -> f32; + pub safe fn coshf(n: f32) -> f32; + pub safe fn sinhf(n: f32) -> f32; + pub safe fn tanf(n: f32) -> f32; + pub safe fn tanhf(n: f32) -> f32; + } } -}} +} + +// On AIX, we don't have lgammaf_r only the f64 version, so we can +// use the f64 version lgamma_r +#[cfg(target_os = "aix")] +pub fn lgammaf_r(n: f32, s: &mut i32) -> f32 { + lgamma_r(n.into(), s) as f32 +} diff --git a/library/std/src/sys/env/mod.rs b/library/std/src/sys/env/mod.rs index d81ff875c83..f211a9fc86b 100644 --- a/library/std/src/sys/env/mod.rs +++ b/library/std/src/sys/env/mod.rs @@ -13,35 +13,44 @@ ))] mod common; -cfg_if::cfg_if! { - if #[cfg(target_family = "unix")] { +cfg_select! { + target_family = "unix" => { mod unix; pub use unix::*; - } else if #[cfg(target_family = "windows")] { + } + target_family = "windows" => { mod windows; pub use windows::*; - } else if #[cfg(target_os = "hermit")] { + } + target_os = "hermit" => { mod hermit; pub use hermit::*; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod sgx; pub use sgx::*; - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod solid; pub use solid::*; - } else if #[cfg(target_os = "uefi")] { + } + target_os = "uefi" => { mod uefi; pub use uefi::*; - } else if #[cfg(target_os = "wasi")] { + } + target_os = "wasi" => { mod wasi; pub use wasi::*; - } else if #[cfg(target_os = "xous")] { + } + target_os = "xous" => { mod xous; pub use xous::*; - } else if #[cfg(target_os = "zkvm")] { + } + target_os = "zkvm" => { mod zkvm; pub use zkvm::*; - } else { + } + _ => { mod unsupported; pub use unsupported::*; } diff --git a/library/std/src/sys/env/wasi.rs b/library/std/src/sys/env/wasi.rs index 3719f9db51e..1327cbc3263 100644 --- a/library/std/src/sys/env/wasi.rs +++ b/library/std/src/sys/env/wasi.rs @@ -7,8 +7,8 @@ use crate::os::wasi::prelude::*; use crate::sys::common::small_c_string::run_with_cstr; use crate::sys::pal::os::{cvt, libc}; -cfg_if::cfg_if! { - if #[cfg(target_feature = "atomics")] { +cfg_select! { + target_feature = "atomics" => { // Access to the environment must be protected by a lock in multi-threaded scenarios. use crate::sync::{PoisonError, RwLock}; static ENV_LOCK: RwLock<()> = RwLock::new(()); @@ -18,7 +18,8 @@ cfg_if::cfg_if! { pub fn env_write_lock() -> impl Drop { ENV_LOCK.write().unwrap_or_else(PoisonError::into_inner) } - } else { + } + _ => { // No need for a lock if we are single-threaded. pub fn env_read_lock() -> impl Drop { Box::new(()) diff --git a/library/std/src/sys/exit_guard.rs b/library/std/src/sys/exit_guard.rs index bd70d178244..00b91842e9d 100644 --- a/library/std/src/sys/exit_guard.rs +++ b/library/std/src/sys/exit_guard.rs @@ -1,5 +1,5 @@ -cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { +cfg_select! { + target_os = "linux" => { /// Mitigation for <https://github.com/rust-lang/rust/issues/126600> /// /// On glibc, `libc::exit` has been observed to not always be thread-safe. @@ -56,7 +56,8 @@ cfg_if::cfg_if! { } } } - } else { + } + _ => { /// Mitigation for <https://github.com/rust-lang/rust/issues/126600> /// /// Mitigation is ***NOT*** implemented on this platform, either because this platform diff --git a/library/std/src/sys/fd/mod.rs b/library/std/src/sys/fd/mod.rs index e0f5eab6951..7cb9dd1cba9 100644 --- a/library/std/src/sys/fd/mod.rs +++ b/library/std/src/sys/fd/mod.rs @@ -2,18 +2,22 @@ #![forbid(unsafe_op_in_unsafe_fn)] -cfg_if::cfg_if! { - if #[cfg(target_family = "unix")] { +cfg_select! { + target_family = "unix" => { mod unix; pub use unix::*; - } else if #[cfg(target_os = "hermit")] { + } + target_os = "hermit" => { mod hermit; pub use hermit::*; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod sgx; pub use sgx::*; - } else if #[cfg(target_os = "wasi")] { + } + target_os = "wasi" => { mod wasi; pub use wasi::*; } + _ => {} } diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs index d55e28074fe..dbd782f5018 100644 --- a/library/std/src/sys/fs/mod.rs +++ b/library/std/src/sys/fs/mod.rs @@ -5,8 +5,8 @@ use crate::path::{Path, PathBuf}; pub mod common; -cfg_if::cfg_if! { - if #[cfg(target_family = "unix")] { +cfg_select! { + target_family = "unix" => { mod unix; use unix as imp; pub use unix::{chown, fchown, lchown, mkfifo}; @@ -16,24 +16,30 @@ cfg_if::cfg_if! { #[cfg(any(target_os = "linux", target_os = "android"))] pub(crate) use unix::CachedFileMetadata; use crate::sys::common::small_c_string::run_path_with_cstr as with_native_path; - } else if #[cfg(target_os = "windows")] { + } + target_os = "windows" => { mod windows; use windows as imp; pub use windows::{symlink_inner, junction_point}; use crate::sys::path::with_native_path; - } else if #[cfg(target_os = "hermit")] { + } + target_os = "hermit" => { mod hermit; use hermit as imp; - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod solid; use solid as imp; - } else if #[cfg(target_os = "uefi")] { + } + target_os = "uefi" => { mod uefi; use uefi as imp; - } else if #[cfg(target_os = "wasi")] { + } + target_os = "wasi" => { mod wasi; use wasi as imp; - } else { + } + _ => { mod unsupported; use unsupported as imp; } @@ -108,6 +114,21 @@ pub fn set_permissions(path: &Path, perm: FilePermissions) -> io::Result<()> { with_native_path(path, &|path| imp::set_perm(path, perm.clone())) } +#[cfg(unix)] +pub fn set_permissions_nofollow(path: &Path, perm: crate::fs::Permissions) -> io::Result<()> { + use crate::fs::OpenOptions; + use crate::os::unix::fs::OpenOptionsExt; + + OpenOptions::new().custom_flags(libc::O_NOFOLLOW).open(path)?.set_permissions(perm) +} + +#[cfg(not(unix))] +pub fn set_permissions_nofollow(_path: &Path, _perm: crate::fs::Permissions) -> io::Result<()> { + crate::unimplemented!( + "`set_permissions_nofollow` is currently only implemented on Unix platforms" + ) +} + pub fn canonicalize(path: &Path) -> io::Result<PathBuf> { with_native_path(path, &imp::canonicalize) } diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index b310db2dac4..7ee9f3c445a 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -101,10 +101,11 @@ pub struct File(FileDesc); // https://github.com/rust-lang/rust/pull/67774 macro_rules! cfg_has_statx { ({ $($then_tt:tt)* } else { $($else_tt:tt)* }) => { - cfg_if::cfg_if! { - if #[cfg(all(target_os = "linux", target_env = "gnu"))] { + cfg_select! { + all(target_os = "linux", target_env = "gnu") => { $($then_tt)* - } else { + } + _ => { $($else_tt)* } } @@ -1263,6 +1264,7 @@ impl File { target_os = "fuchsia", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_vendor = "apple", ))] pub fn lock(&self) -> io::Result<()> { @@ -1275,6 +1277,7 @@ impl File { target_os = "fuchsia", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_vendor = "apple", )))] pub fn lock(&self) -> io::Result<()> { @@ -1286,6 +1289,7 @@ impl File { target_os = "fuchsia", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_vendor = "apple", ))] pub fn lock_shared(&self) -> io::Result<()> { @@ -1298,6 +1302,7 @@ impl File { target_os = "fuchsia", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_vendor = "apple", )))] pub fn lock_shared(&self) -> io::Result<()> { @@ -1309,6 +1314,7 @@ impl File { target_os = "fuchsia", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_vendor = "apple", ))] pub fn try_lock(&self) -> Result<(), TryLockError> { @@ -1329,6 +1335,7 @@ impl File { target_os = "fuchsia", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_vendor = "apple", )))] pub fn try_lock(&self) -> Result<(), TryLockError> { @@ -1343,6 +1350,7 @@ impl File { target_os = "fuchsia", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_vendor = "apple", ))] pub fn try_lock_shared(&self) -> Result<(), TryLockError> { @@ -1363,6 +1371,7 @@ impl File { target_os = "fuchsia", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_vendor = "apple", )))] pub fn try_lock_shared(&self) -> Result<(), TryLockError> { @@ -1377,6 +1386,7 @@ impl File { target_os = "fuchsia", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_vendor = "apple", ))] pub fn unlock(&self) -> io::Result<()> { @@ -1389,6 +1399,7 @@ impl File { target_os = "fuchsia", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_vendor = "apple", )))] pub fn unlock(&self) -> io::Result<()> { @@ -1505,8 +1516,8 @@ impl File { )), None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }), }; - cfg_if::cfg_if! { - if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx"))] { + cfg_select! { + any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx") => { // Redox doesn't appear to support `UTIME_OMIT`. // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore // the same as for Redox. @@ -1515,7 +1526,8 @@ impl File { io::ErrorKind::Unsupported, "setting file times not supported", )) - } else if #[cfg(target_vendor = "apple")] { + } + target_vendor = "apple" => { let mut buf = [mem::MaybeUninit::<libc::timespec>::uninit(); 3]; let mut num_times = 0; let mut attrlist: libc::attrlist = unsafe { mem::zeroed() }; @@ -1543,7 +1555,8 @@ impl File { 0 ) })?; Ok(()) - } else if #[cfg(target_os = "android")] { + } + target_os = "android" => { let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?]; // futimens requires Android API level 19 cvt(unsafe { @@ -1559,7 +1572,8 @@ impl File { } })?; Ok(()) - } else { + } + _ => { #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))] { use crate::sys::{time::__timespec64, weak::weak}; @@ -1677,13 +1691,14 @@ impl fmt::Debug for File { let mut buf = vec![0; libc::PATH_MAX as usize]; let n = unsafe { libc::fcntl(fd, libc::F_GETPATH, buf.as_ptr()) }; if n == -1 { - cfg_if::cfg_if! { - if #[cfg(target_os = "netbsd")] { + cfg_select! { + target_os = "netbsd" => { // fallback to procfs as last resort let mut p = PathBuf::from("/proc/self/fd"); p.push(&fd.to_string()); return run_path_with_cstr(&p, &readlink).ok() - } else { + } + _ => { return None; } } @@ -1884,15 +1899,16 @@ pub fn symlink(original: &CStr, link: &CStr) -> io::Result<()> { } pub fn link(original: &CStr, link: &CStr) -> io::Result<()> { - cfg_if::cfg_if! { - if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_env = "nto70"))] { + cfg_select! { + any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_env = "nto70") => { // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves // it implementation-defined whether `link` follows symlinks, so rely on the // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior. // Android has `linkat` on newer versions, but we happen to know `link` // always has the correct behavior, so it's here as well. cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?; - } else { + } + _ => { // Where we can, use `linkat` instead of `link`; see the comment above // this one for details on why. cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?; diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs index ae75f4d97b4..fe8ec1dbb73 100644 --- a/library/std/src/sys/io/mod.rs +++ b/library/std/src/sys/io/mod.rs @@ -1,20 +1,24 @@ #![forbid(unsafe_op_in_unsafe_fn)] mod io_slice { - cfg_if::cfg_if! { - if #[cfg(any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty"))] { + cfg_select! { + any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty") => { mod iovec; pub use iovec::*; - } else if #[cfg(target_os = "windows")] { + } + target_os = "windows" => { mod windows; pub use windows::*; - } else if #[cfg(target_os = "wasi")] { + } + target_os = "wasi" => { mod wasi; pub use wasi::*; - } else if #[cfg(target_os = "uefi")] { + } + target_os = "uefi" => { mod uefi; pub use uefi::*; - } else { + } + _ => { mod unsupported; pub use unsupported::*; } @@ -22,17 +26,20 @@ mod io_slice { } mod is_terminal { - cfg_if::cfg_if! { - if #[cfg(any(target_family = "unix", target_os = "wasi"))] { + cfg_select! { + any(target_family = "unix", target_os = "wasi") => { mod isatty; pub use isatty::*; - } else if #[cfg(target_os = "windows")] { + } + target_os = "windows" => { mod windows; pub use windows::*; - } else if #[cfg(target_os = "hermit")] { + } + target_os = "hermit" => { mod hermit; pub use hermit::*; - } else { + } + _ => { mod unsupported; pub use unsupported::*; } diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 8ec0a0e3302..6324c1a232a 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -1,7 +1,7 @@ #![allow(unsafe_op_in_unsafe_fn)] /// The configure builtins provides runtime support compiler-builtin features -/// which require dynamic intialization to work as expected, e.g. aarch64 +/// which require dynamic initialization to work as expected, e.g. aarch64 /// outline-atomics. mod configure_builtins; diff --git a/library/std/src/sys/net/connection/socket.rs b/library/std/src/sys/net/connection/socket.rs index 7301bde6881..aa83ed65d4c 100644 --- a/library/std/src/sys/net/connection/socket.rs +++ b/library/std/src/sys/net/connection/socket.rs @@ -9,29 +9,34 @@ use crate::sys_common::{AsInner, FromInner}; use crate::time::Duration; use crate::{cmp, fmt, mem, ptr}; -cfg_if::cfg_if! { - if #[cfg(target_os = "hermit")] { +cfg_select! { + target_os = "hermit" => { mod hermit; pub use hermit::*; - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod solid; pub use solid::*; - } else if #[cfg(target_family = "unix")] { + } + target_family = "unix" => { mod unix; pub use unix::*; - } else if #[cfg(all(target_os = "wasi", target_env = "p2"))] { + } + all(target_os = "wasi", target_env = "p2") => { mod wasip2; pub use wasip2::*; - } else if #[cfg(target_os = "windows")] { + } + target_os = "windows" => { mod windows; pub use windows::*; } + _ => {} } use netc as c; -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", @@ -43,39 +48,44 @@ cfg_if::cfg_if! { target_os = "nto", target_os = "nuttx", target_vendor = "apple", - ))] { + ) => { use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; - } else { + } + _ => { use c::IPV6_ADD_MEMBERSHIP; use c::IPV6_DROP_MEMBERSHIP; } } -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( target_os = "linux", target_os = "android", target_os = "hurd", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "solaris", target_os = "illumos", target_os = "haiku", target_os = "nto", - target_os = "cygwin"))] { + target_os = "cygwin", + ) => { use libc::MSG_NOSIGNAL; - } else { + } + _ => { const MSG_NOSIGNAL: c_int = 0x0; } } -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "solaris", target_os = "illumos", - target_os = "nto"))] { + target_os = "nto", + ) => { use crate::ffi::c_uchar; type IpV4MultiCastType = c_uchar; - } else { + } + _ => { type IpV4MultiCastType = c_int; } } @@ -523,17 +533,19 @@ impl TcpListener { let (addr, len) = socket_addr_to_c(addr); cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?; - cfg_if::cfg_if! { - if #[cfg(target_os = "horizon")] { + cfg_select! { + target_os = "horizon" => { // The 3DS doesn't support a big connection backlog. Sometimes // it allows up to about 37, but other times it doesn't even // accept 32. There may be a global limitation causing this. let backlog = 20; - } else if #[cfg(target_os = "haiku")] { + } + target_os = "haiku" => { // Haiku does not support a queue length > 32 // https://github.com/haiku/haiku/blob/979a0bc487864675517fb2fab28f87dc8bf43041/headers/posix/sys/socket.h#L81 let backlog = 32; - } else { + } + _ => { // The default for all other platforms let backlog = 128; } diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index cc111f3521b..8b5970d1494 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -12,10 +12,11 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::time::{Duration, Instant}; use crate::{cmp, mem}; -cfg_if::cfg_if! { - if #[cfg(target_vendor = "apple")] { +cfg_select! { + target_vendor = "apple" => { use libc::SO_LINGER_SEC as SO_LINGER; - } else { + } + _ => { use libc::SO_LINGER; } } @@ -72,8 +73,8 @@ impl Socket { pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> { unsafe { - cfg_if::cfg_if! { - if #[cfg(any( + cfg_select! { + any( target_os = "android", target_os = "dragonfly", target_os = "freebsd", @@ -85,7 +86,7 @@ impl Socket { target_os = "cygwin", target_os = "nto", target_os = "solaris", - ))] { + ) => { // On platforms that support it we pass the SOCK_CLOEXEC // flag to atomically create the socket and set it as // CLOEXEC. On Linux this was added in 2.6.27. @@ -98,7 +99,8 @@ impl Socket { setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?; Ok(socket) - } else { + } + _ => { let fd = cvt(libc::socket(fam, ty, 0))?; let fd = FileDesc::from_raw_fd(fd); fd.set_cloexec()?; @@ -120,8 +122,8 @@ impl Socket { unsafe { let mut fds = [0, 0]; - cfg_if::cfg_if! { - if #[cfg(any( + cfg_select! { + any( target_os = "android", target_os = "dragonfly", target_os = "freebsd", @@ -132,11 +134,12 @@ impl Socket { target_os = "openbsd", target_os = "cygwin", target_os = "nto", - ))] { + ) => { // Like above, set cloexec atomically cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr()))?; Ok((Socket(FileDesc::from_raw_fd(fds[0])), Socket(FileDesc::from_raw_fd(fds[1])))) - } else { + } + _ => { cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?; let a = FileDesc::from_raw_fd(fds[0]); let b = FileDesc::from_raw_fd(fds[1]); @@ -250,8 +253,8 @@ impl Socket { // atomically set the CLOEXEC flag is to use the `accept4` syscall on // platforms that support it. On Linux, this was added in 2.6.28, // glibc 2.10 and musl 0.9.5. - cfg_if::cfg_if! { - if #[cfg(any( + cfg_select! { + any( target_os = "android", target_os = "dragonfly", target_os = "freebsd", @@ -261,12 +264,13 @@ impl Socket { target_os = "netbsd", target_os = "openbsd", target_os = "cygwin", - ))] { + ) => { unsafe { let fd = cvt_r(|| libc::accept4(self.as_raw_fd(), storage, len, libc::SOCK_CLOEXEC))?; Ok(Socket(FileDesc::from_raw_fd(fd))) } - } else { + } + _ => { unsafe { let fd = cvt_r(|| libc::accept(self.as_raw_fd(), storage, len))?; let fd = FileDesc::from_raw_fd(fd); diff --git a/library/std/src/sys/net/mod.rs b/library/std/src/sys/net/mod.rs index 646679a1cc8..5df1fe138ab 100644 --- a/library/std/src/sys/net/mod.rs +++ b/library/std/src/sys/net/mod.rs @@ -1,36 +1,41 @@ -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( all(target_family = "unix", not(target_os = "l4re")), target_os = "windows", target_os = "hermit", all(target_os = "wasi", target_env = "p2"), target_os = "solid_asp3", - ))] { + ) => { mod connection { mod socket; pub use socket::*; } - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod connection { mod sgx; pub use sgx::*; } - } else if #[cfg(all(target_os = "wasi", target_env = "p1"))] { + } + all(target_os = "wasi", target_env = "p1") => { mod connection { mod wasip1; pub use wasip1::*; } - } else if #[cfg(target_os = "xous")] { + } + target_os = "xous" => { mod connection { mod xous; pub use xous::*; } - } else if #[cfg(target_os = "uefi")] { + } + target_os = "uefi" => { mod connection { mod uefi; pub use uefi::*; } - } else { + } + _ => { mod connection { mod unsupported; pub use unsupported::*; diff --git a/library/std/src/sys/os_str/mod.rs b/library/std/src/sys/os_str/mod.rs index 345e661586d..65c90d88049 100644 --- a/library/std/src/sys/os_str/mod.rs +++ b/library/std/src/sys/os_str/mod.rs @@ -1,13 +1,11 @@ #![forbid(unsafe_op_in_unsafe_fn)] -cfg_if::cfg_if! { - if #[cfg(any( - target_os = "windows", - target_os = "uefi", - ))] { +cfg_select! { + any(target_os = "windows", target_os = "uefi") => { mod wtf8; pub use wtf8::{Buf, Slice}; - } else { + } + _ => { mod bytes; pub use bytes::{Buf, Slice}; } diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index fbefc62ac88..9376f5249f1 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -24,60 +24,70 @@ pub mod common; -cfg_if::cfg_if! { - if #[cfg(unix)] { +cfg_select! { + unix => { mod unix; pub use self::unix::*; - } else if #[cfg(windows)] { + } + windows => { mod windows; pub use self::windows::*; - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod solid; pub use self::solid::*; - } else if #[cfg(target_os = "hermit")] { + } + target_os = "hermit" => { mod hermit; pub use self::hermit::*; - } else if #[cfg(target_os = "trusty")] { + } + target_os = "trusty" => { mod trusty; pub use self::trusty::*; - } else if #[cfg(all(target_os = "wasi", target_env = "p2"))] { + } + all(target_os = "wasi", target_env = "p2") => { mod wasip2; pub use self::wasip2::*; - } else if #[cfg(target_os = "wasi")] { + } + target_os = "wasi" => { mod wasi; pub use self::wasi::*; - } else if #[cfg(target_family = "wasm")] { + } + target_family = "wasm" => { mod wasm; pub use self::wasm::*; - } else if #[cfg(target_os = "xous")] { + } + target_os = "xous" => { mod xous; pub use self::xous::*; - } else if #[cfg(target_os = "uefi")] { + } + target_os = "uefi" => { mod uefi; pub use self::uefi::*; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod sgx; pub use self::sgx::*; - } else if #[cfg(target_os = "teeos")] { + } + target_os = "teeos" => { mod teeos; pub use self::teeos::*; - } else if #[cfg(target_os = "zkvm")] { + } + target_os = "zkvm" => { mod zkvm; pub use self::zkvm::*; - } else { + } + _ => { mod unsupported; pub use self::unsupported::*; } } -cfg_if::cfg_if! { +pub const FULL_BACKTRACE_DEFAULT: bool = cfg_select! { // Fuchsia components default to full backtrace. - if #[cfg(target_os = "fuchsia")] { - pub const FULL_BACKTRACE_DEFAULT: bool = true; - } else { - pub const FULL_BACKTRACE_DEFAULT: bool = false; - } -} + target_os = "fuchsia" => true, + _ => false, +}; #[cfg(not(target_os = "uefi"))] pub type RawOsError = i32; diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs index df5611b2ddd..36ce3f7ef96 100644 --- a/library/std/src/sys/pal/uefi/time.rs +++ b/library/std/src/sys/pal/uefi/time.rs @@ -188,7 +188,7 @@ pub(crate) mod system_time_internal { Duration::new(epoch, t.nanosecond) } - /// This algorithm is a modifed version of the one described in the post: + /// This algorithm is a modified version of the one described in the post: /// https://howardhinnant.github.io/date_algorithms.html#clive_from_days /// /// The changes are to use 1900-01-01-00:00:00 with timezone -1440 as anchor instead of UNIX @@ -197,7 +197,7 @@ pub(crate) mod system_time_internal { // Check timzone validity assert!(timezone <= 1440 && timezone >= -1440); - // FIXME(#126043): use checked_sub_signed once stablized + // FIXME(#126043): use checked_sub_signed once stabilized let secs = dur.as_secs().checked_add_signed((-timezone as i64) * SECS_IN_MINUTE as i64).unwrap(); @@ -296,12 +296,9 @@ pub(crate) mod instant_internal { } pub fn platform_specific() -> Option<Instant> { - cfg_if::cfg_if! { - if #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] { - timestamp_rdtsc().map(Instant) - } else { - None - } + cfg_select! { + any(target_arch = "x86_64", target_arch = "x86") => timestamp_rdtsc().map(Instant), + _ => None, } } diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs index c23278bdf5e..265067d84d5 100644 --- a/library/std/src/sys/pal/unix/futex.rs +++ b/library/std/src/sys/pal/unix/futex.rs @@ -46,8 +46,8 @@ pub fn futex_wait(futex: &Atomic<u32>, expected: u32, timeout: Option<Duration>) } let r = unsafe { - cfg_if::cfg_if! { - if #[cfg(target_os = "freebsd")] { + cfg_select! { + target_os = "freebsd" => { // FreeBSD doesn't have futex(), but it has // _umtx_op(UMTX_OP_WAIT_UINT_PRIVATE), which is nearly // identical. It supports absolute timeouts through a flag @@ -66,7 +66,8 @@ pub fn futex_wait(futex: &Atomic<u32>, expected: u32, timeout: Option<Duration>) crate::ptr::without_provenance_mut(umtx_timeout_size), umtx_timeout_ptr as *mut _, ) - } else if #[cfg(any(target_os = "linux", target_os = "android"))] { + } + any(target_os = "linux", target_os = "android") => { // Use FUTEX_WAIT_BITSET rather than FUTEX_WAIT to be able to give an // absolute time rather than a relative time. libc::syscall( @@ -78,7 +79,8 @@ pub fn futex_wait(futex: &Atomic<u32>, expected: u32, timeout: Option<Duration>) null::<u32>(), // This argument is unused for FUTEX_WAIT_BITSET. !0u32, // A full bitmask, to make it behave like a regular FUTEX_WAIT. ) - } else { + } + _ => { compile_error!("unknown target_os"); } } diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index ba9e14b8009..fede3673eb6 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -366,31 +366,36 @@ pub fn abort_internal() -> ! { unsafe { libc::abort() } } -cfg_if::cfg_if! { - if #[cfg(target_os = "android")] { +cfg_select! { + target_os = "android" => { #[link(name = "dl", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] #[link(name = "dl", cfg(not(target_feature = "crt-static")))] #[link(name = "log", cfg(not(target_feature = "crt-static")))] unsafe extern "C" {} - } else if #[cfg(target_os = "freebsd")] { + } + target_os = "freebsd" => { #[link(name = "execinfo")] #[link(name = "pthread")] unsafe extern "C" {} - } else if #[cfg(target_os = "netbsd")] { + } + target_os = "netbsd" => { #[link(name = "pthread")] #[link(name = "rt")] unsafe extern "C" {} - } else if #[cfg(any(target_os = "dragonfly", target_os = "openbsd", target_os = "cygwin"))] { + } + any(target_os = "dragonfly", target_os = "openbsd", target_os = "cygwin") => { #[link(name = "pthread")] unsafe extern "C" {} - } else if #[cfg(target_os = "solaris")] { + } + target_os = "solaris" => { #[link(name = "socket")] #[link(name = "posix4")] #[link(name = "pthread")] #[link(name = "resolv")] unsafe extern "C" {} - } else if #[cfg(target_os = "illumos")] { + } + target_os = "illumos" => { #[link(name = "socket")] #[link(name = "posix4")] #[link(name = "pthread")] @@ -399,24 +404,29 @@ cfg_if::cfg_if! { // Use libumem for the (malloc-compatible) allocator #[link(name = "umem")] unsafe extern "C" {} - } else if #[cfg(target_vendor = "apple")] { + } + target_vendor = "apple" => { // Link to `libSystem.dylib`. // // Don't get confused by the presence of `System.framework`, // it is a deprecated wrapper over the dynamic library. #[link(name = "System")] unsafe extern "C" {} - } else if #[cfg(target_os = "fuchsia")] { + } + target_os = "fuchsia" => { #[link(name = "zircon")] #[link(name = "fdio")] unsafe extern "C" {} - } else if #[cfg(all(target_os = "linux", target_env = "uclibc"))] { + } + all(target_os = "linux", target_env = "uclibc") => { #[link(name = "dl")] unsafe extern "C" {} - } else if #[cfg(target_os = "vita")] { + } + target_os = "vita" => { #[link(name = "pthread", kind = "static", modifiers = "-bundle")] unsafe extern "C" {} } + _ => {} } #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index 0e68313cc3e..1110b775c09 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -17,13 +17,10 @@ use crate::{fmt, io, iter, mem, ptr, slice, str}; const TMPBUF_SZ: usize = 128; -cfg_if::cfg_if! { - if #[cfg(target_os = "redox")] { - const PATH_SEPARATOR: u8 = b';'; - } else { - const PATH_SEPARATOR: u8 = b':'; - } -} +const PATH_SEPARATOR: u8 = cfg_select! { + target_os = "redox" => b';', + _ => b':', +}; unsafe extern "C" { #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))] @@ -620,14 +617,10 @@ fn darwin_temp_dir() -> PathBuf { pub fn temp_dir() -> PathBuf { crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| { - cfg_if::cfg_if! { - if #[cfg(all(target_vendor = "apple", not(miri)))] { - darwin_temp_dir() - } else if #[cfg(target_os = "android")] { - PathBuf::from("/data/local/tmp") - } else { - PathBuf::from("/tmp") - } + cfg_select! { + all(target_vendor = "apple", not(miri)) => darwin_temp_dir(), + target_os = "android" => PathBuf::from("/data/local/tmp"), + _ => PathBuf::from("/tmp"), } }) } diff --git a/library/std/src/sys/pal/unix/pipe.rs b/library/std/src/sys/pal/unix/pipe.rs index 55510153dc8..6b0cd14da4f 100644 --- a/library/std/src/sys/pal/unix/pipe.rs +++ b/library/std/src/sys/pal/unix/pipe.rs @@ -18,8 +18,8 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { // The only known way right now to create atomically set the CLOEXEC flag is // to use the `pipe2` syscall. This was added to Linux in 2.6.27, glibc 2.9 // and musl 0.9.3, and some other targets also have it. - cfg_if::cfg_if! { - if #[cfg(any( + cfg_select! { + any( target_os = "dragonfly", target_os = "freebsd", target_os = "hurd", @@ -29,12 +29,13 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { target_os = "openbsd", target_os = "cygwin", target_os = "redox" - ))] { + ) => { unsafe { cvt(libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC))?; Ok((AnonPipe(FileDesc::from_raw_fd(fds[0])), AnonPipe(FileDesc::from_raw_fd(fds[1])))) } - } else { + } + _ => { unsafe { cvt(libc::pipe(fds.as_mut_ptr()))?; diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 24b65c11fd2..3389b8c0c8a 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -151,12 +151,13 @@ impl Thread { ))] pub fn set_name(name: &CStr) { unsafe { - cfg_if::cfg_if! { - if #[cfg(any(target_os = "linux", target_os = "cygwin"))] { + cfg_select! { + any(target_os = "linux", target_os = "cygwin") => { // Linux and Cygwin limits the allowed length of the name. const TASK_COMM_LEN: usize = 16; let name = truncate_cstr::<{ TASK_COMM_LEN }>(name); - } else { + } + _ => { // FreeBSD, DragonFly BSD and NuttX do not enforce length limits. } }; @@ -415,9 +416,9 @@ pub(crate) fn current_os_id() -> Option<u64> { // // The OS thread ID is used rather than `pthread_self` so as to match what will be displayed // for process inspection (debuggers, trace, `top`, etc.). - cfg_if::cfg_if! { + cfg_select! { // Most platforms have a function returning a `pid_t` or int, which is an `i32`. - if #[cfg(any(target_os = "android", target_os = "linux"))] { + any(target_os = "android", target_os = "linux") => { use crate::sys::weak::syscall; // `libc::gettid` is only available on glibc 2.30+, but the syscall is available @@ -427,28 +428,34 @@ pub(crate) fn current_os_id() -> Option<u64> { // SAFETY: FFI call with no preconditions. let id: libc::pid_t = unsafe { gettid() }; Some(id as u64) - } else if #[cfg(target_os = "nto")] { + } + target_os = "nto" => { // SAFETY: FFI call with no preconditions. let id: libc::pid_t = unsafe { libc::gettid() }; Some(id as u64) - } else if #[cfg(target_os = "openbsd")] { + } + target_os = "openbsd" => { // SAFETY: FFI call with no preconditions. let id: libc::pid_t = unsafe { libc::getthrid() }; Some(id as u64) - } else if #[cfg(target_os = "freebsd")] { + } + target_os = "freebsd" => { // SAFETY: FFI call with no preconditions. let id: libc::c_int = unsafe { libc::pthread_getthreadid_np() }; Some(id as u64) - } else if #[cfg(target_os = "netbsd")] { + } + target_os = "netbsd" => { // SAFETY: FFI call with no preconditions. let id: libc::lwpid_t = unsafe { libc::_lwp_self() }; Some(id as u64) - } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] { + } + any(target_os = "illumos", target_os = "solaris") => { // On Illumos and Solaris, the `pthread_t` is the same as the OS thread ID. // SAFETY: FFI call with no preconditions. let id: libc::pthread_t = unsafe { libc::pthread_self() }; Some(id as u64) - } else if #[cfg(target_vendor = "apple")] { + } + target_vendor = "apple" => { // Apple allows querying arbitrary thread IDs, `thread=NULL` queries the current thread. let mut id = 0u64; // SAFETY: `thread_id` is a valid pointer, no other preconditions. @@ -458,10 +465,9 @@ pub(crate) fn current_os_id() -> Option<u64> { } else { None } - } else { - // Other platforms don't have an OS thread ID or don't have a way to access it. - None } + // Other platforms don't have an OS thread ID or don't have a way to access it. + _ => None, } } @@ -483,8 +489,8 @@ fn truncate_cstr<const MAX_WITH_NUL: usize>(cstr: &CStr) -> [libc::c_char; MAX_W } pub fn available_parallelism() -> io::Result<NonZero<usize>> { - cfg_if::cfg_if! { - if #[cfg(any( + cfg_select! { + any( target_os = "android", target_os = "emscripten", target_os = "fuchsia", @@ -493,7 +499,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> { target_os = "aix", target_vendor = "apple", target_os = "cygwin", - ))] { + ) => { #[allow(unused_assignments)] #[allow(unused_mut)] let mut quota = usize::MAX; @@ -527,12 +533,13 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> { Ok(unsafe { NonZero::new_unchecked(count) }) } } - } else if #[cfg(any( - target_os = "freebsd", - target_os = "dragonfly", - target_os = "openbsd", - target_os = "netbsd", - ))] { + } + any( + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd", + target_os = "netbsd", + ) => { use crate::ptr; #[cfg(target_os = "freebsd")] @@ -607,7 +614,8 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> { } Ok(unsafe { NonZero::new_unchecked(cpus as usize) }) - } else if #[cfg(target_os = "nto")] { + } + target_os = "nto" => { unsafe { use libc::_syspage_ptr; if _syspage_ptr.is_null() { @@ -618,13 +626,15 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> { .ok_or(io::Error::UNKNOWN_THREAD_COUNT) } } - } else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] { + } + any(target_os = "solaris", target_os = "illumos") => { let mut cpus = 0u32; if unsafe { libc::pset_info(libc::PS_MYID, core::ptr::null_mut(), &mut cpus, core::ptr::null_mut()) } != 0 { return Err(io::Error::UNKNOWN_THREAD_COUNT); } Ok(unsafe { NonZero::new_unchecked(cpus as usize) }) - } else if #[cfg(target_os = "haiku")] { + } + target_os = "haiku" => { // system_info cpu_count field gets the static data set at boot time with `smp_set_num_cpus` // `get_system_info` calls then `smp_get_num_cpus` unsafe { @@ -637,7 +647,8 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> { Ok(NonZero::new_unchecked(sinfo.cpu_count as usize)) } - } else if #[cfg(target_os = "vxworks")] { + } + target_os = "vxworks" => { // Note: there is also `vxCpuConfiguredGet`, closer to _SC_NPROCESSORS_CONF // expectations than the actual cores availability. unsafe extern "C" { @@ -649,7 +660,8 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> { let set = vxCpuEnabledGet(); Ok(NonZero::new_unchecked(set.count_ones() as usize)) } - } else { + } + _ => { // FIXME: implement on Redox, l4re Err(io::const_error!(io::ErrorKind::Unsupported, "getting the number of hardware threads is not supported on the target platform")) } diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs index 4755e2ef5da..e062b49bd7a 100644 --- a/library/std/src/sys/pal/wasi/thread.rs +++ b/library/std/src/sys/pal/wasi/thread.rs @@ -5,8 +5,8 @@ use crate::num::NonZero; use crate::time::{Duration, Instant}; use crate::{io, mem}; -cfg_if::cfg_if! { - if #[cfg(target_feature = "atomics")] { +cfg_select! { + target_feature = "atomics" => { use crate::cmp; use crate::ptr; use crate::sys::os; @@ -62,7 +62,8 @@ cfg_if::cfg_if! { debug_assert_eq!(ret, 0); } } - } else { + } + _ => { pub struct Thread(!); } } @@ -71,8 +72,8 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024; impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements - cfg_if::cfg_if! { - if #[cfg(target_feature = "atomics")] { + cfg_select! { + target_feature = "atomics" => { pub unsafe fn new(stack: usize, _name: Option<&str>, p: Box<dyn FnOnce()>) -> io::Result<Thread> { let p = Box::into_raw(Box::new(p)); let mut native: libc::pthread_t = unsafe { mem::zeroed() }; @@ -119,7 +120,8 @@ impl Thread { ptr::null_mut() } } - } else { + } + _ => { pub unsafe fn new(_stack: usize, _name: Option<&str>, _p: Box<dyn FnOnce()>) -> io::Result<Thread> { crate::sys::unsupported() } @@ -180,14 +182,15 @@ impl Thread { } pub fn join(self) { - cfg_if::cfg_if! { - if #[cfg(target_feature = "atomics")] { + cfg_select! { + target_feature = "atomics" => { let id = mem::ManuallyDrop::new(self).id; let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; if ret != 0 { rtabort!("failed to join thread: {}", io::Error::from_raw_os_error(ret)); } - } else { + } + _ => { self.0 } } @@ -199,14 +202,13 @@ pub(crate) fn current_os_id() -> Option<u64> { } pub fn available_parallelism() -> io::Result<NonZero<usize>> { - cfg_if::cfg_if! { - if #[cfg(target_feature = "atomics")] { + cfg_select! { + target_feature = "atomics" => { match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } { -1 => Err(io::Error::last_os_error()), cpus => NonZero::new(cpus as usize).ok_or(io::Error::UNKNOWN_THREAD_COUNT), } - } else { - crate::sys::unsupported() } + _ => crate::sys::unsupported(), } } diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs index 37cb46a8f6b..346c9ff88c9 100644 --- a/library/std/src/sys/pal/wasm/mod.rs +++ b/library/std/src/sys/pal/wasm/mod.rs @@ -23,13 +23,14 @@ pub mod pipe; #[path = "../unsupported/time.rs"] pub mod time; -cfg_if::cfg_if! { - if #[cfg(target_feature = "atomics")] { +cfg_select! { + target_feature = "atomics" => { #[path = "atomics/futex.rs"] pub mod futex; #[path = "atomics/thread.rs"] pub mod thread; - } else { + } + _ => { #[path = "../unsupported/thread.rs"] pub mod thread; } diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index edac5262a4e..25c1a82cc42 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -95,11 +95,8 @@ pub struct MOUNT_POINT_REPARSE_BUFFER { } // Desktop specific functions & types -cfg_if::cfg_if! { -if #[cfg(not(target_vendor = "uwp"))] { - pub const EXCEPTION_CONTINUE_SEARCH: i32 = 0; -} -} +#[cfg(not(target_vendor = "uwp"))] +pub const EXCEPTION_CONTINUE_SEARCH: i32 = 0; // Use raw-dylib to import ProcessPrng as we can't rely on there being an import library. #[cfg(not(target_vendor = "win7"))] @@ -230,12 +227,13 @@ compat_fn_with_fallback! { } } -cfg_if::cfg_if! { - if #[cfg(target_vendor = "uwp")] { +cfg_select! { + target_vendor = "uwp" => { windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtCreateFile(filehandle : *mut HANDLE, desiredaccess : FILE_ACCESS_RIGHTS, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, allocationsize : *const i64, fileattributes : FILE_FLAGS_AND_ATTRIBUTES, shareaccess : FILE_SHARE_MODE, createdisposition : NTCREATEFILE_CREATE_DISPOSITION, createoptions : NTCREATEFILE_CREATE_OPTIONS, eabuffer : *const core::ffi::c_void, ealength : u32) -> NTSTATUS); windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtOpenFile(filehandle : *mut HANDLE, desiredaccess : u32, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, shareaccess : u32, openoptions : u32) -> NTSTATUS); windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtReadFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *mut core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS); windows_targets::link_raw_dylib!("ntdll.dll" "system" fn NtWriteFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *const core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS); windows_targets::link_raw_dylib!("ntdll.dll" "system" fn RtlNtStatusToDosError(status : NTSTATUS) -> u32); } + _ => {} } diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 8f54e2376eb..10ad4541bed 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -22,10 +22,11 @@ pub mod os; pub mod pipe; pub mod thread; pub mod time; -cfg_if::cfg_if! { - if #[cfg(not(target_vendor = "uwp"))] { +cfg_select! { + not(target_vendor = "uwp") => { pub mod stack_overflow; - } else { + } + _ => { pub mod stack_overflow_uwp; pub use self::stack_overflow_uwp as stack_overflow; } @@ -337,14 +338,17 @@ pub fn dur2timeout(dur: Duration) -> u32 { #[cfg(not(miri))] // inline assembly does not work in Miri pub fn abort_internal() -> ! { unsafe { - cfg_if::cfg_if! { - if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + cfg_select! { + any(target_arch = "x86", target_arch = "x86_64") => { core::arch::asm!("int $$0x29", in("ecx") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); - } else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] { + } + all(target_arch = "arm", target_feature = "thumb-mode") => { core::arch::asm!(".inst 0xDEFB", in("r0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); - } else if #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] { + } + any(target_arch = "aarch64", target_arch = "arm64ec") => { core::arch::asm!("brk 0xF003", in("x0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); - } else { + } + _ => { core::intrinsics::abort(); } } diff --git a/library/std/src/sys/path/mod.rs b/library/std/src/sys/path/mod.rs index a4ff4338cf5..254683bc83f 100644 --- a/library/std/src/sys/path/mod.rs +++ b/library/std/src/sys/path/mod.rs @@ -1,22 +1,27 @@ -cfg_if::cfg_if! { - if #[cfg(target_os = "windows")] { +cfg_select! { + target_os = "windows" => { mod windows; mod windows_prefix; pub use windows::*; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod sgx; pub use sgx::*; - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod unsupported_backslash; pub use unsupported_backslash::*; - } else if #[cfg(target_os = "uefi")] { + } + target_os = "uefi" => { mod uefi; pub use uefi::*; - } else if #[cfg(target_os = "cygwin")] { + } + target_os = "cygwin" => { mod cygwin; mod windows_prefix; pub use cygwin::*; - } else { + } + _ => { mod unix; pub use unix::*; } diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs index 75e793f18b8..019d5629d6d 100644 --- a/library/std/src/sys/personality/gcc.rs +++ b/library/std/src/sys/personality/gcc.rs @@ -93,12 +93,12 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1 // https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c -cfg_if::cfg_if! { - if #[cfg(all( +cfg_select! { + all( target_arch = "arm", not(target_vendor = "apple"), not(target_os = "netbsd"), - ))] { + ) => { /// personality fn called by [ARM EHABI][armeabi-eh] /// /// 32-bit ARM on iOS/tvOS/watchOS does not use ARM EHABI, it uses @@ -202,7 +202,8 @@ cfg_if::cfg_if! { } } } - } else { + } + _ => { /// Default personality routine, which is used directly on most targets /// and indirectly on Windows x86_64 and AArch64 via SEH. unsafe extern "C" fn rust_eh_personality_impl( @@ -247,11 +248,11 @@ cfg_if::cfg_if! { } } - cfg_if::cfg_if! { - if #[cfg(any( - all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"), - target_os = "cygwin", - ))] { + cfg_select! { + any( + all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"), + target_os = "cygwin", + ) => { /// personality fn called by [Windows Structured Exception Handling][windows-eh] /// /// On x86_64 and AArch64 MinGW targets, the unwinding mechanism is SEH, @@ -279,7 +280,8 @@ cfg_if::cfg_if! { ) } } - } else { + } + _ => { /// personality fn called by [Itanium C++ ABI Exception Handling][itanium-eh] /// /// The personality routine for most non-Windows targets. This will be called by diff --git a/library/std/src/sys/personality/mod.rs b/library/std/src/sys/personality/mod.rs index 2e1d2e53a29..158e44e1764 100644 --- a/library/std/src/sys/personality/mod.rs +++ b/library/std/src/sys/personality/mod.rs @@ -13,10 +13,11 @@ mod dwarf; #[cfg(not(any(test, doctest)))] -cfg_if::cfg_if! { - if #[cfg(target_os = "emscripten")] { +cfg_select! { + target_os = "emscripten" => { mod emcc; - } else if #[cfg(any(target_env = "msvc", target_family = "wasm"))] { + } + any(target_env = "msvc", target_family = "wasm") => { // This is required by the compiler to exist (e.g., it's a lang item), // but it's never actually called by the compiler because // __CxxFrameHandler3 (msvc) / __gxx_wasm_personality_v0 (wasm) is the @@ -26,16 +27,18 @@ cfg_if::cfg_if! { fn rust_eh_personality() { core::intrinsics::abort() } - } else if #[cfg(any( + } + any( all(target_family = "windows", target_env = "gnu"), target_os = "psp", target_os = "xous", target_os = "solid_asp3", all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "nuttx")), all(target_vendor = "fortanix", target_env = "sgx"), - ))] { + ) => { mod gcc; - } else { + } + _ => { // Targets that don't support unwinding. // - os=none ("bare metal" targets) // - os=uefi diff --git a/library/std/src/sys/process/mod.rs b/library/std/src/sys/process/mod.rs index 91c7005a328..9ef5496e57a 100644 --- a/library/std/src/sys/process/mod.rs +++ b/library/std/src/sys/process/mod.rs @@ -1,14 +1,17 @@ -cfg_if::cfg_if! { - if #[cfg(target_family = "unix")] { +cfg_select! { + target_family = "unix" => { mod unix; use unix as imp; - } else if #[cfg(target_os = "windows")] { + } + target_os = "windows" => { mod windows; use windows as imp; - } else if #[cfg(target_os = "uefi")] { + } + target_os = "uefi" => { mod uefi; use uefi as imp; - } else { + } + _ => { mod unsupported; use unsupported as imp; } diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs index 6219be60caf..ea45b08e90a 100644 --- a/library/std/src/sys/process/unix/common.rs +++ b/library/std/src/sys/process/unix/common.rs @@ -20,12 +20,14 @@ use crate::{fmt, io}; mod cstring_array; -cfg_if::cfg_if! { - if #[cfg(target_os = "fuchsia")] { +cfg_select! { + target_os = "fuchsia" => { // fuchsia doesn't have /dev/null - } else if #[cfg(target_os = "vxworks")] { + } + target_os = "vxworks" => { const DEV_NULL: &CStr = c"/null"; - } else { + } + _ => { const DEV_NULL: &CStr = c"/dev/null"; } } @@ -35,8 +37,8 @@ cfg_if::cfg_if! { // to support older Android version (independent of libc version). // The following implementations are based on // https://github.com/aosp-mirror/platform_bionic/blob/ad8dcd6023294b646e5a8288c0ed431b0845da49/libc/include/android/legacy_signal_inlines.h -cfg_if::cfg_if! { - if #[cfg(target_os = "android")] { +cfg_select! { + target_os = "android" => { #[allow(dead_code)] pub unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int { set.write_bytes(0u8, 1); @@ -69,7 +71,8 @@ cfg_if::cfg_if! { raw[bit / LONG_BIT] |= 1 << (bit % LONG_BIT); return 0; } - } else { + } + _ => { #[allow(unused_imports)] pub use libc::{sigemptyset, sigaddset}; } diff --git a/library/std/src/sys/process/unix/mod.rs b/library/std/src/sys/process/unix/mod.rs index ee8fd8b2ca3..b4cf060fba9 100644 --- a/library/std/src/sys/process/unix/mod.rs +++ b/library/std/src/sys/process/unix/mod.rs @@ -1,18 +1,21 @@ #[cfg_attr(any(target_os = "espidf", target_os = "horizon", target_os = "nuttx"), allow(unused))] mod common; -cfg_if::cfg_if! { - if #[cfg(target_os = "fuchsia")] { +cfg_select! { + target_os = "fuchsia" => { mod fuchsia; use fuchsia as imp; - } else if #[cfg(target_os = "vxworks")] { + } + target_os = "vxworks" => { mod vxworks; use vxworks as imp; - } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] { + } + any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx") => { mod unsupported; use unsupported as imp; pub use unsupported::output; - } else { + } + _ => { mod unix; use unix as imp; } diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 5d13d6da185..11d48878727 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -18,8 +18,8 @@ use crate::sys::cvt; use crate::sys::pal::linux::pidfd::PidFd; use crate::{fmt, mem, sys}; -cfg_if::cfg_if! { - if #[cfg(target_os = "nto")] { +cfg_select! { + target_os = "nto" => { use crate::thread; use libc::{c_char, posix_spawn_file_actions_t, posix_spawnattr_t}; use crate::time::Duration; @@ -43,6 +43,7 @@ cfg_if::cfg_if! { // Maximum duration of sleeping before giving up and returning an error const MAX_FORKSPAWN_SLEEP: Duration = Duration::from_millis(1000); } + _ => {} } //////////////////////////////////////////////////////////////////////////////// @@ -465,8 +466,8 @@ impl Command { return Ok(None); } - cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + cfg_select! { + target_os = "linux" => { use crate::sys::weak::weak; weak!( @@ -526,7 +527,8 @@ impl Command { } core::assert_matches::debug_assert_matches!(support, SPAWN | NO); } - } else { + } + _ => { if self.get_create_pidfd() { unreachable!("only implemented on linux") } @@ -746,10 +748,11 @@ impl Command { } if self.get_setsid() { - cfg_if::cfg_if! { - if #[cfg(all(target_os = "linux", target_env = "gnu"))] { + cfg_select! { + all(target_os = "linux", target_env = "gnu") => { flags |= libc::POSIX_SPAWN_SETSID; - } else { + } + _ => { return Ok(None); } } diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index fc85797dcc2..a7fbae86099 100644 --- a/library/std/src/sys/random/mod.rs +++ b/library/std/src/sys/random/mod.rs @@ -1,16 +1,19 @@ -cfg_if::cfg_if! { +cfg_select! { // Tier 1 - if #[cfg(any(target_os = "linux", target_os = "android"))] { + any(target_os = "linux", target_os = "android") => { mod linux; pub use linux::{fill_bytes, hashmap_random_keys}; - } else if #[cfg(target_os = "windows")] { + } + target_os = "windows" => { mod windows; pub use windows::fill_bytes; - } else if #[cfg(target_vendor = "apple")] { + } + target_vendor = "apple" => { mod apple; pub use apple::fill_bytes; // Others, in alphabetical ordering. - } else if #[cfg(any( + } + any( target_os = "dragonfly", target_os = "freebsd", target_os = "haiku", @@ -21,69 +24,86 @@ cfg_if::cfg_if! { target_os = "solaris", target_os = "vita", target_os = "nuttx", - ))] { + ) => { mod arc4random; pub use arc4random::fill_bytes; - } else if #[cfg(target_os = "emscripten")] { + } + target_os = "emscripten" => { mod getentropy; pub use getentropy::fill_bytes; - } else if #[cfg(target_os = "espidf")] { + } + target_os = "espidf" => { mod espidf; pub use espidf::fill_bytes; - } else if #[cfg(target_os = "fuchsia")] { + } + target_os = "fuchsia" => { mod fuchsia; pub use fuchsia::fill_bytes; - } else if #[cfg(target_os = "hermit")] { + } + target_os = "hermit" => { mod hermit; pub use hermit::fill_bytes; - } else if #[cfg(any(target_os = "horizon", target_os = "cygwin"))] { + } + any(target_os = "horizon", target_os = "cygwin") => { // FIXME(horizon): add arc4random_buf to shim-3ds mod getrandom; pub use getrandom::fill_bytes; - } else if #[cfg(any( + } + any( target_os = "aix", target_os = "hurd", target_os = "l4re", target_os = "nto", - ))] { + ) => { mod unix_legacy; pub use unix_legacy::fill_bytes; - } else if #[cfg(target_os = "redox")] { + } + target_os = "redox" => { mod redox; pub use redox::fill_bytes; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod sgx; pub use sgx::fill_bytes; - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod solid; pub use solid::fill_bytes; - } else if #[cfg(target_os = "teeos")] { + } + target_os = "teeos" => { mod teeos; pub use teeos::fill_bytes; - } else if #[cfg(target_os = "trusty")] { + } + target_os = "trusty" => { mod trusty; pub use trusty::fill_bytes; - } else if #[cfg(target_os = "uefi")] { + } + target_os = "uefi" => { mod uefi; pub use uefi::fill_bytes; - } else if #[cfg(target_os = "vxworks")] { + } + target_os = "vxworks" => { mod vxworks; pub use vxworks::fill_bytes; - } else if #[cfg(target_os = "wasi")] { + } + target_os = "wasi" => { mod wasi; pub use wasi::fill_bytes; - } else if #[cfg(target_os = "zkvm")] { + } + target_os = "zkvm" => { mod zkvm; pub use zkvm::fill_bytes; - } else if #[cfg(any( + } + any( all(target_family = "wasm", target_os = "unknown"), target_os = "xous", - ))] { + ) => { // FIXME: finally remove std support for wasm32-unknown-unknown // FIXME: add random data generation to xous mod unsupported; pub use unsupported::{fill_bytes, hashmap_random_keys}; } + _ => {} } #[cfg(not(any( diff --git a/library/std/src/sys/random/uefi.rs b/library/std/src/sys/random/uefi.rs index 4a71d32fffe..697933f197b 100644 --- a/library/std/src/sys/random/uefi.rs +++ b/library/std/src/sys/random/uefi.rs @@ -55,12 +55,13 @@ mod rng_protocol { /// Port from [getrandom](https://github.com/rust-random/getrandom/blob/master/src/backends/rdrand.rs) #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] mod rdrand { - cfg_if::cfg_if! { - if #[cfg(target_arch = "x86_64")] { + cfg_select! { + target_arch = "x86_64" => { use crate::arch::x86_64 as arch; use arch::_rdrand64_step as rdrand_step; type Word = u64; - } else if #[cfg(target_arch = "x86")] { + } + target_arch = "x86" => { use crate::arch::x86 as arch; use arch::_rdrand32_step as rdrand_step; type Word = u32; diff --git a/library/std/src/sys/stdio/mod.rs b/library/std/src/sys/stdio/mod.rs index 336d4c8527d..314f226f07b 100644 --- a/library/std/src/sys/stdio/mod.rs +++ b/library/std/src/sys/stdio/mod.rs @@ -1,40 +1,47 @@ #![forbid(unsafe_op_in_unsafe_fn)] -cfg_if::cfg_if! { - if #[cfg(any( - target_family = "unix", - target_os = "hermit" - ))] { +cfg_select! { + any(target_family = "unix", target_os = "hermit") => { mod unix; pub use unix::*; - } else if #[cfg(target_os = "windows")] { + } + target_os = "windows" => { mod windows; pub use windows::*; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod sgx; pub use sgx::*; - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod solid; pub use solid::*; - } else if #[cfg(target_os = "teeos")] { + } + target_os = "teeos" => { mod teeos; pub use teeos::*; - } else if #[cfg(target_os = "trusty")] { + } + target_os = "trusty" => { mod trusty; pub use trusty::*; - } else if #[cfg(target_os = "uefi")] { + } + target_os = "uefi" => { mod uefi; pub use uefi::*; - } else if #[cfg(target_os = "wasi")] { + } + target_os = "wasi" => { mod wasi; pub use wasi::*; - } else if #[cfg(target_os = "xous")] { + } + target_os = "xous" => { mod xous; pub use xous::*; - } else if #[cfg(target_os = "zkvm")] { + } + target_os = "zkvm" => { mod zkvm; pub use zkvm::*; - } else { + } + _ => { mod unsupported; pub use unsupported::*; } diff --git a/library/std/src/sys/sync/condvar/mod.rs b/library/std/src/sys/sync/condvar/mod.rs index d0c998a5597..cb67d273759 100644 --- a/library/std/src/sys/sync/condvar/mod.rs +++ b/library/std/src/sys/sync/condvar/mod.rs @@ -1,5 +1,5 @@ -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( all(target_os = "windows", not(target_vendor="win7")), target_os = "linux", target_os = "android", @@ -9,28 +9,34 @@ cfg_if::cfg_if! { target_os = "fuchsia", all(target_family = "wasm", target_feature = "atomics"), target_os = "hermit", - ))] { + ) => { mod futex; pub use futex::Condvar; - } else if #[cfg(any( + } + any( target_family = "unix", target_os = "teeos", - ))] { + ) => { mod pthread; pub use pthread::Condvar; - } else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] { + } + all(target_os = "windows", target_vendor = "win7") => { mod windows7; pub use windows7::Condvar; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod sgx; pub use sgx::Condvar; - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod itron; pub use itron::Condvar; - } else if #[cfg(target_os = "xous")] { + } + target_os = "xous" => { mod xous; pub use xous::Condvar; - } else { + } + _ => { mod no_threads; pub use no_threads::Condvar; } diff --git a/library/std/src/sys/sync/mutex/mod.rs b/library/std/src/sys/sync/mutex/mod.rs index 360df3fc4b5..c885b0eabae 100644 --- a/library/std/src/sys/sync/mutex/mod.rs +++ b/library/std/src/sys/sync/mutex/mod.rs @@ -1,5 +1,5 @@ -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( all(target_os = "windows", not(target_vendor = "win7")), target_os = "linux", target_os = "android", @@ -8,31 +8,38 @@ cfg_if::cfg_if! { target_os = "dragonfly", all(target_family = "wasm", target_feature = "atomics"), target_os = "hermit", - ))] { + ) => { mod futex; pub use futex::Mutex; - } else if #[cfg(target_os = "fuchsia")] { + } + target_os = "fuchsia" => { mod fuchsia; pub use fuchsia::Mutex; - } else if #[cfg(any( + } + any( target_family = "unix", target_os = "teeos", - ))] { + ) => { mod pthread; pub use pthread::Mutex; - } else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] { + } + all(target_os = "windows", target_vendor = "win7") => { mod windows7; pub use windows7::{Mutex, raw}; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod sgx; pub use sgx::Mutex; - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod itron; pub use itron::Mutex; - } else if #[cfg(target_os = "xous")] { + } + target_os = "xous" => { mod xous; pub use xous::Mutex; - } else { + } + _ => { mod no_threads; pub use no_threads::Mutex; } diff --git a/library/std/src/sys/sync/once/mod.rs b/library/std/src/sys/sync/once/mod.rs index 0e38937b121..8adeb1f259d 100644 --- a/library/std/src/sys/sync/once/mod.rs +++ b/library/std/src/sys/sync/once/mod.rs @@ -7,8 +7,8 @@ // This also gives us the opportunity to optimize the implementation a bit which // should help the fast path on call sites. -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( all(target_os = "windows", not(target_vendor="win7")), target_os = "linux", target_os = "android", @@ -18,19 +18,21 @@ cfg_if::cfg_if! { target_os = "dragonfly", target_os = "fuchsia", target_os = "hermit", - ))] { + ) => { mod futex; pub use futex::{Once, OnceState}; - } else if #[cfg(any( + } + any( windows, target_family = "unix", all(target_vendor = "fortanix", target_env = "sgx"), target_os = "solid_asp3", target_os = "xous", - ))] { + ) => { mod queue; pub use queue::{Once, OnceState}; - } else { + } + _ => { mod no_threads; pub use no_threads::{Once, OnceState}; } diff --git a/library/std/src/sys/sync/rwlock/mod.rs b/library/std/src/sys/sync/rwlock/mod.rs index 70ba6bf38ef..82f1dd18dee 100644 --- a/library/std/src/sys/sync/rwlock/mod.rs +++ b/library/std/src/sys/sync/rwlock/mod.rs @@ -1,5 +1,5 @@ -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( all(target_os = "windows", not(target_vendor = "win7")), target_os = "linux", target_os = "android", @@ -9,24 +9,28 @@ cfg_if::cfg_if! { target_os = "fuchsia", all(target_family = "wasm", target_feature = "atomics"), target_os = "hermit", - ))] { + ) => { mod futex; pub use futex::RwLock; - } else if #[cfg(any( + } + any( target_family = "unix", all(target_os = "windows", target_vendor = "win7"), all(target_vendor = "fortanix", target_env = "sgx"), target_os = "xous", - ))] { + ) => { mod queue; pub use queue::RwLock; - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod solid; pub use solid::RwLock; - } else if #[cfg(target_os = "teeos")] { + } + target_os = "teeos" => { mod teeos; pub use teeos::RwLock; - } else { + } + _ => { mod no_threads; pub use no_threads::RwLock; } diff --git a/library/std/src/sys/sync/thread_parking/mod.rs b/library/std/src/sys/sync/thread_parking/mod.rs index f4d8fa0a58c..b9fb27b4eef 100644 --- a/library/std/src/sys/sync/thread_parking/mod.rs +++ b/library/std/src/sys/sync/thread_parking/mod.rs @@ -1,5 +1,5 @@ -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( all(target_os = "windows", not(target_vendor = "win7")), target_os = "linux", target_os = "android", @@ -9,30 +9,36 @@ cfg_if::cfg_if! { target_os = "dragonfly", target_os = "fuchsia", target_os = "hermit", - ))] { + ) => { mod futex; pub use futex::Parker; - } else if #[cfg(any( + } + any( target_os = "netbsd", all(target_vendor = "fortanix", target_env = "sgx"), target_os = "solid_asp3", - ))] { + ) => { mod id; pub use id::Parker; - } else if #[cfg(target_vendor = "win7")] { + } + target_vendor = "win7" => { mod windows7; pub use windows7::Parker; - } else if #[cfg(all(target_vendor = "apple", not(miri)))] { + } + all(target_vendor = "apple", not(miri)) => { // Doesn't work in Miri, see <https://github.com/rust-lang/miri/issues/2589>. mod darwin; pub use darwin::Parker; - } else if #[cfg(target_os = "xous")] { + } + target_os = "xous" => { mod xous; pub use xous::Parker; - } else if #[cfg(target_family = "unix")] { + } + target_family = "unix" => { mod pthread; pub use pthread::Parker; - } else { + } + _ => { mod unsupported; pub use unsupported::Parker; } diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 9fafac3aa5b..cff74857c47 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -23,21 +23,23 @@ issue = "none" )] -cfg_if::cfg_if! { - if #[cfg(any( +cfg_select! { + any( all(target_family = "wasm", not(target_feature = "atomics")), target_os = "uefi", target_os = "zkvm", target_os = "trusty", - ))] { + ) => { mod no_threads; pub use no_threads::{EagerStorage, LazyStorage, thread_local_inner}; pub(crate) use no_threads::{LocalPointer, local_pointer}; - } else if #[cfg(target_thread_local)] { + } + target_thread_local => { mod native; pub use native::{EagerStorage, LazyStorage, thread_local_inner}; pub(crate) use native::{LocalPointer, local_pointer}; - } else { + } + _ => { mod os; pub use os::{Storage, thread_local_inner}; pub(crate) use os::{LocalPointer, local_pointer}; @@ -53,8 +55,8 @@ cfg_if::cfg_if! { /// single callback that runs all of the destructors in the list. #[cfg(all(target_thread_local, not(all(target_family = "wasm", not(target_feature = "atomics")))))] pub(crate) mod destructors { - cfg_if::cfg_if! { - if #[cfg(any( + cfg_select! { + any( target_os = "linux", target_os = "android", target_os = "fuchsia", @@ -62,12 +64,13 @@ pub(crate) mod destructors { target_os = "hurd", target_os = "netbsd", target_os = "dragonfly" - ))] { + ) => { mod linux_like; mod list; pub(super) use linux_like::register; pub(super) use list::run; - } else { + } + _ => { mod list; pub(super) use list::register; pub(crate) use list::run; @@ -79,21 +82,23 @@ pub(crate) mod destructors { /// and the [runtime cleanup](crate::rt::thread_cleanup) function. Calling `enable` /// should ensure that these functions are called at the right times. pub(crate) mod guard { - cfg_if::cfg_if! { - if #[cfg(all(target_thread_local, target_vendor = "apple"))] { + cfg_select! { + all(target_thread_local, target_vendor = "apple") => { mod apple; pub(crate) use apple::enable; - } else if #[cfg(target_os = "windows")] { + } + target_os = "windows" => { mod windows; pub(crate) use windows::enable; - } else if #[cfg(any( + } + any( all(target_family = "wasm", not( all(target_os = "wasi", target_env = "p1", target_feature = "atomics") )), target_os = "uefi", target_os = "zkvm", target_os = "trusty", - ))] { + ) => { pub(crate) fn enable() { // FIXME: Right now there is no concept of "thread exit" on // wasm, but this is likely going to show up at some point in @@ -107,17 +112,20 @@ pub(crate) mod guard { #[allow(unused)] use crate::rt::thread_cleanup; } - } else if #[cfg(any( + } + any( target_os = "hermit", target_os = "xous", - ))] { + ) => { // `std` is the only runtime, so it just calls the destructor functions // itself when the time comes. pub(crate) fn enable() {} - } else if #[cfg(target_os = "solid_asp3")] { + } + target_os = "solid_asp3" => { mod solid; pub(crate) use solid::enable; - } else { + } + _ => { mod key; pub(crate) use key::enable; } @@ -131,8 +139,8 @@ pub(crate) mod guard { /// reference an entry in a thread-local table. This then associates each key /// with a pointer which we can get and set to store our data. pub(crate) mod key { - cfg_if::cfg_if! { - if #[cfg(any( + cfg_select! { + any( all( not(target_vendor = "apple"), not(target_family = "wasm"), @@ -141,7 +149,7 @@ pub(crate) mod key { all(not(target_thread_local), target_vendor = "apple"), target_os = "teeos", all(target_os = "wasi", target_env = "p1", target_feature = "atomics"), - ))] { + ) => { mod racy; mod unix; #[cfg(test)] @@ -151,12 +159,14 @@ pub(crate) mod key { #[cfg(any(not(target_thread_local), test))] pub(super) use unix::get; use unix::{create, destroy}; - } else if #[cfg(all(not(target_thread_local), target_os = "windows"))] { + } + all(not(target_thread_local), target_os = "windows") => { #[cfg(test)] mod tests; mod windows; pub(super) use windows::{Key, LazyKey, get, run_dtors, set}; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + } + all(target_vendor = "fortanix", target_env = "sgx") => { mod racy; mod sgx; #[cfg(test)] @@ -164,7 +174,8 @@ pub(crate) mod key { pub(super) use racy::LazyKey; pub(super) use sgx::{Key, get, set}; use sgx::{create, destroy}; - } else if #[cfg(target_os = "xous")] { + } + target_os = "xous" => { mod racy; #[cfg(test)] mod tests; @@ -174,6 +185,7 @@ pub(crate) mod key { pub(super) use xous::{Key, get, set}; use xous::{create, destroy}; } + _ => {} } } diff --git a/library/std/src/thread/current.rs b/library/std/src/thread/current.rs index 5c879903526..7da1621da45 100644 --- a/library/std/src/thread/current.rs +++ b/library/std/src/thread/current.rs @@ -18,8 +18,8 @@ local_pointer! { pub(super) mod id { use super::*; - cfg_if::cfg_if! { - if #[cfg(target_thread_local)] { + cfg_select! { + target_thread_local => { use crate::cell::Cell; #[thread_local] @@ -34,7 +34,8 @@ pub(super) mod id { pub(super) fn set(id: ThreadId) { ID.set(Some(id)) } - } else if #[cfg(target_pointer_width = "16")] { + } + target_pointer_width = "16" => { local_pointer! { static ID0; static ID16; @@ -59,7 +60,8 @@ pub(super) mod id { ID32.set(ptr::without_provenance_mut((val >> 32) as usize)); ID48.set(ptr::without_provenance_mut((val >> 48) as usize)); } - } else if #[cfg(target_pointer_width = "32")] { + } + target_pointer_width = "32" => { local_pointer! { static ID0; static ID32; @@ -78,7 +80,8 @@ pub(super) mod id { ID0.set(ptr::without_provenance_mut(val as usize)); ID32.set(ptr::without_provenance_mut((val >> 32) as usize)); } - } else { + } + _ => { local_pointer! { static ID; } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 292323d0118..b6059c28cec 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1212,8 +1212,8 @@ impl ThreadId { panic!("failed to generate unique thread ID: bitspace exhausted") } - cfg_if::cfg_if! { - if #[cfg(target_has_atomic = "64")] { + cfg_select! { + target_has_atomic = "64" => { use crate::sync::atomic::{Atomic, AtomicU64}; static COUNTER: Atomic<u64> = AtomicU64::new(0); @@ -1229,7 +1229,8 @@ impl ThreadId { Err(id) => last = id, } } - } else { + } + _ => { use crate::sync::{Mutex, PoisonError}; static COUNTER: Mutex<u64> = Mutex::new(0); @@ -1318,8 +1319,8 @@ use thread_name_string::ThreadNameString; /// Note however that this also means that the name reported in pre-main functions /// will be incorrect, but that's just something we have to live with. pub(crate) mod main_thread { - cfg_if::cfg_if! { - if #[cfg(target_has_atomic = "64")] { + cfg_select! { + target_has_atomic = "64" => { use super::ThreadId; use crate::sync::atomic::{Atomic, AtomicU64}; use crate::sync::atomic::Ordering::Relaxed; @@ -1335,7 +1336,8 @@ pub(crate) mod main_thread { pub(crate) unsafe fn set(id: ThreadId) { MAIN.store(id.as_u64().get(), Relaxed) } - } else { + } + _ => { use super::ThreadId; use crate::mem::MaybeUninit; use crate::sync::atomic::{Atomic, AtomicBool}; diff --git a/library/std/tests/env_modify.rs b/library/std/tests/env_modify.rs index ba84978b35f..fe0ae68806e 100644 --- a/library/std/tests/env_modify.rs +++ b/library/std/tests/env_modify.rs @@ -1,5 +1,6 @@ // These tests are in a separate integration test as they modify the environment, // and would otherwise cause some other tests to fail. +#![feature(cfg_select)] use std::env::*; use std::ffi::{OsStr, OsString}; @@ -110,8 +111,8 @@ fn env_home_dir() { } } - cfg_if::cfg_if! { - if #[cfg(unix)] { + cfg_select! { + unix => { let oldhome = var_to_os_string(var("HOME")); unsafe { @@ -130,7 +131,8 @@ fn env_home_dir() { } if let Some(oldhome) = oldhome { unsafe { set_var("HOME", oldhome); } } - } else if #[cfg(windows)] { + } + windows => { let oldhome = var_to_os_string(var("HOME")); let olduserprofile = var_to_os_string(var("USERPROFILE")); @@ -159,6 +161,7 @@ fn env_home_dir() { if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); } } } + _ => {} } } diff --git a/library/std_detect/Cargo.toml b/library/std_detect/Cargo.toml index 8d91454726b..33e6617c381 100644 --- a/library/std_detect/Cargo.toml +++ b/library/std_detect/Cargo.toml @@ -21,7 +21,6 @@ is-it-maintained-open-issues = { repository = "rust-lang/stdarch" } maintenance = { status = "experimental" } [dependencies] -cfg-if = "1.0.0" core = { path = "../core" } alloc = { path = "../alloc" } diff --git a/library/std_detect/src/detect/arch/loongarch.rs b/library/std_detect/src/detect/arch/loongarch.rs index 68fc600fa8e..d5a442fbbb8 100644 --- a/library/std_detect/src/detect/arch/loongarch.rs +++ b/library/std_detect/src/detect/arch/loongarch.rs @@ -8,6 +8,7 @@ features! { /// Checks if `loongarch` feature is enabled. /// Supported arguments are: /// + /// * `"32s"` /// * `"f"` /// * `"d"` /// * `"frecipe"` @@ -22,6 +23,8 @@ features! { /// * `"lvz"` /// * `"ual"` #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] + @FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] _32s: "32s"; + /// 32S @FEATURE: #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] f: "f"; /// F @FEATURE: #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] d: "d"; diff --git a/library/std_detect/src/detect/arch/mod.rs b/library/std_detect/src/detect/arch/mod.rs index b0be554ed89..c066b9cc681 100644 --- a/library/std_detect/src/detect/arch/mod.rs +++ b/library/std_detect/src/detect/arch/mod.rs @@ -1,7 +1,5 @@ #![allow(dead_code)] -use cfg_if::cfg_if; - // Export the macros for all supported architectures. #[macro_use] mod x86; @@ -24,38 +22,48 @@ mod loongarch; #[macro_use] mod s390x; -cfg_if! { - if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { +cfg_select! { + any(target_arch = "x86", target_arch = "x86_64") => { #[stable(feature = "simd_x86", since = "1.27.0")] pub use x86::*; - } else if #[cfg(target_arch = "arm")] { + } + target_arch = "arm" => { #[unstable(feature = "stdarch_arm_feature_detection", issue = "111190")] pub use arm::*; - } else if #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] { + } + any(target_arch = "aarch64", target_arch = "arm64ec") => { #[stable(feature = "simd_aarch64", since = "1.60.0")] pub use aarch64::*; - } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { + } + any(target_arch = "riscv32", target_arch = "riscv64") => { #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] pub use riscv::*; - } else if #[cfg(target_arch = "powerpc")] { + } + target_arch = "powerpc" => { #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] pub use powerpc::*; - } else if #[cfg(target_arch = "powerpc64")] { + } + target_arch = "powerpc64" => { #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] pub use powerpc64::*; - } else if #[cfg(target_arch = "mips")] { + } + target_arch = "mips" => { #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] pub use mips::*; - } else if #[cfg(target_arch = "mips64")] { + } + target_arch = "mips64" => { #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] pub use mips64::*; - } else if #[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] { + } + any(target_arch = "loongarch32", target_arch = "loongarch64") => { #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] pub use loongarch::*; - } else if #[cfg(target_arch = "s390x")] { + } + target_arch = "s390x" => { #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] pub use s390x::*; - } else { + } + _ => { // Unimplemented architecture: #[doc(hidden)] pub(crate) enum Feature { diff --git a/library/std_detect/src/detect/cache.rs b/library/std_detect/src/detect/cache.rs index 1a42e091463..c0c0b7b7f86 100644 --- a/library/std_detect/src/detect/cache.rs +++ b/library/std_detect/src/detect/cache.rs @@ -101,8 +101,8 @@ impl Cache { } } -cfg_if::cfg_if! { - if #[cfg(feature = "std_detect_env_override")] { +cfg_select! { + feature = "std_detect_env_override" => { #[inline] fn disable_features(disable: &[u8], value: &mut Initializer) { if let Ok(disable) = core::str::from_utf8(disable) { @@ -116,8 +116,8 @@ cfg_if::cfg_if! { fn initialize(mut value: Initializer) -> Initializer { use core::ffi::CStr; const RUST_STD_DETECT_UNSTABLE: &CStr = c"RUST_STD_DETECT_UNSTABLE"; - cfg_if::cfg_if! { - if #[cfg(windows)] { + cfg_select! { + windows => { use alloc::vec; #[link(name = "kernel32")] unsafe extern "system" { @@ -132,7 +132,8 @@ cfg_if::cfg_if! { disable_features(&env[..len as usize], &mut value); } } - } else { + } + _ => { let env = unsafe { libc::getenv(RUST_STD_DETECT_UNSTABLE.as_ptr()) }; @@ -146,7 +147,8 @@ cfg_if::cfg_if! { do_initialize(value); value } - } else { + } + _ => { #[inline] fn initialize(value: Initializer) -> Initializer { do_initialize(value); diff --git a/library/std_detect/src/detect/mod.rs b/library/std_detect/src/detect/mod.rs index f936a5a1345..2bc6e9a24db 100644 --- a/library/std_detect/src/detect/mod.rs +++ b/library/std_detect/src/detect/mod.rs @@ -17,8 +17,6 @@ //! due to security concerns (x86 is the big exception). These functions are //! implemented in the `os/{target_os}.rs` modules. -use cfg_if::cfg_if; - #[macro_use] mod macros; @@ -34,8 +32,8 @@ pub(crate) use self::arch::Feature; mod bit; mod cache; -cfg_if! { - if #[cfg(miri)] { +cfg_select! { + miri => { // When running under miri all target-features that are not enabled at // compile-time are reported as disabled at run-time. // @@ -43,35 +41,42 @@ cfg_if! { // this run-time detection logic is never called. #[path = "os/other.rs"] mod os; - } else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + } + any(target_arch = "x86", target_arch = "x86_64") => { // On x86/x86_64 no OS specific functionality is required. #[path = "os/x86.rs"] mod os; - } else if #[cfg(all(any(target_os = "linux", target_os = "android"), feature = "libc"))] { + } + all(any(target_os = "linux", target_os = "android"), feature = "libc") => { #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] #[path = "os/riscv.rs"] mod riscv; #[path = "os/linux/mod.rs"] mod os; - } else if #[cfg(all(target_os = "freebsd", feature = "libc"))] { + } + all(target_os = "freebsd", feature = "libc") => { #[cfg(target_arch = "aarch64")] #[path = "os/aarch64.rs"] mod aarch64; #[path = "os/freebsd/mod.rs"] mod os; - } else if #[cfg(all(target_os = "openbsd", target_arch = "aarch64", feature = "libc"))] { + } + all(target_os = "openbsd", target_arch = "aarch64", feature = "libc") => { #[allow(dead_code)] // we don't use code that calls the mrs instruction. #[path = "os/aarch64.rs"] mod aarch64; #[path = "os/openbsd/aarch64.rs"] mod os; - } else if #[cfg(all(target_os = "windows", any(target_arch = "aarch64", target_arch = "arm64ec")))] { + } + all(target_os = "windows", any(target_arch = "aarch64", target_arch = "arm64ec")) => { #[path = "os/windows/aarch64.rs"] mod os; - } else if #[cfg(all(target_vendor = "apple", target_arch = "aarch64", feature = "libc"))] { + } + all(target_vendor = "apple", target_arch = "aarch64", feature = "libc") => { #[path = "os/darwin/aarch64.rs"] mod os; - } else { + } + _ => { #[path = "os/other.rs"] mod os; } @@ -89,8 +94,8 @@ fn check_for(x: Feature) -> bool { /// is `true` if the feature is supported by the host and `false` otherwise. #[unstable(feature = "stdarch_internal", issue = "none")] pub fn features() -> impl Iterator<Item = (&'static str, bool)> { - cfg_if! { - if #[cfg(any( + cfg_select! { + any( target_arch = "x86", target_arch = "x86_64", target_arch = "arm", @@ -105,7 +110,7 @@ pub fn features() -> impl Iterator<Item = (&'static str, bool)> { target_arch = "loongarch32", target_arch = "loongarch64", target_arch = "s390x", - ))] { + ) => { (0_u8..Feature::_last as u8).map(|discriminant: u8| { #[allow(bindings_with_variant_name)] // RISC-V has Feature::f let f: Feature = unsafe { core::mem::transmute(discriminant) }; @@ -113,8 +118,7 @@ pub fn features() -> impl Iterator<Item = (&'static str, bool)> { let enabled: bool = check_for(f); (name, enabled) }) - } else { - None.into_iter() } + _ => None.into_iter(), } } diff --git a/library/std_detect/src/detect/os/freebsd/mod.rs b/library/std_detect/src/detect/os/freebsd/mod.rs index ade7fb6269d..7de9250e835 100644 --- a/library/std_detect/src/detect/os/freebsd/mod.rs +++ b/library/std_detect/src/detect/os/freebsd/mod.rs @@ -2,17 +2,20 @@ mod auxvec; -cfg_if::cfg_if! { - if #[cfg(target_arch = "aarch64")] { +cfg_select! { + target_arch = "aarch64" => { mod aarch64; pub(crate) use self::aarch64::detect_features; - } else if #[cfg(target_arch = "arm")] { + } + target_arch = "arm" => { mod arm; pub(crate) use self::arm::detect_features; - } else if #[cfg(target_arch = "powerpc64")] { + } + target_arch = "powerpc64" => { mod powerpc; pub(crate) use self::powerpc::detect_features; - } else { + } + _ => { use crate::detect::cache; /// Performs run-time feature detection. pub(crate) fn detect_features() -> cache::Initializer { diff --git a/library/std_detect/src/detect/os/linux/auxvec.rs b/library/std_detect/src/detect/os/linux/auxvec.rs index 443caaaa186..75e01bdc449 100644 --- a/library/std_detect/src/detect/os/linux/auxvec.rs +++ b/library/std_detect/src/detect/os/linux/auxvec.rs @@ -131,15 +131,15 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> { /// `getauxval` function. If the function is not linked, this function return `Err`. fn getauxval(key: usize) -> Result<usize, ()> { type F = unsafe extern "C" fn(libc::c_ulong) -> libc::c_ulong; - cfg_if::cfg_if! { - if #[cfg(all( + cfg_select! { + all( feature = "std_detect_dlsym_getauxval", not(all( target_os = "linux", any(target_env = "gnu", target_env = "musl", target_env = "ohos"), )), not(target_os = "android"), - ))] { + ) => { let ffi_getauxval: F = unsafe { let ptr = libc::dlsym(libc::RTLD_DEFAULT, c"getauxval".as_ptr()); if ptr.is_null() { @@ -147,7 +147,8 @@ fn getauxval(key: usize) -> Result<usize, ()> { } core::mem::transmute(ptr) }; - } else { + } + _ => { let ffi_getauxval: F = libc::getauxval; } } diff --git a/library/std_detect/src/detect/os/linux/auxvec/tests.rs b/library/std_detect/src/detect/os/linux/auxvec/tests.rs index 536615fa272..631a3e5e9ef 100644 --- a/library/std_detect/src/detect/os/linux/auxvec/tests.rs +++ b/library/std_detect/src/detect/os/linux/auxvec/tests.rs @@ -42,8 +42,8 @@ fn auxv_dump() { } #[cfg(feature = "std_detect_file_io")] -cfg_if::cfg_if! { - if #[cfg(target_arch = "arm")] { +cfg_select! { + target_arch = "arm" => { // The tests below can be executed under qemu, where we do not have access to the test // files on disk, so we need to embed them with `include_bytes!`. #[test] @@ -62,7 +62,8 @@ cfg_if::cfg_if! { assert_eq!(v.hwcap, 126614527); assert_eq!(v.hwcap2, 0); } - } else if #[cfg(target_arch = "aarch64")] { + } + target_arch = "aarch64" => { #[cfg(target_endian = "little")] #[test] fn linux_artificial_aarch64() { @@ -81,6 +82,7 @@ cfg_if::cfg_if! { assert_eq!(v.hwcap2, 0); } } + _ => {} } #[test] diff --git a/library/std_detect/src/detect/os/linux/loongarch.rs b/library/std_detect/src/detect/os/linux/loongarch.rs index e97fda11d08..74415266f8b 100644 --- a/library/std_detect/src/detect/os/linux/loongarch.rs +++ b/library/std_detect/src/detect/os/linux/loongarch.rs @@ -17,22 +17,21 @@ pub(crate) fn detect_features() -> cache::Initializer { // The values are part of the platform-specific [cpucfg] // // [cpucfg]: LoongArch Reference Manual Volume 1: Basic Architecture v1.1 + let cpucfg1: usize; let cpucfg2: usize; - unsafe { - asm!( - "cpucfg {}, {}", - out(reg) cpucfg2, in(reg) 2, - options(pure, nomem, preserves_flags, nostack) - ); - } let cpucfg3: usize; unsafe { asm!( "cpucfg {}, {}", + "cpucfg {}, {}", + "cpucfg {}, {}", + out(reg) cpucfg1, in(reg) 1, + out(reg) cpucfg2, in(reg) 2, out(reg) cpucfg3, in(reg) 3, options(pure, nomem, preserves_flags, nostack) ); } + enable_feature(&mut value, Feature::_32s, bit::test(cpucfg1, 0) || bit::test(cpucfg1, 1)); enable_feature(&mut value, Feature::frecipe, bit::test(cpucfg2, 25)); enable_feature(&mut value, Feature::div32, bit::test(cpucfg2, 26)); enable_feature(&mut value, Feature::lam_bh, bit::test(cpucfg2, 27)); diff --git a/library/std_detect/src/detect/os/linux/mod.rs b/library/std_detect/src/detect/os/linux/mod.rs index 5ae2aaeab5b..5273c16c089 100644 --- a/library/std_detect/src/detect/os/linux/mod.rs +++ b/library/std_detect/src/detect/os/linux/mod.rs @@ -37,29 +37,36 @@ fn read_file(orig_path: &str) -> Result<Vec<u8>, alloc::string::String> { } } -cfg_if::cfg_if! { - if #[cfg(target_arch = "aarch64")] { +cfg_select! { + target_arch = "aarch64" => { mod aarch64; pub(crate) use self::aarch64::detect_features; - } else if #[cfg(target_arch = "arm")] { + } + target_arch = "arm" => { mod arm; pub(crate) use self::arm::detect_features; - } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { + } + any(target_arch = "riscv32", target_arch = "riscv64") => { mod riscv; pub(crate) use self::riscv::detect_features; - } else if #[cfg(any(target_arch = "mips", target_arch = "mips64"))] { + } + any(target_arch = "mips", target_arch = "mips64") => { mod mips; pub(crate) use self::mips::detect_features; - } else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] { + } + any(target_arch = "powerpc", target_arch = "powerpc64") => { mod powerpc; pub(crate) use self::powerpc::detect_features; - } else if #[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] { + } + any(target_arch = "loongarch32", target_arch = "loongarch64") => { mod loongarch; pub(crate) use self::loongarch::detect_features; - } else if #[cfg(target_arch = "s390x")] { + } + target_arch = "s390x" => { mod s390x; pub(crate) use self::s390x::detect_features; - } else { + } + _ => { use crate::detect::cache; /// Performs run-time feature detection. pub(crate) fn detect_features() -> cache::Initializer { diff --git a/library/std_detect/src/lib.rs b/library/std_detect/src/lib.rs index ab1b77bad5b..73e2f5dd964 100644 --- a/library/std_detect/src/lib.rs +++ b/library/std_detect/src/lib.rs @@ -15,7 +15,7 @@ //! * `s390x`: [`is_s390x_feature_detected`] #![unstable(feature = "stdarch_internal", issue = "none")] -#![feature(staged_api, doc_cfg, allow_internal_unstable)] +#![feature(staged_api, cfg_select, doc_cfg, allow_internal_unstable)] #![deny(rust_2018_idioms)] #![allow(clippy::shadow_reuse)] #![cfg_attr(test, allow(unused_imports))] diff --git a/library/std_detect/tests/macro_trailing_commas.rs b/library/std_detect/tests/macro_trailing_commas.rs index 2fee0abdd57..6072ddf5ac4 100644 --- a/library/std_detect/tests/macro_trailing_commas.rs +++ b/library/std_detect/tests/macro_trailing_commas.rs @@ -69,6 +69,8 @@ fn aarch64() { #[test] #[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] fn loongarch() { + let _ = is_loongarch_feature_detected!("32s"); + let _ = is_loongarch_feature_detected!("32s",); let _ = is_loongarch_feature_detected!("lsx"); let _ = is_loongarch_feature_detected!("lsx",); } diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index b9ce676eb3f..f02744a1070 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -14,7 +14,6 @@ bench = false doc = false [dependencies] -cfg-if = "1.0" core = { path = "../rustc-std-workspace-core", package = "rustc-std-workspace-core" } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index 5451a38a674..cd3a2f33ffa 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -1,6 +1,7 @@ #![no_std] #![unstable(feature = "panic_unwind", issue = "32837")] #![feature(cfg_emscripten_wasm_eh)] +#![feature(cfg_select)] #![feature(link_cfg)] #![feature(staged_api)] #![cfg_attr(not(target_env = "msvc"), feature(libc))] @@ -15,32 +16,37 @@ #[cfg(not(all(windows, target_env = "msvc")))] extern crate libc as _; -cfg_if::cfg_if! { - if #[cfg(target_env = "msvc")] { +cfg_select! { + target_env = "msvc" => { // Windows MSVC no extra unwinder support needed - } else if #[cfg(any( + } + any( target_os = "l4re", target_os = "none", target_os = "espidf", target_os = "nuttx", - ))] { + ) => { // These "unix" family members do not have unwinder. - } else if #[cfg(any( + } + any( unix, windows, target_os = "psp", target_os = "solid_asp3", all(target_vendor = "fortanix", target_env = "sgx"), - ))] { + ) => { mod libunwind; pub use libunwind::*; - } else if #[cfg(target_os = "xous")] { + } + target_os = "xous" => { mod unwinding; pub use unwinding::*; - } else if #[cfg(target_family = "wasm")] { + } + target_family = "wasm" => { mod wasm; pub use wasm::*; - } else { + } + _ => { // no unwinder on the system! // - os=none ("bare metal" targets) // - os=hermit @@ -52,17 +58,20 @@ cfg_if::cfg_if! { } #[cfg(target_env = "musl")] -cfg_if::cfg_if! { - if #[cfg(all(feature = "llvm-libunwind", feature = "system-llvm-libunwind"))] { +cfg_select! { + all(feature = "llvm-libunwind", feature = "system-llvm-libunwind") => { compile_error!("`llvm-libunwind` and `system-llvm-libunwind` cannot be enabled at the same time"); - } else if #[cfg(feature = "llvm-libunwind")] { + } + feature = "llvm-libunwind" => { #[link(name = "unwind", kind = "static", modifiers = "-bundle")] unsafe extern "C" {} - } else if #[cfg(feature = "system-llvm-libunwind")] { + } + feature = "system-llvm-libunwind" => { #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] #[link(name = "unwind", cfg(not(target_feature = "crt-static")))] unsafe extern "C" {} - } else { + } + _ => { #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] unsafe extern "C" {} @@ -72,13 +81,15 @@ cfg_if::cfg_if! { // This is the same as musl except that we default to using the system libunwind // instead of libgcc. #[cfg(target_env = "ohos")] -cfg_if::cfg_if! { - if #[cfg(all(feature = "llvm-libunwind", feature = "system-llvm-libunwind"))] { +cfg_select! { + all(feature = "llvm-libunwind", feature = "system-llvm-libunwind") => { compile_error!("`llvm-libunwind` and `system-llvm-libunwind` cannot be enabled at the same time"); - } else if #[cfg(feature = "llvm-libunwind")] { + } + feature = "llvm-libunwind" => { #[link(name = "unwind", kind = "static", modifiers = "-bundle")] unsafe extern "C" {} - } else { + } + _ => { #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] #[link(name = "unwind", cfg(not(target_feature = "crt-static")))] unsafe extern "C" {} @@ -86,10 +97,11 @@ cfg_if::cfg_if! { } #[cfg(target_os = "android")] -cfg_if::cfg_if! { - if #[cfg(feature = "llvm-libunwind")] { +cfg_select! { + feature = "llvm-libunwind" => { compile_error!("`llvm-libunwind` is not supported for Android targets"); - } else { + } + _ => { #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] #[link(name = "unwind", cfg(not(target_feature = "crt-static")))] unsafe extern "C" {} @@ -166,11 +178,12 @@ unsafe extern "C" {} unsafe extern "C" {} #[cfg(target_os = "nto")] -cfg_if::cfg_if! { - if #[cfg(target_env = "nto70")] { +cfg_select! { + target_env = "nto70" => { #[link(name = "gcc")] unsafe extern "C" {} - } else { + } + _ => { #[link(name = "gcc_s")] unsafe extern "C" {} } diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index b350003cbb1..9ac9b54ed4a 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -122,198 +122,205 @@ unsafe extern "C" { pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr; } -cfg_if::cfg_if! { -if #[cfg(any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "arm")))] { - // Not ARM EHABI - // - // 32-bit ARM on iOS/tvOS/watchOS use either DWARF/Compact unwinding or - // "setjmp-longjmp" / SjLj unwinding. - pub type _Unwind_Action = c_int; - - pub const _UA_SEARCH_PHASE: c_int = 1; - pub const _UA_CLEANUP_PHASE: c_int = 2; - pub const _UA_HANDLER_FRAME: c_int = 4; - pub const _UA_FORCE_UNWIND: c_int = 8; - pub const _UA_END_OF_STACK: c_int = 16; - - #[cfg_attr( - all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")), - link(name = "unwind", kind = "static", modifiers = "-bundle") - )] - unsafe extern "C" { - pub fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word; - pub fn _Unwind_SetGR(ctx: *mut _Unwind_Context, reg_index: c_int, value: _Unwind_Word); - pub fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> _Unwind_Word; - pub fn _Unwind_SetIP(ctx: *mut _Unwind_Context, value: _Unwind_Word); - pub fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context, ip_before_insn: *mut c_int) - -> _Unwind_Word; - pub fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void; - } +cfg_select! { + any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "arm")) => { + // Not ARM EHABI + // + // 32-bit ARM on iOS/tvOS/watchOS use either DWARF/Compact unwinding or + // "setjmp-longjmp" / SjLj unwinding. + pub type _Unwind_Action = c_int; + + pub const _UA_SEARCH_PHASE: c_int = 1; + pub const _UA_CLEANUP_PHASE: c_int = 2; + pub const _UA_HANDLER_FRAME: c_int = 4; + pub const _UA_FORCE_UNWIND: c_int = 8; + pub const _UA_END_OF_STACK: c_int = 16; + + #[cfg_attr( + all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")), + link(name = "unwind", kind = "static", modifiers = "-bundle") + )] + unsafe extern "C" { + pub fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word; + pub fn _Unwind_SetGR(ctx: *mut _Unwind_Context, reg_index: c_int, value: _Unwind_Word); + pub fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> _Unwind_Word; + pub fn _Unwind_SetIP(ctx: *mut _Unwind_Context, value: _Unwind_Word); + pub fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context, ip_before_insn: *mut c_int) + -> _Unwind_Word; + pub fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void; + } -} else { - // ARM EHABI - #[repr(C)] - #[derive(Copy, Clone, PartialEq)] - pub enum _Unwind_State { - _US_VIRTUAL_UNWIND_FRAME = 0, - _US_UNWIND_FRAME_STARTING = 1, - _US_UNWIND_FRAME_RESUME = 2, - _US_ACTION_MASK = 3, - _US_FORCE_UNWIND = 8, - _US_END_OF_STACK = 16, } - pub use _Unwind_State::*; + _ => { + // ARM EHABI + #[repr(C)] + #[derive(Copy, Clone, PartialEq)] + pub enum _Unwind_State { + _US_VIRTUAL_UNWIND_FRAME = 0, + _US_UNWIND_FRAME_STARTING = 1, + _US_UNWIND_FRAME_RESUME = 2, + _US_ACTION_MASK = 3, + _US_FORCE_UNWIND = 8, + _US_END_OF_STACK = 16, + } + pub use _Unwind_State::*; - #[repr(C)] - enum _Unwind_VRS_Result { - _UVRSR_OK = 0, - _UVRSR_NOT_IMPLEMENTED = 1, - _UVRSR_FAILED = 2, - } - #[repr(C)] - enum _Unwind_VRS_RegClass { - _UVRSC_CORE = 0, - _UVRSC_VFP = 1, - _UVRSC_FPA = 2, - _UVRSC_WMMXD = 3, - _UVRSC_WMMXC = 4, - } - use _Unwind_VRS_RegClass::*; - #[repr(C)] - enum _Unwind_VRS_DataRepresentation { - _UVRSD_UINT32 = 0, - _UVRSD_VFPX = 1, - _UVRSD_FPAX = 2, - _UVRSD_UINT64 = 3, - _UVRSD_FLOAT = 4, - _UVRSD_DOUBLE = 5, - } - use _Unwind_VRS_DataRepresentation::*; - - pub const UNWIND_POINTER_REG: c_int = 12; - pub const UNWIND_SP_REG: c_int = 13; - pub const UNWIND_IP_REG: c_int = 15; - - #[cfg_attr( - all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")), - link(name = "unwind", kind = "static", modifiers = "-bundle") - )] - unsafe extern "C" { - fn _Unwind_VRS_Get(ctx: *mut _Unwind_Context, - regclass: _Unwind_VRS_RegClass, - regno: _Unwind_Word, - repr: _Unwind_VRS_DataRepresentation, - data: *mut c_void) - -> _Unwind_VRS_Result; - - fn _Unwind_VRS_Set(ctx: *mut _Unwind_Context, - regclass: _Unwind_VRS_RegClass, - regno: _Unwind_Word, - repr: _Unwind_VRS_DataRepresentation, - data: *mut c_void) - -> _Unwind_VRS_Result; - } + #[repr(C)] + enum _Unwind_VRS_Result { + _UVRSR_OK = 0, + _UVRSR_NOT_IMPLEMENTED = 1, + _UVRSR_FAILED = 2, + } + #[repr(C)] + enum _Unwind_VRS_RegClass { + _UVRSC_CORE = 0, + _UVRSC_VFP = 1, + _UVRSC_FPA = 2, + _UVRSC_WMMXD = 3, + _UVRSC_WMMXC = 4, + } + use _Unwind_VRS_RegClass::*; + #[repr(C)] + enum _Unwind_VRS_DataRepresentation { + _UVRSD_UINT32 = 0, + _UVRSD_VFPX = 1, + _UVRSD_FPAX = 2, + _UVRSD_UINT64 = 3, + _UVRSD_FLOAT = 4, + _UVRSD_DOUBLE = 5, + } + use _Unwind_VRS_DataRepresentation::*; + + pub const UNWIND_POINTER_REG: c_int = 12; + pub const UNWIND_SP_REG: c_int = 13; + pub const UNWIND_IP_REG: c_int = 15; + + #[cfg_attr( + all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")), + link(name = "unwind", kind = "static", modifiers = "-bundle") + )] + unsafe extern "C" { + fn _Unwind_VRS_Get(ctx: *mut _Unwind_Context, + regclass: _Unwind_VRS_RegClass, + regno: _Unwind_Word, + repr: _Unwind_VRS_DataRepresentation, + data: *mut c_void) + -> _Unwind_VRS_Result; + + fn _Unwind_VRS_Set(ctx: *mut _Unwind_Context, + regclass: _Unwind_VRS_RegClass, + regno: _Unwind_Word, + repr: _Unwind_VRS_DataRepresentation, + data: *mut c_void) + -> _Unwind_VRS_Result; + } - // On Android or ARM/Linux, these are implemented as macros: + // On Android or ARM/Linux, these are implemented as macros: - pub unsafe fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word { - let mut val: _Unwind_Word = core::ptr::null(); - unsafe { _Unwind_VRS_Get(ctx, _UVRSC_CORE, reg_index as _Unwind_Word, _UVRSD_UINT32, - (&raw mut val) as *mut c_void); } - val - } + pub unsafe fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word { + let mut val: _Unwind_Word = core::ptr::null(); + unsafe { _Unwind_VRS_Get(ctx, _UVRSC_CORE, reg_index as _Unwind_Word, _UVRSD_UINT32, + (&raw mut val) as *mut c_void); } + val + } - pub unsafe fn _Unwind_SetGR(ctx: *mut _Unwind_Context, reg_index: c_int, value: _Unwind_Word) { - let mut value = value; - unsafe { _Unwind_VRS_Set(ctx, _UVRSC_CORE, reg_index as _Unwind_Word, _UVRSD_UINT32, - (&raw mut value) as *mut c_void); } - } + pub unsafe fn _Unwind_SetGR( + ctx: *mut _Unwind_Context, + reg_index: c_int, + value: _Unwind_Word + ) { + let mut value = value; + unsafe { _Unwind_VRS_Set(ctx, _UVRSC_CORE, reg_index as _Unwind_Word, _UVRSD_UINT32, + (&raw mut value) as *mut c_void); } + } - pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) - -> _Unwind_Word { - let val = unsafe { _Unwind_GetGR(ctx, UNWIND_IP_REG) }; - val.map_addr(|v| v & !1) - } + pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) + -> _Unwind_Word { + let val = unsafe { _Unwind_GetGR(ctx, UNWIND_IP_REG) }; + val.map_addr(|v| v & !1) + } - pub unsafe fn _Unwind_SetIP(ctx: *mut _Unwind_Context, - value: _Unwind_Word) { - // Propagate thumb bit to instruction pointer - let thumb_state = unsafe { _Unwind_GetGR(ctx, UNWIND_IP_REG).addr() & 1 }; - let value = value.map_addr(|v| v | thumb_state); - unsafe { _Unwind_SetGR(ctx, UNWIND_IP_REG, value); } - } + pub unsafe fn _Unwind_SetIP(ctx: *mut _Unwind_Context, + value: _Unwind_Word) { + // Propagate thumb bit to instruction pointer + let thumb_state = unsafe { _Unwind_GetGR(ctx, UNWIND_IP_REG).addr() & 1 }; + let value = value.map_addr(|v| v | thumb_state); + unsafe { _Unwind_SetGR(ctx, UNWIND_IP_REG, value); } + } - pub unsafe fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context, - ip_before_insn: *mut c_int) - -> _Unwind_Word { - unsafe { - *ip_before_insn = 0; - _Unwind_GetIP(ctx) + pub unsafe fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context, + ip_before_insn: *mut c_int) + -> _Unwind_Word { + unsafe { + *ip_before_insn = 0; + _Unwind_GetIP(ctx) + } } - } - // This function also doesn't exist on Android or ARM/Linux, so make it a no-op - pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void { - pc + // This function also doesn't exist on Android or ARM/Linux, so make it a no-op + pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void { + pc + } } } -} // cfg_if! - -cfg_if::cfg_if! { -if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm"))] { - // 32-bit ARM Apple (except for watchOS armv7k specifically) uses SjLj and - // does not provide _Unwind_Backtrace() - unsafe extern "C-unwind" { - pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code; - } - pub use _Unwind_SjLj_RaiseException as _Unwind_RaiseException; -} else { - #[cfg_attr( - all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")), - link(name = "unwind", kind = "static", modifiers = "-bundle") - )] - unsafe extern "C-unwind" { - pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code; +cfg_select! { + all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm") => { + // 32-bit ARM Apple (except for watchOS armv7k specifically) uses SjLj and + // does not provide _Unwind_Backtrace() + unsafe extern "C-unwind" { + pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code; + } + + pub use _Unwind_SjLj_RaiseException as _Unwind_RaiseException; } - #[cfg_attr( - all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")), - link(name = "unwind", kind = "static", modifiers = "-bundle") - )] - unsafe extern "C" { - pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn, - trace_argument: *mut c_void) - -> _Unwind_Reason_Code; + _ => { + #[cfg_attr( + all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")), + link(name = "unwind", kind = "static", modifiers = "-bundle") + )] + unsafe extern "C-unwind" { + pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code; + } + #[cfg_attr( + all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")), + link(name = "unwind", kind = "static", modifiers = "-bundle") + )] + unsafe extern "C" { + pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn, + trace_argument: *mut c_void) + -> _Unwind_Reason_Code; + } } } -} // cfg_if! -cfg_if::cfg_if! { -if #[cfg(any( +cfg_select! { + any( all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"), target_os = "cygwin", - ))] { - // We declare these as opaque types. This is fine since you just need to - // pass them to _GCC_specific_handler and forget about them. - pub enum EXCEPTION_RECORD {} - pub type LPVOID = *mut c_void; - pub enum CONTEXT {} - pub enum DISPATCHER_CONTEXT {} - pub type EXCEPTION_DISPOSITION = c_int; - type PersonalityFn = unsafe extern "C" fn(version: c_int, - actions: _Unwind_Action, - exception_class: _Unwind_Exception_Class, - exception_object: *mut _Unwind_Exception, - context: *mut _Unwind_Context) - -> _Unwind_Reason_Code; - - unsafe extern "C" { - pub fn _GCC_specific_handler(exceptionRecord: *mut EXCEPTION_RECORD, - establisherFrame: LPVOID, - contextRecord: *mut CONTEXT, - dispatcherContext: *mut DISPATCHER_CONTEXT, - personality: PersonalityFn) - -> EXCEPTION_DISPOSITION; + ) => { + // We declare these as opaque types. This is fine since you just need to + // pass them to _GCC_specific_handler and forget about them. + pub enum EXCEPTION_RECORD {} + pub type LPVOID = *mut c_void; + pub enum CONTEXT {} + pub enum DISPATCHER_CONTEXT {} + pub type EXCEPTION_DISPOSITION = c_int; + type PersonalityFn = unsafe extern "C" fn(version: c_int, + actions: _Unwind_Action, + exception_class: _Unwind_Exception_Class, + exception_object: *mut _Unwind_Exception, + context: *mut _Unwind_Context) + -> _Unwind_Reason_Code; + + unsafe extern "C" { + pub fn _GCC_specific_handler(exceptionRecord: *mut EXCEPTION_RECORD, + establisherFrame: LPVOID, + contextRecord: *mut CONTEXT, + dispatcherContext: *mut DISPATCHER_CONTEXT, + personality: PersonalityFn) + -> EXCEPTION_DISPOSITION; + } } + _ => {} } -} // cfg_if! diff --git a/library/unwind/src/wasm.rs b/library/unwind/src/wasm.rs index 2d36a8be004..3341e54759a 100644 --- a/library/unwind/src/wasm.rs +++ b/library/unwind/src/wasm.rs @@ -45,18 +45,19 @@ pub unsafe fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwi // via integers, with 0 corresponding to C++ exceptions and 1 to C setjmp()/longjmp(). // Ideally, we'd be able to choose something unique for Rust, but for now, // we pretend to be C++ and implement the Itanium exception-handling ABI. - cfg_if::cfg_if! { + cfg_select! { // panic=abort is default for wasm targets. Because an unknown instruction is a load-time // error on wasm, instead of a runtime error like on traditional architectures, we never // want to codegen a `throw` instruction, as that would break users using runtimes that // don't yet support exceptions. The only time this first branch would be selected is if // the user explicitly opts in to wasm exceptions, via -Zbuild-std with -Cpanic=unwind. - if #[cfg(panic = "unwind")] { + panic = "unwind" => { // corresponds with llvm::WebAssembly::Tag::CPP_EXCEPTION // in llvm-project/llvm/include/llvm/CodeGen/WasmEHFuncInfo.h const CPP_EXCEPTION_TAG: i32 = 0; core::arch::wasm::throw::<CPP_EXCEPTION_TAG>(exception.cast()) - } else { + } + _ => { let _ = exception; core::arch::wasm::unreachable() } |
