library: Migrate from cfg_if to cfg_select

Migrate the standard library from using the external `cfg_if` crate to
using the now-built-in `cfg_select` macro.

This does not yet eliminate the dependency from
`library/std/Cargo.toml`, because while the standard library itself no
longer uses `cfg_if`, it also incorporates the `backtrace` crate, which
does.

Migration assisted by the following vim command (after selecting the
full `cfg_if!` invocation):

```
'<,'>s/\(cfg_if::\)\?cfg_if/cfg_select/ | '<,'>s/^\( *\)} else {/\1}\r\1_ => {/c | '<,'>s/^\( *\)} else if #\[cfg(\(.*\))\] /\1}\r\1\2 => /e | '<,'>s/if #\[cfg(\(.*\))\] {/\1 => {/e
```

This is imperfect, but substantially accelerated the process. This
prompts for confirmation on the `} else {` since that can also appear
inside one of the arms. This also requires manual intervention to handle
any multi-line conditions.
This commit is contained in:
Josh Triplett
2025-08-10 14:25:43 -07:00
parent 3507a749b3
commit 1ae4a0cc34
66 changed files with 847 additions and 609 deletions

View File

@@ -337,7 +337,6 @@ name = "std_detect"
version = "0.1.5" version = "0.1.5"
dependencies = [ dependencies = [
"alloc", "alloc",
"cfg-if",
"core", "core",
"libc", "libc",
] ]
@@ -376,7 +375,6 @@ dependencies = [
name = "unwind" name = "unwind"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"cfg-if",
"libc", "libc",
"rustc-std-workspace-core", "rustc-std-workspace-core",
"unwinding", "unwinding",

View File

@@ -14,6 +14,7 @@ crate-type = ["dylib", "rlib"]
[dependencies] [dependencies]
alloc = { path = "../alloc", public = true } 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'] } cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true } panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" } panic_abort = { path = "../panic_abort" }

View File

@@ -63,10 +63,11 @@ where
R: Read, R: Read,
W: Write, W: Write,
{ {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any(target_os = "linux", target_os = "android"))] { any(target_os = "linux", target_os = "android") => {
crate::sys::kernel_copy::copy_spec(reader, writer) crate::sys::kernel_copy::copy_spec(reader, writer)
} else { }
_ => {
generic_copy(reader, writer) generic_copy(reader, writer)
} }
} }

View File

@@ -330,6 +330,7 @@
#![feature(bstr)] #![feature(bstr)]
#![feature(bstr_internals)] #![feature(bstr_internals)]
#![feature(cast_maybe_uninit)] #![feature(cast_maybe_uninit)]
#![feature(cfg_select)]
#![feature(char_internals)] #![feature(char_internals)]
#![feature(clone_to_uninit)] #![feature(clone_to_uninit)]
#![feature(const_cmp)] #![feature(const_cmp)]

View File

@@ -1,14 +1,16 @@
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
target_os = "linux", target_os = "android", target_os = "linux", target_os = "android",
target_os = "hurd", target_os = "hurd",
target_os = "dragonfly", target_os = "freebsd", target_os = "dragonfly", target_os = "freebsd",
target_os = "openbsd", target_os = "netbsd", target_os = "openbsd", target_os = "netbsd",
target_os = "solaris", target_os = "illumos", target_os = "solaris", target_os = "illumos",
target_os = "haiku", target_os = "nto", target_os = "haiku", target_os = "nto",
target_os = "cygwin"))] { target_os = "cygwin",
) => {
use libc::MSG_NOSIGNAL; use libc::MSG_NOSIGNAL;
} else { }
_ => {
const MSG_NOSIGNAL: core::ffi::c_int = 0x0; const MSG_NOSIGNAL: core::ffi::c_int = 0x0;
} }
} }

View File

@@ -4,8 +4,6 @@
#![stable(feature = "rust1", since = "1.0.0")] #![stable(feature = "rust1", since = "1.0.0")]
use cfg_if::cfg_if;
use crate::ffi::OsStr; use crate::ffi::OsStr;
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use crate::path::Path; use crate::path::Path;
@@ -13,17 +11,19 @@ use crate::sealed::Sealed;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
use crate::{io, process, sys}; use crate::{io, process, sys};
cfg_if! { cfg_select! {
if #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon", target_os = "vita"))] { any(target_os = "vxworks", target_os = "espidf", target_os = "horizon", target_os = "vita") => {
type UserId = u16; type UserId = u16;
type GroupId = 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. // Both IDs are signed, see `sys/target_nto.h` of the QNX Neutrino SDP.
// Only positive values should be used, see e.g. // 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 // https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/s/setuid.html
type UserId = i32; type UserId = i32;
type GroupId = i32; type GroupId = i32;
} else { }
_ => {
type UserId = u32; type UserId = u32;
type GroupId = u32; type GroupId = u32;
} }

View File

@@ -1,5 +1,3 @@
use cfg_if::cfg_if;
use crate::cell::UnsafeCell; use crate::cell::UnsafeCell;
use crate::fmt; use crate::fmt;
use crate::ops::Deref; use crate::ops::Deref;
@@ -87,8 +85,8 @@ pub struct ReentrantLock<T: ?Sized> {
data: T, data: T,
} }
cfg_if!( cfg_select!(
if #[cfg(target_has_atomic = "64")] { target_has_atomic = "64" => {
use crate::sync::atomic::{Atomic, AtomicU64, Ordering::Relaxed}; use crate::sync::atomic::{Atomic, AtomicU64, Ordering::Relaxed};
struct Tid(Atomic<u64>); struct Tid(Atomic<u64>);
@@ -110,7 +108,8 @@ cfg_if!(
self.0.store(value, Relaxed); self.0.store(value, Relaxed);
} }
} }
} else { }
_ => {
/// Returns the address of a TLS variable. This is guaranteed to /// Returns the address of a TLS variable. This is guaranteed to
/// be unique across all currently alive threads. /// be unique across all currently alive threads.
fn tls_addr() -> usize { fn tls_addr() -> usize {

View File

@@ -68,29 +68,37 @@ unsafe fn realloc_fallback(
} }
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
target_family = "unix", target_family = "unix",
target_os = "wasi", target_os = "wasi",
target_os = "teeos", target_os = "teeos",
target_os = "trusty", target_os = "trusty",
))] { ) => {
mod unix; mod unix;
} else if #[cfg(target_os = "windows")] { }
target_os = "windows" => {
mod windows; mod windows;
} else if #[cfg(target_os = "hermit")] { }
target_os = "hermit" => {
mod hermit; mod hermit;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { }
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx; mod sgx;
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod solid; mod solid;
} else if #[cfg(target_os = "uefi")] { }
target_os = "uefi" => {
mod uefi; mod uefi;
} else if #[cfg(target_family = "wasm")] { }
target_family = "wasm" => {
mod wasm; mod wasm;
} else if #[cfg(target_os = "xous")] { }
target_os = "xous" => {
mod xous; mod xous;
} else if #[cfg(target_os = "zkvm")] { }
target_os = "zkvm" => {
mod zkvm; mod zkvm;
} }
} }

View File

@@ -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 // We use posix_memalign wherever possible, but some targets have very incomplete POSIX coverage
// so we need a fallback for those. // so we need a fallback for those.
if #[cfg(any( any(target_os = "horizon", target_os = "vita") => {
target_os = "horizon",
target_os = "vita",
))] {
#[inline] #[inline]
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
unsafe { libc::memalign(layout.align(), layout.size()) as *mut u8 } unsafe { libc::memalign(layout.align(), layout.size()) as *mut u8 }
} }
} else { }
_ => {
#[inline] #[inline]
#[cfg_attr(target_os = "vxworks", allow(unused_unsafe))] #[cfg_attr(target_os = "vxworks", allow(unused_unsafe))]
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {

View File

@@ -1,13 +1,15 @@
#![forbid(unsafe_op_in_unsafe_fn)] #![forbid(unsafe_op_in_unsafe_fn)]
cfg_if::cfg_if! { cfg_select! {
if #[cfg(unix)] { unix => {
mod unix; mod unix;
pub use unix::{AnonPipe, pipe}; pub use unix::{AnonPipe, pipe};
} else if #[cfg(windows)] { }
windows => {
mod windows; mod windows;
pub use windows::{AnonPipe, pipe}; pub use windows::{AnonPipe, pipe};
} else { }
_ => {
mod unsupported; mod unsupported;
pub use unsupported::{AnonPipe, pipe}; pub use unsupported::{AnonPipe, pipe};
} }

View File

@@ -12,32 +12,39 @@
))] ))]
mod common; mod common;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))), all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))),
target_os = "hermit", target_os = "hermit",
))] { ) => {
mod unix; mod unix;
pub use unix::*; pub use unix::*;
} else if #[cfg(target_family = "windows")] { }
target_family = "windows" => {
mod windows; mod windows;
pub use windows::*; pub use windows::*;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { }
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx; mod sgx;
pub use sgx::*; pub use sgx::*;
} else if #[cfg(target_os = "uefi")] { }
target_os = "uefi" => {
mod uefi; mod uefi;
pub use uefi::*; pub use uefi::*;
} else if #[cfg(target_os = "wasi")] { }
target_os = "wasi" => {
mod wasi; mod wasi;
pub use wasi::*; pub use wasi::*;
} else if #[cfg(target_os = "xous")] { }
target_os = "xous" => {
mod xous; mod xous;
pub use xous::*; pub use xous::*;
} else if #[cfg(target_os = "zkvm")] { }
target_os = "zkvm" => {
mod zkvm; mod zkvm;
pub use zkvm::*; pub use zkvm::*;
} else { }
_ => {
mod unsupported; mod unsupported;
pub use unsupported::*; pub use unsupported::*;
} }

View File

@@ -45,18 +45,65 @@ unsafe extern "C" {
pub safe fn lgammaf128_r(n: f128, s: &mut i32) -> f128; pub safe fn lgammaf128_r(n: f128, s: &mut i32) -> f128;
pub safe fn erff128(n: f128) -> f128; pub safe fn erff128(n: f128) -> f128;
pub safe fn erfcf128(n: f128) -> f128; pub safe fn erfcf128(n: f128) -> f128;
}
cfg_if::cfg_if! { cfg_select! {
if #[cfg(not(all(target_os = "windows", target_env = "msvc", target_arch = "x86")))] { all(target_os = "windows", target_env = "msvc", target_arch = "x86") => {
pub safe fn acosf(n: f32) -> f32; // On 32-bit x86 MSVC these functions aren't defined, so we just define shims
pub safe fn asinf(n: f32) -> f32; // which promote everything to f64, perform the calculation, and then demote
pub safe fn atan2f(a: f32, b: f32) -> f32; // back to f32. While not precisely correct should be "correct enough" for now.
pub safe fn atanf(n: f32) -> f32; #[inline]
pub safe fn coshf(n: f32) -> f32; pub fn acosf(n: f32) -> f32 {
pub safe fn sinhf(n: f32) -> f32; f64::acos(n as f64) as f32
pub safe fn tanf(n: f32) -> f32; }
pub safe fn tanhf(n: f32) -> 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 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 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 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 // On AIX, we don't have lgammaf_r only the f64 version, so we can
@@ -65,49 +112,3 @@ unsafe extern "C" {
pub fn lgammaf_r(n: f32, s: &mut i32) -> f32 { pub fn lgammaf_r(n: f32, s: &mut i32) -> f32 {
lgamma_r(n.into(), s) as f32 lgamma_r(n.into(), s) 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 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 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 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
}
}}

View File

@@ -13,35 +13,44 @@
))] ))]
mod common; mod common;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_family = "unix")] { target_family = "unix" => {
mod unix; mod unix;
pub use unix::*; pub use unix::*;
} else if #[cfg(target_family = "windows")] { }
target_family = "windows" => {
mod windows; mod windows;
pub use windows::*; pub use windows::*;
} else if #[cfg(target_os = "hermit")] { }
target_os = "hermit" => {
mod hermit; mod hermit;
pub use hermit::*; pub use hermit::*;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { }
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx; mod sgx;
pub use sgx::*; pub use sgx::*;
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod solid; mod solid;
pub use solid::*; pub use solid::*;
} else if #[cfg(target_os = "uefi")] { }
target_os = "uefi" => {
mod uefi; mod uefi;
pub use uefi::*; pub use uefi::*;
} else if #[cfg(target_os = "wasi")] { }
target_os = "wasi" => {
mod wasi; mod wasi;
pub use wasi::*; pub use wasi::*;
} else if #[cfg(target_os = "xous")] { }
target_os = "xous" => {
mod xous; mod xous;
pub use xous::*; pub use xous::*;
} else if #[cfg(target_os = "zkvm")] { }
target_os = "zkvm" => {
mod zkvm; mod zkvm;
pub use zkvm::*; pub use zkvm::*;
} else { }
_ => {
mod unsupported; mod unsupported;
pub use unsupported::*; pub use unsupported::*;
} }

View File

@@ -7,8 +7,8 @@ use crate::os::wasi::prelude::*;
use crate::sys::common::small_c_string::run_with_cstr; use crate::sys::common::small_c_string::run_with_cstr;
use crate::sys::pal::os::{cvt, libc}; use crate::sys::pal::os::{cvt, libc};
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_feature = "atomics")] { target_feature = "atomics" => {
// Access to the environment must be protected by a lock in multi-threaded scenarios. // Access to the environment must be protected by a lock in multi-threaded scenarios.
use crate::sync::{PoisonError, RwLock}; use crate::sync::{PoisonError, RwLock};
static ENV_LOCK: RwLock<()> = RwLock::new(()); static ENV_LOCK: RwLock<()> = RwLock::new(());
@@ -18,7 +18,8 @@ cfg_if::cfg_if! {
pub fn env_write_lock() -> impl Drop { pub fn env_write_lock() -> impl Drop {
ENV_LOCK.write().unwrap_or_else(PoisonError::into_inner) ENV_LOCK.write().unwrap_or_else(PoisonError::into_inner)
} }
} else { }
_ => {
// No need for a lock if we are single-threaded. // No need for a lock if we are single-threaded.
pub fn env_read_lock() -> impl Drop { pub fn env_read_lock() -> impl Drop {
Box::new(()) Box::new(())

View File

@@ -1,5 +1,5 @@
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "linux")] { target_os = "linux" => {
/// Mitigation for <https://github.com/rust-lang/rust/issues/126600> /// Mitigation for <https://github.com/rust-lang/rust/issues/126600>
/// ///
/// On glibc, `libc::exit` has been observed to not always be thread-safe. /// 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 for <https://github.com/rust-lang/rust/issues/126600>
/// ///
/// Mitigation is ***NOT*** implemented on this platform, either because this platform /// Mitigation is ***NOT*** implemented on this platform, either because this platform

View File

@@ -2,18 +2,22 @@
#![forbid(unsafe_op_in_unsafe_fn)] #![forbid(unsafe_op_in_unsafe_fn)]
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_family = "unix")] { target_family = "unix" => {
mod unix; mod unix;
pub use unix::*; pub use unix::*;
} else if #[cfg(target_os = "hermit")] { }
target_os = "hermit" => {
mod hermit; mod hermit;
pub use hermit::*; pub use hermit::*;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { }
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx; mod sgx;
pub use sgx::*; pub use sgx::*;
} else if #[cfg(target_os = "wasi")] { }
target_os = "wasi" => {
mod wasi; mod wasi;
pub use wasi::*; pub use wasi::*;
} }
_ => {}
} }

View File

@@ -5,8 +5,8 @@ use crate::path::{Path, PathBuf};
pub mod common; pub mod common;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_family = "unix")] { target_family = "unix" => {
mod unix; mod unix;
use unix as imp; use unix as imp;
pub use unix::{chown, fchown, lchown, mkfifo}; pub use unix::{chown, fchown, lchown, mkfifo};
@@ -16,24 +16,30 @@ cfg_if::cfg_if! {
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
pub(crate) use unix::CachedFileMetadata; pub(crate) use unix::CachedFileMetadata;
use crate::sys::common::small_c_string::run_path_with_cstr as with_native_path; 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; mod windows;
use windows as imp; use windows as imp;
pub use windows::{symlink_inner, junction_point}; pub use windows::{symlink_inner, junction_point};
use crate::sys::path::with_native_path; use crate::sys::path::with_native_path;
} else if #[cfg(target_os = "hermit")] { }
target_os = "hermit" => {
mod hermit; mod hermit;
use hermit as imp; use hermit as imp;
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod solid; mod solid;
use solid as imp; use solid as imp;
} else if #[cfg(target_os = "uefi")] { }
target_os = "uefi" => {
mod uefi; mod uefi;
use uefi as imp; use uefi as imp;
} else if #[cfg(target_os = "wasi")] { }
target_os = "wasi" => {
mod wasi; mod wasi;
use wasi as imp; use wasi as imp;
} else { }
_ => {
mod unsupported; mod unsupported;
use unsupported as imp; use unsupported as imp;
} }

View File

@@ -101,10 +101,11 @@ pub struct File(FileDesc);
// https://github.com/rust-lang/rust/pull/67774 // https://github.com/rust-lang/rust/pull/67774
macro_rules! cfg_has_statx { macro_rules! cfg_has_statx {
({ $($then_tt:tt)* } else { $($else_tt:tt)* }) => { ({ $($then_tt:tt)* } else { $($else_tt:tt)* }) => {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(all(target_os = "linux", target_env = "gnu"))] { all(target_os = "linux", target_env = "gnu") => {
$($then_tt)* $($then_tt)*
} else { }
_ => {
$($else_tt)* $($else_tt)*
} }
} }
@@ -1505,8 +1506,8 @@ impl File {
)), )),
None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }), None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
}; };
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx"))] { any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx") => {
// Redox doesn't appear to support `UTIME_OMIT`. // 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 // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
// the same as for Redox. // the same as for Redox.
@@ -1515,7 +1516,8 @@ impl File {
io::ErrorKind::Unsupported, io::ErrorKind::Unsupported,
"setting file times not supported", "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 buf = [mem::MaybeUninit::<libc::timespec>::uninit(); 3];
let mut num_times = 0; let mut num_times = 0;
let mut attrlist: libc::attrlist = unsafe { mem::zeroed() }; let mut attrlist: libc::attrlist = unsafe { mem::zeroed() };
@@ -1543,7 +1545,8 @@ impl File {
0 0
) })?; ) })?;
Ok(()) Ok(())
} else if #[cfg(target_os = "android")] { }
target_os = "android" => {
let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?]; let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
// futimens requires Android API level 19 // futimens requires Android API level 19
cvt(unsafe { cvt(unsafe {
@@ -1559,7 +1562,8 @@ impl File {
} }
})?; })?;
Ok(()) Ok(())
} else { }
_ => {
#[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))] #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))]
{ {
use crate::sys::{time::__timespec64, weak::weak}; use crate::sys::{time::__timespec64, weak::weak};
@@ -1677,13 +1681,14 @@ impl fmt::Debug for File {
let mut buf = vec![0; libc::PATH_MAX as usize]; let mut buf = vec![0; libc::PATH_MAX as usize];
let n = unsafe { libc::fcntl(fd, libc::F_GETPATH, buf.as_ptr()) }; let n = unsafe { libc::fcntl(fd, libc::F_GETPATH, buf.as_ptr()) };
if n == -1 { if n == -1 {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "netbsd")] { target_os = "netbsd" => {
// fallback to procfs as last resort // fallback to procfs as last resort
let mut p = PathBuf::from("/proc/self/fd"); let mut p = PathBuf::from("/proc/self/fd");
p.push(&fd.to_string()); p.push(&fd.to_string());
return run_path_with_cstr(&p, &readlink).ok() return run_path_with_cstr(&p, &readlink).ok()
} else { }
_ => {
return None; return None;
} }
} }
@@ -1884,15 +1889,16 @@ pub fn symlink(original: &CStr, link: &CStr) -> io::Result<()> {
} }
pub fn link(original: &CStr, link: &CStr) -> io::Result<()> { pub fn link(original: &CStr, link: &CStr) -> io::Result<()> {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_env = "nto70"))] { 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 // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves
// it implementation-defined whether `link` follows symlinks, so rely on the // 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. // `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` // Android has `linkat` on newer versions, but we happen to know `link`
// always has the correct behavior, so it's here as well. // always has the correct behavior, so it's here as well.
cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?; cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
} else { }
_ => {
// Where we can, use `linkat` instead of `link`; see the comment above // Where we can, use `linkat` instead of `link`; see the comment above
// this one for details on why. // this one for details on why.
cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?; cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;

View File

@@ -1,20 +1,24 @@
#![forbid(unsafe_op_in_unsafe_fn)] #![forbid(unsafe_op_in_unsafe_fn)]
mod io_slice { mod io_slice {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty"))] { any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty") => {
mod iovec; mod iovec;
pub use iovec::*; pub use iovec::*;
} else if #[cfg(target_os = "windows")] { }
target_os = "windows" => {
mod windows; mod windows;
pub use windows::*; pub use windows::*;
} else if #[cfg(target_os = "wasi")] { }
target_os = "wasi" => {
mod wasi; mod wasi;
pub use wasi::*; pub use wasi::*;
} else if #[cfg(target_os = "uefi")] { }
target_os = "uefi" => {
mod uefi; mod uefi;
pub use uefi::*; pub use uefi::*;
} else { }
_ => {
mod unsupported; mod unsupported;
pub use unsupported::*; pub use unsupported::*;
} }
@@ -22,17 +26,20 @@ mod io_slice {
} }
mod is_terminal { mod is_terminal {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any(target_family = "unix", target_os = "wasi"))] { any(target_family = "unix", target_os = "wasi") => {
mod isatty; mod isatty;
pub use isatty::*; pub use isatty::*;
} else if #[cfg(target_os = "windows")] { }
target_os = "windows" => {
mod windows; mod windows;
pub use windows::*; pub use windows::*;
} else if #[cfg(target_os = "hermit")] { }
target_os = "hermit" => {
mod hermit; mod hermit;
pub use hermit::*; pub use hermit::*;
} else { }
_ => {
mod unsupported; mod unsupported;
pub use unsupported::*; pub use unsupported::*;
} }

View File

@@ -9,29 +9,34 @@ use crate::sys_common::{AsInner, FromInner};
use crate::time::Duration; use crate::time::Duration;
use crate::{cmp, fmt, mem, ptr}; use crate::{cmp, fmt, mem, ptr};
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "hermit")] { target_os = "hermit" => {
mod hermit; mod hermit;
pub use hermit::*; pub use hermit::*;
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod solid; mod solid;
pub use solid::*; pub use solid::*;
} else if #[cfg(target_family = "unix")] { }
target_family = "unix" => {
mod unix; mod unix;
pub use unix::*; pub use unix::*;
} else if #[cfg(all(target_os = "wasi", target_env = "p2"))] { }
all(target_os = "wasi", target_env = "p2") => {
mod wasip2; mod wasip2;
pub use wasip2::*; pub use wasip2::*;
} else if #[cfg(target_os = "windows")] { }
target_os = "windows" => {
mod windows; mod windows;
pub use windows::*; pub use windows::*;
} }
_ => {}
} }
use netc as c; use netc as c;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
target_os = "dragonfly", target_os = "dragonfly",
target_os = "freebsd", target_os = "freebsd",
target_os = "openbsd", target_os = "openbsd",
@@ -43,39 +48,44 @@ cfg_if::cfg_if! {
target_os = "nto", target_os = "nto",
target_os = "nuttx", target_os = "nuttx",
target_vendor = "apple", target_vendor = "apple",
))] { ) => {
use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP;
} else { }
_ => {
use c::IPV6_ADD_MEMBERSHIP; use c::IPV6_ADD_MEMBERSHIP;
use c::IPV6_DROP_MEMBERSHIP; use c::IPV6_DROP_MEMBERSHIP;
} }
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
target_os = "linux", target_os = "android", target_os = "linux", target_os = "android",
target_os = "hurd", target_os = "hurd",
target_os = "dragonfly", target_os = "freebsd", target_os = "dragonfly", target_os = "freebsd",
target_os = "openbsd", target_os = "netbsd", target_os = "openbsd", target_os = "netbsd",
target_os = "solaris", target_os = "illumos", target_os = "solaris", target_os = "illumos",
target_os = "haiku", target_os = "nto", target_os = "haiku", target_os = "nto",
target_os = "cygwin"))] { target_os = "cygwin",
) => {
use libc::MSG_NOSIGNAL; use libc::MSG_NOSIGNAL;
} else { }
_ => {
const MSG_NOSIGNAL: c_int = 0x0; const MSG_NOSIGNAL: c_int = 0x0;
} }
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
target_os = "dragonfly", target_os = "freebsd", target_os = "dragonfly", target_os = "freebsd",
target_os = "openbsd", target_os = "netbsd", target_os = "openbsd", target_os = "netbsd",
target_os = "solaris", target_os = "illumos", target_os = "solaris", target_os = "illumos",
target_os = "nto"))] { target_os = "nto",
) => {
use crate::ffi::c_uchar; use crate::ffi::c_uchar;
type IpV4MultiCastType = c_uchar; type IpV4MultiCastType = c_uchar;
} else { }
_ => {
type IpV4MultiCastType = c_int; type IpV4MultiCastType = c_int;
} }
} }
@@ -523,17 +533,19 @@ impl TcpListener {
let (addr, len) = socket_addr_to_c(addr); let (addr, len) = socket_addr_to_c(addr);
cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?; cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "horizon")] { target_os = "horizon" => {
// The 3DS doesn't support a big connection backlog. Sometimes // The 3DS doesn't support a big connection backlog. Sometimes
// it allows up to about 37, but other times it doesn't even // it allows up to about 37, but other times it doesn't even
// accept 32. There may be a global limitation causing this. // accept 32. There may be a global limitation causing this.
let backlog = 20; let backlog = 20;
} else if #[cfg(target_os = "haiku")] { }
target_os = "haiku" => {
// Haiku does not support a queue length > 32 // Haiku does not support a queue length > 32
// https://github.com/haiku/haiku/blob/979a0bc487864675517fb2fab28f87dc8bf43041/headers/posix/sys/socket.h#L81 // https://github.com/haiku/haiku/blob/979a0bc487864675517fb2fab28f87dc8bf43041/headers/posix/sys/socket.h#L81
let backlog = 32; let backlog = 32;
} else { }
_ => {
// The default for all other platforms // The default for all other platforms
let backlog = 128; let backlog = 128;
} }

View File

@@ -12,10 +12,11 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::time::{Duration, Instant}; use crate::time::{Duration, Instant};
use crate::{cmp, mem}; use crate::{cmp, mem};
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_vendor = "apple")] { target_vendor = "apple" => {
use libc::SO_LINGER_SEC as SO_LINGER; use libc::SO_LINGER_SEC as SO_LINGER;
} else { }
_ => {
use libc::SO_LINGER; use libc::SO_LINGER;
} }
} }
@@ -72,8 +73,8 @@ impl Socket {
pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> { pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
unsafe { unsafe {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
target_os = "android", target_os = "android",
target_os = "dragonfly", target_os = "dragonfly",
target_os = "freebsd", target_os = "freebsd",
@@ -85,7 +86,7 @@ impl Socket {
target_os = "cygwin", target_os = "cygwin",
target_os = "nto", target_os = "nto",
target_os = "solaris", target_os = "solaris",
))] { ) => {
// On platforms that support it we pass the SOCK_CLOEXEC // On platforms that support it we pass the SOCK_CLOEXEC
// flag to atomically create the socket and set it as // flag to atomically create the socket and set it as
// CLOEXEC. On Linux this was added in 2.6.27. // 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)?; setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?;
Ok(socket) Ok(socket)
} else { }
_ => {
let fd = cvt(libc::socket(fam, ty, 0))?; let fd = cvt(libc::socket(fam, ty, 0))?;
let fd = FileDesc::from_raw_fd(fd); let fd = FileDesc::from_raw_fd(fd);
fd.set_cloexec()?; fd.set_cloexec()?;
@@ -120,8 +122,8 @@ impl Socket {
unsafe { unsafe {
let mut fds = [0, 0]; let mut fds = [0, 0];
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
target_os = "android", target_os = "android",
target_os = "dragonfly", target_os = "dragonfly",
target_os = "freebsd", target_os = "freebsd",
@@ -132,11 +134,12 @@ impl Socket {
target_os = "openbsd", target_os = "openbsd",
target_os = "cygwin", target_os = "cygwin",
target_os = "nto", target_os = "nto",
))] { ) => {
// Like above, set cloexec atomically // Like above, set cloexec atomically
cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr()))?; 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])))) 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()))?; cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?;
let a = FileDesc::from_raw_fd(fds[0]); let a = FileDesc::from_raw_fd(fds[0]);
let b = FileDesc::from_raw_fd(fds[1]); 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 // 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, // platforms that support it. On Linux, this was added in 2.6.28,
// glibc 2.10 and musl 0.9.5. // glibc 2.10 and musl 0.9.5.
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
target_os = "android", target_os = "android",
target_os = "dragonfly", target_os = "dragonfly",
target_os = "freebsd", target_os = "freebsd",
@@ -261,12 +264,13 @@ impl Socket {
target_os = "netbsd", target_os = "netbsd",
target_os = "openbsd", target_os = "openbsd",
target_os = "cygwin", target_os = "cygwin",
))] { ) => {
unsafe { unsafe {
let fd = cvt_r(|| libc::accept4(self.as_raw_fd(), storage, len, libc::SOCK_CLOEXEC))?; let fd = cvt_r(|| libc::accept4(self.as_raw_fd(), storage, len, libc::SOCK_CLOEXEC))?;
Ok(Socket(FileDesc::from_raw_fd(fd))) Ok(Socket(FileDesc::from_raw_fd(fd)))
} }
} else { }
_ => {
unsafe { unsafe {
let fd = cvt_r(|| libc::accept(self.as_raw_fd(), storage, len))?; let fd = cvt_r(|| libc::accept(self.as_raw_fd(), storage, len))?;
let fd = FileDesc::from_raw_fd(fd); let fd = FileDesc::from_raw_fd(fd);

View File

@@ -1,36 +1,41 @@
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
all(target_family = "unix", not(target_os = "l4re")), all(target_family = "unix", not(target_os = "l4re")),
target_os = "windows", target_os = "windows",
target_os = "hermit", target_os = "hermit",
all(target_os = "wasi", target_env = "p2"), all(target_os = "wasi", target_env = "p2"),
target_os = "solid_asp3", target_os = "solid_asp3",
))] { ) => {
mod connection { mod connection {
mod socket; mod socket;
pub use socket::*; pub use socket::*;
} }
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { }
all(target_vendor = "fortanix", target_env = "sgx") => {
mod connection { mod connection {
mod sgx; mod sgx;
pub use sgx::*; pub use sgx::*;
} }
} else if #[cfg(all(target_os = "wasi", target_env = "p1"))] { }
all(target_os = "wasi", target_env = "p1") => {
mod connection { mod connection {
mod wasip1; mod wasip1;
pub use wasip1::*; pub use wasip1::*;
} }
} else if #[cfg(target_os = "xous")] { }
target_os = "xous" => {
mod connection { mod connection {
mod xous; mod xous;
pub use xous::*; pub use xous::*;
} }
} else if #[cfg(target_os = "uefi")] { }
target_os = "uefi" => {
mod connection { mod connection {
mod uefi; mod uefi;
pub use uefi::*; pub use uefi::*;
} }
} else { }
_ => {
mod connection { mod connection {
mod unsupported; mod unsupported;
pub use unsupported::*; pub use unsupported::*;

View File

@@ -1,13 +1,11 @@
#![forbid(unsafe_op_in_unsafe_fn)] #![forbid(unsafe_op_in_unsafe_fn)]
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(target_os = "windows", target_os = "uefi") => {
target_os = "windows",
target_os = "uefi",
))] {
mod wtf8; mod wtf8;
pub use wtf8::{Buf, Slice}; pub use wtf8::{Buf, Slice};
} else { }
_ => {
mod bytes; mod bytes;
pub use bytes::{Buf, Slice}; pub use bytes::{Buf, Slice};
} }

View File

@@ -24,60 +24,70 @@
pub mod common; pub mod common;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(unix)] { unix => {
mod unix; mod unix;
pub use self::unix::*; pub use self::unix::*;
} else if #[cfg(windows)] { }
windows => {
mod windows; mod windows;
pub use self::windows::*; pub use self::windows::*;
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod solid; mod solid;
pub use self::solid::*; pub use self::solid::*;
} else if #[cfg(target_os = "hermit")] { }
target_os = "hermit" => {
mod hermit; mod hermit;
pub use self::hermit::*; pub use self::hermit::*;
} else if #[cfg(target_os = "trusty")] { }
target_os = "trusty" => {
mod trusty; mod trusty;
pub use self::trusty::*; pub use self::trusty::*;
} else if #[cfg(all(target_os = "wasi", target_env = "p2"))] { }
all(target_os = "wasi", target_env = "p2") => {
mod wasip2; mod wasip2;
pub use self::wasip2::*; pub use self::wasip2::*;
} else if #[cfg(target_os = "wasi")] { }
target_os = "wasi" => {
mod wasi; mod wasi;
pub use self::wasi::*; pub use self::wasi::*;
} else if #[cfg(target_family = "wasm")] { }
target_family = "wasm" => {
mod wasm; mod wasm;
pub use self::wasm::*; pub use self::wasm::*;
} else if #[cfg(target_os = "xous")] { }
target_os = "xous" => {
mod xous; mod xous;
pub use self::xous::*; pub use self::xous::*;
} else if #[cfg(target_os = "uefi")] { }
target_os = "uefi" => {
mod uefi; mod uefi;
pub use self::uefi::*; pub use self::uefi::*;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { }
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx; mod sgx;
pub use self::sgx::*; pub use self::sgx::*;
} else if #[cfg(target_os = "teeos")] { }
target_os = "teeos" => {
mod teeos; mod teeos;
pub use self::teeos::*; pub use self::teeos::*;
} else if #[cfg(target_os = "zkvm")] { }
target_os = "zkvm" => {
mod zkvm; mod zkvm;
pub use self::zkvm::*; pub use self::zkvm::*;
} else { }
_ => {
mod unsupported; mod unsupported;
pub use self::unsupported::*; pub use self::unsupported::*;
} }
} }
cfg_if::cfg_if! { pub const FULL_BACKTRACE_DEFAULT: bool = cfg_select! {
// Fuchsia components default to full backtrace. // Fuchsia components default to full backtrace.
if #[cfg(target_os = "fuchsia")] { target_os = "fuchsia" => true,
pub const FULL_BACKTRACE_DEFAULT: bool = true; _ => false,
} else { };
pub const FULL_BACKTRACE_DEFAULT: bool = false;
}
}
#[cfg(not(target_os = "uefi"))] #[cfg(not(target_os = "uefi"))]
pub type RawOsError = i32; pub type RawOsError = i32;

View File

@@ -296,12 +296,9 @@ pub(crate) mod instant_internal {
} }
pub fn platform_specific() -> Option<Instant> { pub fn platform_specific() -> Option<Instant> {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] { any(target_arch = "x86_64", target_arch = "x86") => timestamp_rdtsc().map(Instant),
timestamp_rdtsc().map(Instant) _ => None,
} else {
None
}
} }
} }

View File

@@ -46,8 +46,8 @@ pub fn futex_wait(futex: &Atomic<u32>, expected: u32, timeout: Option<Duration>)
} }
let r = unsafe { let r = unsafe {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "freebsd")] { target_os = "freebsd" => {
// FreeBSD doesn't have futex(), but it has // FreeBSD doesn't have futex(), but it has
// _umtx_op(UMTX_OP_WAIT_UINT_PRIVATE), which is nearly // _umtx_op(UMTX_OP_WAIT_UINT_PRIVATE), which is nearly
// identical. It supports absolute timeouts through a flag // 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), crate::ptr::without_provenance_mut(umtx_timeout_size),
umtx_timeout_ptr as *mut _, 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 // Use FUTEX_WAIT_BITSET rather than FUTEX_WAIT to be able to give an
// absolute time rather than a relative time. // absolute time rather than a relative time.
libc::syscall( 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. null::<u32>(), // This argument is unused for FUTEX_WAIT_BITSET.
!0u32, // A full bitmask, to make it behave like a regular FUTEX_WAIT. !0u32, // A full bitmask, to make it behave like a regular FUTEX_WAIT.
) )
} else { }
_ => {
compile_error!("unknown target_os"); compile_error!("unknown target_os");
} }
} }

View File

@@ -366,31 +366,36 @@ pub fn abort_internal() -> ! {
unsafe { libc::abort() } unsafe { libc::abort() }
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "android")] { target_os = "android" => {
#[link(name = "dl", kind = "static", modifiers = "-bundle", #[link(name = "dl", kind = "static", modifiers = "-bundle",
cfg(target_feature = "crt-static"))] cfg(target_feature = "crt-static"))]
#[link(name = "dl", cfg(not(target_feature = "crt-static")))] #[link(name = "dl", cfg(not(target_feature = "crt-static")))]
#[link(name = "log", cfg(not(target_feature = "crt-static")))] #[link(name = "log", cfg(not(target_feature = "crt-static")))]
unsafe extern "C" {} unsafe extern "C" {}
} else if #[cfg(target_os = "freebsd")] { }
target_os = "freebsd" => {
#[link(name = "execinfo")] #[link(name = "execinfo")]
#[link(name = "pthread")] #[link(name = "pthread")]
unsafe extern "C" {} unsafe extern "C" {}
} else if #[cfg(target_os = "netbsd")] { }
target_os = "netbsd" => {
#[link(name = "pthread")] #[link(name = "pthread")]
#[link(name = "rt")] #[link(name = "rt")]
unsafe extern "C" {} 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")] #[link(name = "pthread")]
unsafe extern "C" {} unsafe extern "C" {}
} else if #[cfg(target_os = "solaris")] { }
target_os = "solaris" => {
#[link(name = "socket")] #[link(name = "socket")]
#[link(name = "posix4")] #[link(name = "posix4")]
#[link(name = "pthread")] #[link(name = "pthread")]
#[link(name = "resolv")] #[link(name = "resolv")]
unsafe extern "C" {} unsafe extern "C" {}
} else if #[cfg(target_os = "illumos")] { }
target_os = "illumos" => {
#[link(name = "socket")] #[link(name = "socket")]
#[link(name = "posix4")] #[link(name = "posix4")]
#[link(name = "pthread")] #[link(name = "pthread")]
@@ -399,24 +404,29 @@ cfg_if::cfg_if! {
// Use libumem for the (malloc-compatible) allocator // Use libumem for the (malloc-compatible) allocator
#[link(name = "umem")] #[link(name = "umem")]
unsafe extern "C" {} unsafe extern "C" {}
} else if #[cfg(target_vendor = "apple")] { }
target_vendor = "apple" => {
// Link to `libSystem.dylib`. // Link to `libSystem.dylib`.
// //
// Don't get confused by the presence of `System.framework`, // Don't get confused by the presence of `System.framework`,
// it is a deprecated wrapper over the dynamic library. // it is a deprecated wrapper over the dynamic library.
#[link(name = "System")] #[link(name = "System")]
unsafe extern "C" {} unsafe extern "C" {}
} else if #[cfg(target_os = "fuchsia")] { }
target_os = "fuchsia" => {
#[link(name = "zircon")] #[link(name = "zircon")]
#[link(name = "fdio")] #[link(name = "fdio")]
unsafe extern "C" {} unsafe extern "C" {}
} else if #[cfg(all(target_os = "linux", target_env = "uclibc"))] { }
all(target_os = "linux", target_env = "uclibc") => {
#[link(name = "dl")] #[link(name = "dl")]
unsafe extern "C" {} unsafe extern "C" {}
} else if #[cfg(target_os = "vita")] { }
target_os = "vita" => {
#[link(name = "pthread", kind = "static", modifiers = "-bundle")] #[link(name = "pthread", kind = "static", modifiers = "-bundle")]
unsafe extern "C" {} unsafe extern "C" {}
} }
_ => {}
} }
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))]

View File

@@ -17,13 +17,10 @@ use crate::{fmt, io, iter, mem, ptr, slice, str};
const TMPBUF_SZ: usize = 128; const TMPBUF_SZ: usize = 128;
cfg_if::cfg_if! { const PATH_SEPARATOR: u8 = cfg_select! {
if #[cfg(target_os = "redox")] { target_os = "redox" => b';',
const PATH_SEPARATOR: u8 = b';'; _ => b':',
} else { };
const PATH_SEPARATOR: u8 = b':';
}
}
unsafe extern "C" { unsafe extern "C" {
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))] #[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 { pub fn temp_dir() -> PathBuf {
crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| { crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(all(target_vendor = "apple", not(miri)))] { all(target_vendor = "apple", not(miri)) => darwin_temp_dir(),
darwin_temp_dir() target_os = "android" => PathBuf::from("/data/local/tmp"),
} else if #[cfg(target_os = "android")] { _ => PathBuf::from("/tmp"),
PathBuf::from("/data/local/tmp")
} else {
PathBuf::from("/tmp")
}
} }
}) })
} }

View File

@@ -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 // 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 // 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. // and musl 0.9.3, and some other targets also have it.
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
target_os = "dragonfly", target_os = "dragonfly",
target_os = "freebsd", target_os = "freebsd",
target_os = "hurd", target_os = "hurd",
@@ -29,12 +29,13 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
target_os = "openbsd", target_os = "openbsd",
target_os = "cygwin", target_os = "cygwin",
target_os = "redox" target_os = "redox"
))] { ) => {
unsafe { unsafe {
cvt(libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC))?; 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])))) Ok((AnonPipe(FileDesc::from_raw_fd(fds[0])), AnonPipe(FileDesc::from_raw_fd(fds[1]))))
} }
} else { }
_ => {
unsafe { unsafe {
cvt(libc::pipe(fds.as_mut_ptr()))?; cvt(libc::pipe(fds.as_mut_ptr()))?;

View File

@@ -140,12 +140,13 @@ impl Thread {
))] ))]
pub fn set_name(name: &CStr) { pub fn set_name(name: &CStr) {
unsafe { unsafe {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any(target_os = "linux", target_os = "cygwin"))] { any(target_os = "linux", target_os = "cygwin") => {
// Linux and Cygwin limits the allowed length of the name. // Linux and Cygwin limits the allowed length of the name.
const TASK_COMM_LEN: usize = 16; const TASK_COMM_LEN: usize = 16;
let name = truncate_cstr::<{ TASK_COMM_LEN }>(name); let name = truncate_cstr::<{ TASK_COMM_LEN }>(name);
} else { }
_ => {
// FreeBSD, DragonFly BSD and NuttX do not enforce length limits. // FreeBSD, DragonFly BSD and NuttX do not enforce length limits.
} }
}; };
@@ -404,9 +405,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 // 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.). // 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`. // 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; use crate::sys::weak::syscall;
// `libc::gettid` is only available on glibc 2.30+, but the syscall is available // `libc::gettid` is only available on glibc 2.30+, but the syscall is available
@@ -416,28 +417,34 @@ pub(crate) fn current_os_id() -> Option<u64> {
// SAFETY: FFI call with no preconditions. // SAFETY: FFI call with no preconditions.
let id: libc::pid_t = unsafe { gettid() }; let id: libc::pid_t = unsafe { gettid() };
Some(id as u64) Some(id as u64)
} else if #[cfg(target_os = "nto")] { }
target_os = "nto" => {
// SAFETY: FFI call with no preconditions. // SAFETY: FFI call with no preconditions.
let id: libc::pid_t = unsafe { libc::gettid() }; let id: libc::pid_t = unsafe { libc::gettid() };
Some(id as u64) Some(id as u64)
} else if #[cfg(target_os = "openbsd")] { }
target_os = "openbsd" => {
// SAFETY: FFI call with no preconditions. // SAFETY: FFI call with no preconditions.
let id: libc::pid_t = unsafe { libc::getthrid() }; let id: libc::pid_t = unsafe { libc::getthrid() };
Some(id as u64) Some(id as u64)
} else if #[cfg(target_os = "freebsd")] { }
target_os = "freebsd" => {
// SAFETY: FFI call with no preconditions. // SAFETY: FFI call with no preconditions.
let id: libc::c_int = unsafe { libc::pthread_getthreadid_np() }; let id: libc::c_int = unsafe { libc::pthread_getthreadid_np() };
Some(id as u64) Some(id as u64)
} else if #[cfg(target_os = "netbsd")] { }
target_os = "netbsd" => {
// SAFETY: FFI call with no preconditions. // SAFETY: FFI call with no preconditions.
let id: libc::lwpid_t = unsafe { libc::_lwp_self() }; let id: libc::lwpid_t = unsafe { libc::_lwp_self() };
Some(id as u64) 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. // On Illumos and Solaris, the `pthread_t` is the same as the OS thread ID.
// SAFETY: FFI call with no preconditions. // SAFETY: FFI call with no preconditions.
let id: libc::pthread_t = unsafe { libc::pthread_self() }; let id: libc::pthread_t = unsafe { libc::pthread_self() };
Some(id as u64) 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. // Apple allows querying arbitrary thread IDs, `thread=NULL` queries the current thread.
let mut id = 0u64; let mut id = 0u64;
// SAFETY: `thread_id` is a valid pointer, no other preconditions. // SAFETY: `thread_id` is a valid pointer, no other preconditions.
@@ -447,10 +454,9 @@ pub(crate) fn current_os_id() -> Option<u64> {
} else { } else {
None 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,
} }
} }
@@ -472,8 +478,8 @@ fn truncate_cstr<const MAX_WITH_NUL: usize>(cstr: &CStr) -> [libc::c_char; MAX_W
} }
pub fn available_parallelism() -> io::Result<NonZero<usize>> { pub fn available_parallelism() -> io::Result<NonZero<usize>> {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
target_os = "android", target_os = "android",
target_os = "emscripten", target_os = "emscripten",
target_os = "fuchsia", target_os = "fuchsia",
@@ -482,7 +488,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
target_os = "aix", target_os = "aix",
target_vendor = "apple", target_vendor = "apple",
target_os = "cygwin", target_os = "cygwin",
))] { ) => {
#[allow(unused_assignments)] #[allow(unused_assignments)]
#[allow(unused_mut)] #[allow(unused_mut)]
let mut quota = usize::MAX; let mut quota = usize::MAX;
@@ -516,12 +522,13 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
Ok(unsafe { NonZero::new_unchecked(count) }) Ok(unsafe { NonZero::new_unchecked(count) })
} }
} }
} else if #[cfg(any( }
target_os = "freebsd", any(
target_os = "dragonfly", target_os = "freebsd",
target_os = "openbsd", target_os = "dragonfly",
target_os = "netbsd", target_os = "openbsd",
))] { target_os = "netbsd",
) => {
use crate::ptr; use crate::ptr;
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
@@ -596,7 +603,8 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
} }
Ok(unsafe { NonZero::new_unchecked(cpus as usize) }) Ok(unsafe { NonZero::new_unchecked(cpus as usize) })
} else if #[cfg(target_os = "nto")] { }
target_os = "nto" => {
unsafe { unsafe {
use libc::_syspage_ptr; use libc::_syspage_ptr;
if _syspage_ptr.is_null() { if _syspage_ptr.is_null() {
@@ -607,13 +615,15 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
.ok_or(io::Error::UNKNOWN_THREAD_COUNT) .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; let mut cpus = 0u32;
if unsafe { libc::pset_info(libc::PS_MYID, core::ptr::null_mut(), &mut cpus, core::ptr::null_mut()) } != 0 { 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); return Err(io::Error::UNKNOWN_THREAD_COUNT);
} }
Ok(unsafe { NonZero::new_unchecked(cpus as usize) }) 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` // 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` // `get_system_info` calls then `smp_get_num_cpus`
unsafe { unsafe {
@@ -626,7 +636,8 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
Ok(NonZero::new_unchecked(sinfo.cpu_count as 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 // Note: there is also `vxCpuConfiguredGet`, closer to _SC_NPROCESSORS_CONF
// expectations than the actual cores availability. // expectations than the actual cores availability.
unsafe extern "C" { unsafe extern "C" {
@@ -638,7 +649,8 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
let set = vxCpuEnabledGet(); let set = vxCpuEnabledGet();
Ok(NonZero::new_unchecked(set.count_ones() as usize)) Ok(NonZero::new_unchecked(set.count_ones() as usize))
} }
} else { }
_ => {
// FIXME: implement on Redox, l4re // 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")) Err(io::const_error!(io::ErrorKind::Unsupported, "getting the number of hardware threads is not supported on the target platform"))
} }

View File

@@ -5,8 +5,8 @@ use crate::num::NonZero;
use crate::time::{Duration, Instant}; use crate::time::{Duration, Instant};
use crate::{io, mem}; use crate::{io, mem};
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_feature = "atomics")] { target_feature = "atomics" => {
use crate::cmp; use crate::cmp;
use crate::ptr; use crate::ptr;
use crate::sys::os; use crate::sys::os;
@@ -62,7 +62,8 @@ cfg_if::cfg_if! {
debug_assert_eq!(ret, 0); debug_assert_eq!(ret, 0);
} }
} }
} else { }
_ => {
pub struct Thread(!); pub struct Thread(!);
} }
} }
@@ -71,8 +72,8 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
impl Thread { impl Thread {
// unsafe: see thread::Builder::spawn_unchecked for safety requirements // unsafe: see thread::Builder::spawn_unchecked for safety requirements
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_feature = "atomics")] { target_feature = "atomics" => {
pub unsafe fn new(stack: usize, _name: Option<&str>, p: Box<dyn FnOnce()>) -> io::Result<Thread> { 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 p = Box::into_raw(Box::new(p));
let mut native: libc::pthread_t = unsafe { mem::zeroed() }; let mut native: libc::pthread_t = unsafe { mem::zeroed() };
@@ -119,7 +120,8 @@ impl Thread {
ptr::null_mut() ptr::null_mut()
} }
} }
} else { }
_ => {
pub unsafe fn new(_stack: usize, _name: Option<&str>, _p: Box<dyn FnOnce()>) -> io::Result<Thread> { pub unsafe fn new(_stack: usize, _name: Option<&str>, _p: Box<dyn FnOnce()>) -> io::Result<Thread> {
crate::sys::unsupported() crate::sys::unsupported()
} }
@@ -180,14 +182,15 @@ impl Thread {
} }
pub fn join(self) { pub fn join(self) {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_feature = "atomics")] { target_feature = "atomics" => {
let id = mem::ManuallyDrop::new(self).id; let id = mem::ManuallyDrop::new(self).id;
let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
if ret != 0 { if ret != 0 {
rtabort!("failed to join thread: {}", io::Error::from_raw_os_error(ret)); rtabort!("failed to join thread: {}", io::Error::from_raw_os_error(ret));
} }
} else { }
_ => {
self.0 self.0
} }
} }
@@ -199,14 +202,13 @@ pub(crate) fn current_os_id() -> Option<u64> {
} }
pub fn available_parallelism() -> io::Result<NonZero<usize>> { pub fn available_parallelism() -> io::Result<NonZero<usize>> {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_feature = "atomics")] { target_feature = "atomics" => {
match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } { match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } {
-1 => Err(io::Error::last_os_error()), -1 => Err(io::Error::last_os_error()),
cpus => NonZero::new(cpus as usize).ok_or(io::Error::UNKNOWN_THREAD_COUNT), cpus => NonZero::new(cpus as usize).ok_or(io::Error::UNKNOWN_THREAD_COUNT),
} }
} else {
crate::sys::unsupported()
} }
_ => crate::sys::unsupported(),
} }
} }

View File

@@ -23,13 +23,14 @@ pub mod pipe;
#[path = "../unsupported/time.rs"] #[path = "../unsupported/time.rs"]
pub mod time; pub mod time;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_feature = "atomics")] { target_feature = "atomics" => {
#[path = "atomics/futex.rs"] #[path = "atomics/futex.rs"]
pub mod futex; pub mod futex;
#[path = "atomics/thread.rs"] #[path = "atomics/thread.rs"]
pub mod thread; pub mod thread;
} else { }
_ => {
#[path = "../unsupported/thread.rs"] #[path = "../unsupported/thread.rs"]
pub mod thread; pub mod thread;
} }

View File

@@ -95,11 +95,8 @@ pub struct MOUNT_POINT_REPARSE_BUFFER {
} }
// Desktop specific functions & types // Desktop specific functions & types
cfg_if::cfg_if! { #[cfg(not(target_vendor = "uwp"))]
if #[cfg(not(target_vendor = "uwp"))] { pub const EXCEPTION_CONTINUE_SEARCH: i32 = 0;
pub const EXCEPTION_CONTINUE_SEARCH: i32 = 0;
}
}
// Use raw-dylib to import ProcessPrng as we can't rely on there being an import library. // Use raw-dylib to import ProcessPrng as we can't rely on there being an import library.
#[cfg(not(target_vendor = "win7"))] #[cfg(not(target_vendor = "win7"))]
@@ -230,12 +227,13 @@ compat_fn_with_fallback! {
} }
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_vendor = "uwp")] { 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 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 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 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 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); windows_targets::link_raw_dylib!("ntdll.dll" "system" fn RtlNtStatusToDosError(status : NTSTATUS) -> u32);
} }
_ => {}
} }

View File

@@ -22,10 +22,11 @@ pub mod os;
pub mod pipe; pub mod pipe;
pub mod thread; pub mod thread;
pub mod time; pub mod time;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(not(target_vendor = "uwp"))] { not(target_vendor = "uwp") => {
pub mod stack_overflow; pub mod stack_overflow;
} else { }
_ => {
pub mod stack_overflow_uwp; pub mod stack_overflow_uwp;
pub use self::stack_overflow_uwp as stack_overflow; 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 #[cfg(not(miri))] // inline assembly does not work in Miri
pub fn abort_internal() -> ! { pub fn abort_internal() -> ! {
unsafe { unsafe {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { any(target_arch = "x86", target_arch = "x86_64") => {
core::arch::asm!("int $$0x29", in("ecx") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); 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)); 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)); core::arch::asm!("brk 0xF003", in("x0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
} else { }
_ => {
core::intrinsics::abort(); core::intrinsics::abort();
} }
} }

View File

@@ -1,22 +1,27 @@
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "windows")] { target_os = "windows" => {
mod windows; mod windows;
mod windows_prefix; mod windows_prefix;
pub use windows::*; pub use windows::*;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { }
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx; mod sgx;
pub use sgx::*; pub use sgx::*;
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod unsupported_backslash; mod unsupported_backslash;
pub use unsupported_backslash::*; pub use unsupported_backslash::*;
} else if #[cfg(target_os = "uefi")] { }
target_os = "uefi" => {
mod uefi; mod uefi;
pub use uefi::*; pub use uefi::*;
} else if #[cfg(target_os = "cygwin")] { }
target_os = "cygwin" => {
mod cygwin; mod cygwin;
mod windows_prefix; mod windows_prefix;
pub use cygwin::*; pub use cygwin::*;
} else { }
_ => {
mod unix; mod unix;
pub use unix::*; pub use unix::*;
} }

View File

@@ -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/master/libstdc++-v3/libsupc++/eh_personality.cc
// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
cfg_if::cfg_if! { cfg_select! {
if #[cfg(all( all(
target_arch = "arm", target_arch = "arm",
not(target_vendor = "apple"), not(target_vendor = "apple"),
not(target_os = "netbsd"), not(target_os = "netbsd"),
))] { ) => {
/// personality fn called by [ARM EHABI][armeabi-eh] /// personality fn called by [ARM EHABI][armeabi-eh]
/// ///
/// 32-bit ARM on iOS/tvOS/watchOS does not use ARM EHABI, it uses /// 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 /// Default personality routine, which is used directly on most targets
/// and indirectly on Windows x86_64 and AArch64 via SEH. /// and indirectly on Windows x86_64 and AArch64 via SEH.
unsafe extern "C" fn rust_eh_personality_impl( unsafe extern "C" fn rust_eh_personality_impl(
@@ -247,11 +248,11 @@ cfg_if::cfg_if! {
} }
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"), all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"),
target_os = "cygwin", target_os = "cygwin",
))] { ) => {
/// personality fn called by [Windows Structured Exception Handling][windows-eh] /// personality fn called by [Windows Structured Exception Handling][windows-eh]
/// ///
/// On x86_64 and AArch64 MinGW targets, the unwinding mechanism is SEH, /// 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] /// personality fn called by [Itanium C++ ABI Exception Handling][itanium-eh]
/// ///
/// The personality routine for most non-Windows targets. This will be called by /// The personality routine for most non-Windows targets. This will be called by

View File

@@ -13,10 +13,11 @@
mod dwarf; mod dwarf;
#[cfg(not(any(test, doctest)))] #[cfg(not(any(test, doctest)))]
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "emscripten")] { target_os = "emscripten" => {
mod emcc; 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), // 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 // but it's never actually called by the compiler because
// __CxxFrameHandler3 (msvc) / __gxx_wasm_personality_v0 (wasm) is the // __CxxFrameHandler3 (msvc) / __gxx_wasm_personality_v0 (wasm) is the
@@ -26,16 +27,18 @@ cfg_if::cfg_if! {
fn rust_eh_personality() { fn rust_eh_personality() {
core::intrinsics::abort() core::intrinsics::abort()
} }
} else if #[cfg(any( }
any(
all(target_family = "windows", target_env = "gnu"), all(target_family = "windows", target_env = "gnu"),
target_os = "psp", target_os = "psp",
target_os = "xous", target_os = "xous",
target_os = "solid_asp3", target_os = "solid_asp3",
all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "nuttx")), all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "nuttx")),
all(target_vendor = "fortanix", target_env = "sgx"), all(target_vendor = "fortanix", target_env = "sgx"),
))] { ) => {
mod gcc; mod gcc;
} else { }
_ => {
// Targets that don't support unwinding. // Targets that don't support unwinding.
// - os=none ("bare metal" targets) // - os=none ("bare metal" targets)
// - os=uefi // - os=uefi

View File

@@ -1,14 +1,17 @@
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_family = "unix")] { target_family = "unix" => {
mod unix; mod unix;
use unix as imp; use unix as imp;
} else if #[cfg(target_os = "windows")] { }
target_os = "windows" => {
mod windows; mod windows;
use windows as imp; use windows as imp;
} else if #[cfg(target_os = "uefi")] { }
target_os = "uefi" => {
mod uefi; mod uefi;
use uefi as imp; use uefi as imp;
} else { }
_ => {
mod unsupported; mod unsupported;
use unsupported as imp; use unsupported as imp;
} }

View File

@@ -20,12 +20,14 @@ use crate::{fmt, io};
mod cstring_array; mod cstring_array;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "fuchsia")] { target_os = "fuchsia" => {
// fuchsia doesn't have /dev/null // fuchsia doesn't have /dev/null
} else if #[cfg(target_os = "vxworks")] { }
target_os = "vxworks" => {
const DEV_NULL: &CStr = c"/null"; const DEV_NULL: &CStr = c"/null";
} else { }
_ => {
const DEV_NULL: &CStr = c"/dev/null"; const DEV_NULL: &CStr = c"/dev/null";
} }
} }
@@ -35,8 +37,8 @@ cfg_if::cfg_if! {
// to support older Android version (independent of libc version). // to support older Android version (independent of libc version).
// The following implementations are based on // The following implementations are based on
// https://github.com/aosp-mirror/platform_bionic/blob/ad8dcd6023294b646e5a8288c0ed431b0845da49/libc/include/android/legacy_signal_inlines.h // https://github.com/aosp-mirror/platform_bionic/blob/ad8dcd6023294b646e5a8288c0ed431b0845da49/libc/include/android/legacy_signal_inlines.h
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "android")] { target_os = "android" => {
#[allow(dead_code)] #[allow(dead_code)]
pub unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int { pub unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
set.write_bytes(0u8, 1); set.write_bytes(0u8, 1);
@@ -69,7 +71,8 @@ cfg_if::cfg_if! {
raw[bit / LONG_BIT] |= 1 << (bit % LONG_BIT); raw[bit / LONG_BIT] |= 1 << (bit % LONG_BIT);
return 0; return 0;
} }
} else { }
_ => {
#[allow(unused_imports)] #[allow(unused_imports)]
pub use libc::{sigemptyset, sigaddset}; pub use libc::{sigemptyset, sigaddset};
} }

View File

@@ -1,18 +1,21 @@
#[cfg_attr(any(target_os = "espidf", target_os = "horizon", target_os = "nuttx"), allow(unused))] #[cfg_attr(any(target_os = "espidf", target_os = "horizon", target_os = "nuttx"), allow(unused))]
mod common; mod common;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "fuchsia")] { target_os = "fuchsia" => {
mod fuchsia; mod fuchsia;
use fuchsia as imp; use fuchsia as imp;
} else if #[cfg(target_os = "vxworks")] { }
target_os = "vxworks" => {
mod vxworks; mod vxworks;
use vxworks as imp; 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; mod unsupported;
use unsupported as imp; use unsupported as imp;
pub use unsupported::output; pub use unsupported::output;
} else { }
_ => {
mod unix; mod unix;
use unix as imp; use unix as imp;
} }

View File

@@ -18,8 +18,8 @@ use crate::sys::cvt;
use crate::sys::pal::linux::pidfd::PidFd; use crate::sys::pal::linux::pidfd::PidFd;
use crate::{fmt, mem, sys}; use crate::{fmt, mem, sys};
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "nto")] { target_os = "nto" => {
use crate::thread; use crate::thread;
use libc::{c_char, posix_spawn_file_actions_t, posix_spawnattr_t}; use libc::{c_char, posix_spawn_file_actions_t, posix_spawnattr_t};
use crate::time::Duration; use crate::time::Duration;
@@ -43,6 +43,7 @@ cfg_if::cfg_if! {
// Maximum duration of sleeping before giving up and returning an error // Maximum duration of sleeping before giving up and returning an error
const MAX_FORKSPAWN_SLEEP: Duration = Duration::from_millis(1000); const MAX_FORKSPAWN_SLEEP: Duration = Duration::from_millis(1000);
} }
_ => {}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -465,8 +466,8 @@ impl Command {
return Ok(None); return Ok(None);
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_os = "linux")] { target_os = "linux" => {
use crate::sys::weak::weak; use crate::sys::weak::weak;
weak!( weak!(
@@ -526,7 +527,8 @@ impl Command {
} }
core::assert_matches::debug_assert_matches!(support, SPAWN | NO); core::assert_matches::debug_assert_matches!(support, SPAWN | NO);
} }
} else { }
_ => {
if self.get_create_pidfd() { if self.get_create_pidfd() {
unreachable!("only implemented on linux") unreachable!("only implemented on linux")
} }
@@ -746,10 +748,11 @@ impl Command {
} }
if self.get_setsid() { if self.get_setsid() {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(all(target_os = "linux", target_env = "gnu"))] { all(target_os = "linux", target_env = "gnu") => {
flags |= libc::POSIX_SPAWN_SETSID; flags |= libc::POSIX_SPAWN_SETSID;
} else { }
_ => {
return Ok(None); return Ok(None);
} }
} }

View File

@@ -1,16 +1,19 @@
cfg_if::cfg_if! { cfg_select! {
// Tier 1 // Tier 1
if #[cfg(any(target_os = "linux", target_os = "android"))] { any(target_os = "linux", target_os = "android") => {
mod linux; mod linux;
pub use linux::{fill_bytes, hashmap_random_keys}; pub use linux::{fill_bytes, hashmap_random_keys};
} else if #[cfg(target_os = "windows")] { }
target_os = "windows" => {
mod windows; mod windows;
pub use windows::fill_bytes; pub use windows::fill_bytes;
} else if #[cfg(target_vendor = "apple")] { }
target_vendor = "apple" => {
mod apple; mod apple;
pub use apple::fill_bytes; pub use apple::fill_bytes;
// Others, in alphabetical ordering. // Others, in alphabetical ordering.
} else if #[cfg(any( }
any(
target_os = "dragonfly", target_os = "dragonfly",
target_os = "freebsd", target_os = "freebsd",
target_os = "haiku", target_os = "haiku",
@@ -21,69 +24,86 @@ cfg_if::cfg_if! {
target_os = "solaris", target_os = "solaris",
target_os = "vita", target_os = "vita",
target_os = "nuttx", target_os = "nuttx",
))] { ) => {
mod arc4random; mod arc4random;
pub use arc4random::fill_bytes; pub use arc4random::fill_bytes;
} else if #[cfg(target_os = "emscripten")] { }
target_os = "emscripten" => {
mod getentropy; mod getentropy;
pub use getentropy::fill_bytes; pub use getentropy::fill_bytes;
} else if #[cfg(target_os = "espidf")] { }
target_os = "espidf" => {
mod espidf; mod espidf;
pub use espidf::fill_bytes; pub use espidf::fill_bytes;
} else if #[cfg(target_os = "fuchsia")] { }
target_os = "fuchsia" => {
mod fuchsia; mod fuchsia;
pub use fuchsia::fill_bytes; pub use fuchsia::fill_bytes;
} else if #[cfg(target_os = "hermit")] { }
target_os = "hermit" => {
mod hermit; mod hermit;
pub use hermit::fill_bytes; 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 // FIXME(horizon): add arc4random_buf to shim-3ds
mod getrandom; mod getrandom;
pub use getrandom::fill_bytes; pub use getrandom::fill_bytes;
} else if #[cfg(any( }
any(
target_os = "aix", target_os = "aix",
target_os = "hurd", target_os = "hurd",
target_os = "l4re", target_os = "l4re",
target_os = "nto", target_os = "nto",
))] { ) => {
mod unix_legacy; mod unix_legacy;
pub use unix_legacy::fill_bytes; pub use unix_legacy::fill_bytes;
} else if #[cfg(target_os = "redox")] { }
target_os = "redox" => {
mod redox; mod redox;
pub use redox::fill_bytes; pub use redox::fill_bytes;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { }
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx; mod sgx;
pub use sgx::fill_bytes; pub use sgx::fill_bytes;
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod solid; mod solid;
pub use solid::fill_bytes; pub use solid::fill_bytes;
} else if #[cfg(target_os = "teeos")] { }
target_os = "teeos" => {
mod teeos; mod teeos;
pub use teeos::fill_bytes; pub use teeos::fill_bytes;
} else if #[cfg(target_os = "trusty")] { }
target_os = "trusty" => {
mod trusty; mod trusty;
pub use trusty::fill_bytes; pub use trusty::fill_bytes;
} else if #[cfg(target_os = "uefi")] { }
target_os = "uefi" => {
mod uefi; mod uefi;
pub use uefi::fill_bytes; pub use uefi::fill_bytes;
} else if #[cfg(target_os = "vxworks")] { }
target_os = "vxworks" => {
mod vxworks; mod vxworks;
pub use vxworks::fill_bytes; pub use vxworks::fill_bytes;
} else if #[cfg(target_os = "wasi")] { }
target_os = "wasi" => {
mod wasi; mod wasi;
pub use wasi::fill_bytes; pub use wasi::fill_bytes;
} else if #[cfg(target_os = "zkvm")] { }
target_os = "zkvm" => {
mod zkvm; mod zkvm;
pub use zkvm::fill_bytes; pub use zkvm::fill_bytes;
} else if #[cfg(any( }
any(
all(target_family = "wasm", target_os = "unknown"), all(target_family = "wasm", target_os = "unknown"),
target_os = "xous", target_os = "xous",
))] { ) => {
// FIXME: finally remove std support for wasm32-unknown-unknown // FIXME: finally remove std support for wasm32-unknown-unknown
// FIXME: add random data generation to xous // FIXME: add random data generation to xous
mod unsupported; mod unsupported;
pub use unsupported::{fill_bytes, hashmap_random_keys}; pub use unsupported::{fill_bytes, hashmap_random_keys};
} }
_ => {}
} }
#[cfg(not(any( #[cfg(not(any(

View File

@@ -55,12 +55,13 @@ mod rng_protocol {
/// Port from [getrandom](https://github.com/rust-random/getrandom/blob/master/src/backends/rdrand.rs) /// Port from [getrandom](https://github.com/rust-random/getrandom/blob/master/src/backends/rdrand.rs)
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))] #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
mod rdrand { mod rdrand {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_arch = "x86_64")] { target_arch = "x86_64" => {
use crate::arch::x86_64 as arch; use crate::arch::x86_64 as arch;
use arch::_rdrand64_step as rdrand_step; use arch::_rdrand64_step as rdrand_step;
type Word = u64; type Word = u64;
} else if #[cfg(target_arch = "x86")] { }
target_arch = "x86" => {
use crate::arch::x86 as arch; use crate::arch::x86 as arch;
use arch::_rdrand32_step as rdrand_step; use arch::_rdrand32_step as rdrand_step;
type Word = u32; type Word = u32;

View File

@@ -1,40 +1,47 @@
#![forbid(unsafe_op_in_unsafe_fn)] #![forbid(unsafe_op_in_unsafe_fn)]
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(target_family = "unix", target_os = "hermit") => {
target_family = "unix",
target_os = "hermit"
))] {
mod unix; mod unix;
pub use unix::*; pub use unix::*;
} else if #[cfg(target_os = "windows")] { }
target_os = "windows" => {
mod windows; mod windows;
pub use windows::*; pub use windows::*;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { }
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx; mod sgx;
pub use sgx::*; pub use sgx::*;
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod solid; mod solid;
pub use solid::*; pub use solid::*;
} else if #[cfg(target_os = "teeos")] { }
target_os = "teeos" => {
mod teeos; mod teeos;
pub use teeos::*; pub use teeos::*;
} else if #[cfg(target_os = "trusty")] { }
target_os = "trusty" => {
mod trusty; mod trusty;
pub use trusty::*; pub use trusty::*;
} else if #[cfg(target_os = "uefi")] { }
target_os = "uefi" => {
mod uefi; mod uefi;
pub use uefi::*; pub use uefi::*;
} else if #[cfg(target_os = "wasi")] { }
target_os = "wasi" => {
mod wasi; mod wasi;
pub use wasi::*; pub use wasi::*;
} else if #[cfg(target_os = "xous")] { }
target_os = "xous" => {
mod xous; mod xous;
pub use xous::*; pub use xous::*;
} else if #[cfg(target_os = "zkvm")] { }
target_os = "zkvm" => {
mod zkvm; mod zkvm;
pub use zkvm::*; pub use zkvm::*;
} else { }
_ => {
mod unsupported; mod unsupported;
pub use unsupported::*; pub use unsupported::*;
} }

View File

@@ -1,5 +1,5 @@
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
all(target_os = "windows", not(target_vendor="win7")), all(target_os = "windows", not(target_vendor="win7")),
target_os = "linux", target_os = "linux",
target_os = "android", target_os = "android",
@@ -9,28 +9,34 @@ cfg_if::cfg_if! {
target_os = "fuchsia", target_os = "fuchsia",
all(target_family = "wasm", target_feature = "atomics"), all(target_family = "wasm", target_feature = "atomics"),
target_os = "hermit", target_os = "hermit",
))] { ) => {
mod futex; mod futex;
pub use futex::Condvar; pub use futex::Condvar;
} else if #[cfg(any( }
any(
target_family = "unix", target_family = "unix",
target_os = "teeos", target_os = "teeos",
))] { ) => {
mod pthread; mod pthread;
pub use pthread::Condvar; pub use pthread::Condvar;
} else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] { }
all(target_os = "windows", target_vendor = "win7") => {
mod windows7; mod windows7;
pub use windows7::Condvar; pub use windows7::Condvar;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { }
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx; mod sgx;
pub use sgx::Condvar; pub use sgx::Condvar;
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod itron; mod itron;
pub use itron::Condvar; pub use itron::Condvar;
} else if #[cfg(target_os = "xous")] { }
target_os = "xous" => {
mod xous; mod xous;
pub use xous::Condvar; pub use xous::Condvar;
} else { }
_ => {
mod no_threads; mod no_threads;
pub use no_threads::Condvar; pub use no_threads::Condvar;
} }

View File

@@ -1,5 +1,5 @@
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
all(target_os = "windows", not(target_vendor = "win7")), all(target_os = "windows", not(target_vendor = "win7")),
target_os = "linux", target_os = "linux",
target_os = "android", target_os = "android",
@@ -8,31 +8,38 @@ cfg_if::cfg_if! {
target_os = "dragonfly", target_os = "dragonfly",
all(target_family = "wasm", target_feature = "atomics"), all(target_family = "wasm", target_feature = "atomics"),
target_os = "hermit", target_os = "hermit",
))] { ) => {
mod futex; mod futex;
pub use futex::Mutex; pub use futex::Mutex;
} else if #[cfg(target_os = "fuchsia")] { }
target_os = "fuchsia" => {
mod fuchsia; mod fuchsia;
pub use fuchsia::Mutex; pub use fuchsia::Mutex;
} else if #[cfg(any( }
any(
target_family = "unix", target_family = "unix",
target_os = "teeos", target_os = "teeos",
))] { ) => {
mod pthread; mod pthread;
pub use pthread::Mutex; pub use pthread::Mutex;
} else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] { }
all(target_os = "windows", target_vendor = "win7") => {
mod windows7; mod windows7;
pub use windows7::{Mutex, raw}; pub use windows7::{Mutex, raw};
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { }
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx; mod sgx;
pub use sgx::Mutex; pub use sgx::Mutex;
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod itron; mod itron;
pub use itron::Mutex; pub use itron::Mutex;
} else if #[cfg(target_os = "xous")] { }
target_os = "xous" => {
mod xous; mod xous;
pub use xous::Mutex; pub use xous::Mutex;
} else { }
_ => {
mod no_threads; mod no_threads;
pub use no_threads::Mutex; pub use no_threads::Mutex;
} }

View File

@@ -7,8 +7,8 @@
// This also gives us the opportunity to optimize the implementation a bit which // This also gives us the opportunity to optimize the implementation a bit which
// should help the fast path on call sites. // should help the fast path on call sites.
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
all(target_os = "windows", not(target_vendor="win7")), all(target_os = "windows", not(target_vendor="win7")),
target_os = "linux", target_os = "linux",
target_os = "android", target_os = "android",
@@ -18,19 +18,21 @@ cfg_if::cfg_if! {
target_os = "dragonfly", target_os = "dragonfly",
target_os = "fuchsia", target_os = "fuchsia",
target_os = "hermit", target_os = "hermit",
))] { ) => {
mod futex; mod futex;
pub use futex::{Once, OnceState}; pub use futex::{Once, OnceState};
} else if #[cfg(any( }
any(
windows, windows,
target_family = "unix", target_family = "unix",
all(target_vendor = "fortanix", target_env = "sgx"), all(target_vendor = "fortanix", target_env = "sgx"),
target_os = "solid_asp3", target_os = "solid_asp3",
target_os = "xous", target_os = "xous",
))] { ) => {
mod queue; mod queue;
pub use queue::{Once, OnceState}; pub use queue::{Once, OnceState};
} else { }
_ => {
mod no_threads; mod no_threads;
pub use no_threads::{Once, OnceState}; pub use no_threads::{Once, OnceState};
} }

View File

@@ -1,5 +1,5 @@
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
all(target_os = "windows", not(target_vendor = "win7")), all(target_os = "windows", not(target_vendor = "win7")),
target_os = "linux", target_os = "linux",
target_os = "android", target_os = "android",
@@ -9,24 +9,28 @@ cfg_if::cfg_if! {
target_os = "fuchsia", target_os = "fuchsia",
all(target_family = "wasm", target_feature = "atomics"), all(target_family = "wasm", target_feature = "atomics"),
target_os = "hermit", target_os = "hermit",
))] { ) => {
mod futex; mod futex;
pub use futex::RwLock; pub use futex::RwLock;
} else if #[cfg(any( }
any(
target_family = "unix", target_family = "unix",
all(target_os = "windows", target_vendor = "win7"), all(target_os = "windows", target_vendor = "win7"),
all(target_vendor = "fortanix", target_env = "sgx"), all(target_vendor = "fortanix", target_env = "sgx"),
target_os = "xous", target_os = "xous",
))] { ) => {
mod queue; mod queue;
pub use queue::RwLock; pub use queue::RwLock;
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod solid; mod solid;
pub use solid::RwLock; pub use solid::RwLock;
} else if #[cfg(target_os = "teeos")] { }
target_os = "teeos" => {
mod teeos; mod teeos;
pub use teeos::RwLock; pub use teeos::RwLock;
} else { }
_ => {
mod no_threads; mod no_threads;
pub use no_threads::RwLock; pub use no_threads::RwLock;
} }

View File

@@ -1,5 +1,5 @@
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
all(target_os = "windows", not(target_vendor = "win7")), all(target_os = "windows", not(target_vendor = "win7")),
target_os = "linux", target_os = "linux",
target_os = "android", target_os = "android",
@@ -9,30 +9,36 @@ cfg_if::cfg_if! {
target_os = "dragonfly", target_os = "dragonfly",
target_os = "fuchsia", target_os = "fuchsia",
target_os = "hermit", target_os = "hermit",
))] { ) => {
mod futex; mod futex;
pub use futex::Parker; pub use futex::Parker;
} else if #[cfg(any( }
any(
target_os = "netbsd", target_os = "netbsd",
all(target_vendor = "fortanix", target_env = "sgx"), all(target_vendor = "fortanix", target_env = "sgx"),
target_os = "solid_asp3", target_os = "solid_asp3",
))] { ) => {
mod id; mod id;
pub use id::Parker; pub use id::Parker;
} else if #[cfg(target_vendor = "win7")] { }
target_vendor = "win7" => {
mod windows7; mod windows7;
pub use windows7::Parker; 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>. // Doesn't work in Miri, see <https://github.com/rust-lang/miri/issues/2589>.
mod darwin; mod darwin;
pub use darwin::Parker; pub use darwin::Parker;
} else if #[cfg(target_os = "xous")] { }
target_os = "xous" => {
mod xous; mod xous;
pub use xous::Parker; pub use xous::Parker;
} else if #[cfg(target_family = "unix")] { }
target_family = "unix" => {
mod pthread; mod pthread;
pub use pthread::Parker; pub use pthread::Parker;
} else { }
_ => {
mod unsupported; mod unsupported;
pub use unsupported::Parker; pub use unsupported::Parker;
} }

View File

@@ -23,21 +23,23 @@
issue = "none" issue = "none"
)] )]
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
all(target_family = "wasm", not(target_feature = "atomics")), all(target_family = "wasm", not(target_feature = "atomics")),
target_os = "uefi", target_os = "uefi",
target_os = "zkvm", target_os = "zkvm",
target_os = "trusty", target_os = "trusty",
))] { ) => {
mod no_threads; mod no_threads;
pub use no_threads::{EagerStorage, LazyStorage, thread_local_inner}; pub use no_threads::{EagerStorage, LazyStorage, thread_local_inner};
pub(crate) use no_threads::{LocalPointer, local_pointer}; pub(crate) use no_threads::{LocalPointer, local_pointer};
} else if #[cfg(target_thread_local)] { }
target_thread_local => {
mod native; mod native;
pub use native::{EagerStorage, LazyStorage, thread_local_inner}; pub use native::{EagerStorage, LazyStorage, thread_local_inner};
pub(crate) use native::{LocalPointer, local_pointer}; pub(crate) use native::{LocalPointer, local_pointer};
} else { }
_ => {
mod os; mod os;
pub use os::{Storage, thread_local_inner}; pub use os::{Storage, thread_local_inner};
pub(crate) use os::{LocalPointer, local_pointer}; 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. /// 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")))))] #[cfg(all(target_thread_local, not(all(target_family = "wasm", not(target_feature = "atomics")))))]
pub(crate) mod destructors { pub(crate) mod destructors {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
target_os = "linux", target_os = "linux",
target_os = "android", target_os = "android",
target_os = "fuchsia", target_os = "fuchsia",
@@ -62,12 +64,13 @@ pub(crate) mod destructors {
target_os = "hurd", target_os = "hurd",
target_os = "netbsd", target_os = "netbsd",
target_os = "dragonfly" target_os = "dragonfly"
))] { ) => {
mod linux_like; mod linux_like;
mod list; mod list;
pub(super) use linux_like::register; pub(super) use linux_like::register;
pub(super) use list::run; pub(super) use list::run;
} else { }
_ => {
mod list; mod list;
pub(super) use list::register; pub(super) use list::register;
pub(crate) use list::run; pub(crate) use list::run;
@@ -79,21 +82,23 @@ pub(crate) mod destructors {
/// and the [runtime cleanup](crate::rt::thread_cleanup) function. Calling `enable` /// and the [runtime cleanup](crate::rt::thread_cleanup) function. Calling `enable`
/// should ensure that these functions are called at the right times. /// should ensure that these functions are called at the right times.
pub(crate) mod guard { pub(crate) mod guard {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(all(target_thread_local, target_vendor = "apple"))] { all(target_thread_local, target_vendor = "apple") => {
mod apple; mod apple;
pub(crate) use apple::enable; pub(crate) use apple::enable;
} else if #[cfg(target_os = "windows")] { }
target_os = "windows" => {
mod windows; mod windows;
pub(crate) use windows::enable; pub(crate) use windows::enable;
} else if #[cfg(any( }
any(
all(target_family = "wasm", not( all(target_family = "wasm", not(
all(target_os = "wasi", target_env = "p1", target_feature = "atomics") all(target_os = "wasi", target_env = "p1", target_feature = "atomics")
)), )),
target_os = "uefi", target_os = "uefi",
target_os = "zkvm", target_os = "zkvm",
target_os = "trusty", target_os = "trusty",
))] { ) => {
pub(crate) fn enable() { pub(crate) fn enable() {
// FIXME: Right now there is no concept of "thread exit" on // FIXME: Right now there is no concept of "thread exit" on
// wasm, but this is likely going to show up at some point in // wasm, but this is likely going to show up at some point in
@@ -107,17 +112,20 @@ pub(crate) mod guard {
#[allow(unused)] #[allow(unused)]
use crate::rt::thread_cleanup; use crate::rt::thread_cleanup;
} }
} else if #[cfg(any( }
any(
target_os = "hermit", target_os = "hermit",
target_os = "xous", target_os = "xous",
))] { ) => {
// `std` is the only runtime, so it just calls the destructor functions // `std` is the only runtime, so it just calls the destructor functions
// itself when the time comes. // itself when the time comes.
pub(crate) fn enable() {} pub(crate) fn enable() {}
} else if #[cfg(target_os = "solid_asp3")] { }
target_os = "solid_asp3" => {
mod solid; mod solid;
pub(crate) use solid::enable; pub(crate) use solid::enable;
} else { }
_ => {
mod key; mod key;
pub(crate) use key::enable; 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 /// 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. /// with a pointer which we can get and set to store our data.
pub(crate) mod key { pub(crate) mod key {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
all( all(
not(target_vendor = "apple"), not(target_vendor = "apple"),
not(target_family = "wasm"), not(target_family = "wasm"),
@@ -141,7 +149,7 @@ pub(crate) mod key {
all(not(target_thread_local), target_vendor = "apple"), all(not(target_thread_local), target_vendor = "apple"),
target_os = "teeos", target_os = "teeos",
all(target_os = "wasi", target_env = "p1", target_feature = "atomics"), all(target_os = "wasi", target_env = "p1", target_feature = "atomics"),
))] { ) => {
mod racy; mod racy;
mod unix; mod unix;
#[cfg(test)] #[cfg(test)]
@@ -151,12 +159,14 @@ pub(crate) mod key {
#[cfg(any(not(target_thread_local), test))] #[cfg(any(not(target_thread_local), test))]
pub(super) use unix::get; pub(super) use unix::get;
use unix::{create, destroy}; 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)] #[cfg(test)]
mod tests; mod tests;
mod windows; mod windows;
pub(super) use windows::{Key, LazyKey, get, run_dtors, set}; 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 racy;
mod sgx; mod sgx;
#[cfg(test)] #[cfg(test)]
@@ -164,7 +174,8 @@ pub(crate) mod key {
pub(super) use racy::LazyKey; pub(super) use racy::LazyKey;
pub(super) use sgx::{Key, get, set}; pub(super) use sgx::{Key, get, set};
use sgx::{create, destroy}; use sgx::{create, destroy};
} else if #[cfg(target_os = "xous")] { }
target_os = "xous" => {
mod racy; mod racy;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
@@ -174,6 +185,7 @@ pub(crate) mod key {
pub(super) use xous::{Key, get, set}; pub(super) use xous::{Key, get, set};
use xous::{create, destroy}; use xous::{create, destroy};
} }
_ => {}
} }
} }

View File

@@ -18,8 +18,8 @@ local_pointer! {
pub(super) mod id { pub(super) mod id {
use super::*; use super::*;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_thread_local)] { target_thread_local => {
use crate::cell::Cell; use crate::cell::Cell;
#[thread_local] #[thread_local]
@@ -34,7 +34,8 @@ pub(super) mod id {
pub(super) fn set(id: ThreadId) { pub(super) fn set(id: ThreadId) {
ID.set(Some(id)) ID.set(Some(id))
} }
} else if #[cfg(target_pointer_width = "16")] { }
target_pointer_width = "16" => {
local_pointer! { local_pointer! {
static ID0; static ID0;
static ID16; static ID16;
@@ -59,7 +60,8 @@ pub(super) mod id {
ID32.set(ptr::without_provenance_mut((val >> 32) as usize)); ID32.set(ptr::without_provenance_mut((val >> 32) as usize));
ID48.set(ptr::without_provenance_mut((val >> 48) 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! { local_pointer! {
static ID0; static ID0;
static ID32; static ID32;
@@ -78,7 +80,8 @@ pub(super) mod id {
ID0.set(ptr::without_provenance_mut(val as usize)); ID0.set(ptr::without_provenance_mut(val as usize));
ID32.set(ptr::without_provenance_mut((val >> 32) as usize)); ID32.set(ptr::without_provenance_mut((val >> 32) as usize));
} }
} else { }
_ => {
local_pointer! { local_pointer! {
static ID; static ID;
} }

View File

@@ -1212,8 +1212,8 @@ impl ThreadId {
panic!("failed to generate unique thread ID: bitspace exhausted") panic!("failed to generate unique thread ID: bitspace exhausted")
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_has_atomic = "64")] { target_has_atomic = "64" => {
use crate::sync::atomic::{Atomic, AtomicU64}; use crate::sync::atomic::{Atomic, AtomicU64};
static COUNTER: Atomic<u64> = AtomicU64::new(0); static COUNTER: Atomic<u64> = AtomicU64::new(0);
@@ -1229,7 +1229,8 @@ impl ThreadId {
Err(id) => last = id, Err(id) => last = id,
} }
} }
} else { }
_ => {
use crate::sync::{Mutex, PoisonError}; use crate::sync::{Mutex, PoisonError};
static COUNTER: Mutex<u64> = Mutex::new(0); 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 /// 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. /// will be incorrect, but that's just something we have to live with.
pub(crate) mod main_thread { pub(crate) mod main_thread {
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_has_atomic = "64")] { target_has_atomic = "64" => {
use super::ThreadId; use super::ThreadId;
use crate::sync::atomic::{Atomic, AtomicU64}; use crate::sync::atomic::{Atomic, AtomicU64};
use crate::sync::atomic::Ordering::Relaxed; use crate::sync::atomic::Ordering::Relaxed;
@@ -1335,7 +1336,8 @@ pub(crate) mod main_thread {
pub(crate) unsafe fn set(id: ThreadId) { pub(crate) unsafe fn set(id: ThreadId) {
MAIN.store(id.as_u64().get(), Relaxed) MAIN.store(id.as_u64().get(), Relaxed)
} }
} else { }
_ => {
use super::ThreadId; use super::ThreadId;
use crate::mem::MaybeUninit; use crate::mem::MaybeUninit;
use crate::sync::atomic::{Atomic, AtomicBool}; use crate::sync::atomic::{Atomic, AtomicBool};

View File

@@ -1,5 +1,6 @@
// These tests are in a separate integration test as they modify the environment, // These tests are in a separate integration test as they modify the environment,
// and would otherwise cause some other tests to fail. // and would otherwise cause some other tests to fail.
#![feature(cfg_select)]
use std::env::*; use std::env::*;
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
@@ -110,8 +111,8 @@ fn env_home_dir() {
} }
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(unix)] { unix => {
let oldhome = var_to_os_string(var("HOME")); let oldhome = var_to_os_string(var("HOME"));
unsafe { unsafe {
@@ -130,7 +131,8 @@ fn env_home_dir() {
} }
if let Some(oldhome) = oldhome { unsafe { set_var("HOME", oldhome); } } if let Some(oldhome) = oldhome { unsafe { set_var("HOME", oldhome); } }
} else if #[cfg(windows)] { }
windows => {
let oldhome = var_to_os_string(var("HOME")); let oldhome = var_to_os_string(var("HOME"));
let olduserprofile = var_to_os_string(var("USERPROFILE")); 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); } if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); }
} }
} }
_ => {}
} }
} }

View File

@@ -21,7 +21,6 @@ is-it-maintained-open-issues = { repository = "rust-lang/stdarch" }
maintenance = { status = "experimental" } maintenance = { status = "experimental" }
[dependencies] [dependencies]
cfg-if = "1.0.0"
core = { path = "../core" } core = { path = "../core" }
alloc = { path = "../alloc" } alloc = { path = "../alloc" }

View File

@@ -1,7 +1,5 @@
#![allow(dead_code)] #![allow(dead_code)]
use cfg_if::cfg_if;
// Export the macros for all supported architectures. // Export the macros for all supported architectures.
#[macro_use] #[macro_use]
mod x86; mod x86;
@@ -24,38 +22,48 @@ mod loongarch;
#[macro_use] #[macro_use]
mod s390x; mod s390x;
cfg_if! { cfg_select! {
if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { any(target_arch = "x86", target_arch = "x86_64") => {
#[stable(feature = "simd_x86", since = "1.27.0")] #[stable(feature = "simd_x86", since = "1.27.0")]
pub use x86::*; pub use x86::*;
} else if #[cfg(target_arch = "arm")] { }
target_arch = "arm" => {
#[unstable(feature = "stdarch_arm_feature_detection", issue = "111190")] #[unstable(feature = "stdarch_arm_feature_detection", issue = "111190")]
pub use arm::*; 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")] #[stable(feature = "simd_aarch64", since = "1.60.0")]
pub use aarch64::*; 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")] #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")]
pub use riscv::*; pub use riscv::*;
} else if #[cfg(target_arch = "powerpc")] { }
target_arch = "powerpc" => {
#[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")]
pub use powerpc::*; pub use powerpc::*;
} else if #[cfg(target_arch = "powerpc64")] { }
target_arch = "powerpc64" => {
#[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")]
pub use powerpc64::*; pub use powerpc64::*;
} else if #[cfg(target_arch = "mips")] { }
target_arch = "mips" => {
#[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")]
pub use mips::*; pub use mips::*;
} else if #[cfg(target_arch = "mips64")] { }
target_arch = "mips64" => {
#[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")]
pub use mips64::*; 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")] #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")]
pub use loongarch::*; pub use loongarch::*;
} else if #[cfg(target_arch = "s390x")] { }
target_arch = "s390x" => {
#[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")]
pub use s390x::*; pub use s390x::*;
} else { }
_ => {
// Unimplemented architecture: // Unimplemented architecture:
#[doc(hidden)] #[doc(hidden)]
pub(crate) enum Feature { pub(crate) enum Feature {

View File

@@ -101,8 +101,8 @@ impl Cache {
} }
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(feature = "std_detect_env_override")] { feature = "std_detect_env_override" => {
#[inline] #[inline]
fn disable_features(disable: &[u8], value: &mut Initializer) { fn disable_features(disable: &[u8], value: &mut Initializer) {
if let Ok(disable) = core::str::from_utf8(disable) { if let Ok(disable) = core::str::from_utf8(disable) {
@@ -116,8 +116,8 @@ cfg_if::cfg_if! {
fn initialize(mut value: Initializer) -> Initializer { fn initialize(mut value: Initializer) -> Initializer {
use core::ffi::CStr; use core::ffi::CStr;
const RUST_STD_DETECT_UNSTABLE: &CStr = c"RUST_STD_DETECT_UNSTABLE"; const RUST_STD_DETECT_UNSTABLE: &CStr = c"RUST_STD_DETECT_UNSTABLE";
cfg_if::cfg_if! { cfg_select! {
if #[cfg(windows)] { windows => {
use alloc::vec; use alloc::vec;
#[link(name = "kernel32")] #[link(name = "kernel32")]
unsafe extern "system" { unsafe extern "system" {
@@ -132,7 +132,8 @@ cfg_if::cfg_if! {
disable_features(&env[..len as usize], &mut value); disable_features(&env[..len as usize], &mut value);
} }
} }
} else { }
_ => {
let env = unsafe { let env = unsafe {
libc::getenv(RUST_STD_DETECT_UNSTABLE.as_ptr()) libc::getenv(RUST_STD_DETECT_UNSTABLE.as_ptr())
}; };
@@ -146,7 +147,8 @@ cfg_if::cfg_if! {
do_initialize(value); do_initialize(value);
value value
} }
} else { }
_ => {
#[inline] #[inline]
fn initialize(value: Initializer) -> Initializer { fn initialize(value: Initializer) -> Initializer {
do_initialize(value); do_initialize(value);

View File

@@ -17,8 +17,6 @@
//! due to security concerns (x86 is the big exception). These functions are //! due to security concerns (x86 is the big exception). These functions are
//! implemented in the `os/{target_os}.rs` modules. //! implemented in the `os/{target_os}.rs` modules.
use cfg_if::cfg_if;
#[macro_use] #[macro_use]
mod macros; mod macros;
@@ -34,8 +32,8 @@ pub(crate) use self::arch::Feature;
mod bit; mod bit;
mod cache; mod cache;
cfg_if! { cfg_select! {
if #[cfg(miri)] { miri => {
// When running under miri all target-features that are not enabled at // When running under miri all target-features that are not enabled at
// compile-time are reported as disabled at run-time. // compile-time are reported as disabled at run-time.
// //
@@ -43,35 +41,42 @@ cfg_if! {
// this run-time detection logic is never called. // this run-time detection logic is never called.
#[path = "os/other.rs"] #[path = "os/other.rs"]
mod os; 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. // On x86/x86_64 no OS specific functionality is required.
#[path = "os/x86.rs"] #[path = "os/x86.rs"]
mod os; 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"))] #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
#[path = "os/riscv.rs"] #[path = "os/riscv.rs"]
mod riscv; mod riscv;
#[path = "os/linux/mod.rs"] #[path = "os/linux/mod.rs"]
mod os; mod os;
} else if #[cfg(all(target_os = "freebsd", feature = "libc"))] { }
all(target_os = "freebsd", feature = "libc") => {
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
#[path = "os/aarch64.rs"] #[path = "os/aarch64.rs"]
mod aarch64; mod aarch64;
#[path = "os/freebsd/mod.rs"] #[path = "os/freebsd/mod.rs"]
mod os; 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. #[allow(dead_code)] // we don't use code that calls the mrs instruction.
#[path = "os/aarch64.rs"] #[path = "os/aarch64.rs"]
mod aarch64; mod aarch64;
#[path = "os/openbsd/aarch64.rs"] #[path = "os/openbsd/aarch64.rs"]
mod os; 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"] #[path = "os/windows/aarch64.rs"]
mod os; 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"] #[path = "os/darwin/aarch64.rs"]
mod os; mod os;
} else { }
_ => {
#[path = "os/other.rs"] #[path = "os/other.rs"]
mod os; 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. /// is `true` if the feature is supported by the host and `false` otherwise.
#[unstable(feature = "stdarch_internal", issue = "none")] #[unstable(feature = "stdarch_internal", issue = "none")]
pub fn features() -> impl Iterator<Item = (&'static str, bool)> { pub fn features() -> impl Iterator<Item = (&'static str, bool)> {
cfg_if! { cfg_select! {
if #[cfg(any( any(
target_arch = "x86", target_arch = "x86",
target_arch = "x86_64", target_arch = "x86_64",
target_arch = "arm", target_arch = "arm",
@@ -105,7 +110,7 @@ pub fn features() -> impl Iterator<Item = (&'static str, bool)> {
target_arch = "loongarch32", target_arch = "loongarch32",
target_arch = "loongarch64", target_arch = "loongarch64",
target_arch = "s390x", target_arch = "s390x",
))] { ) => {
(0_u8..Feature::_last as u8).map(|discriminant: u8| { (0_u8..Feature::_last as u8).map(|discriminant: u8| {
#[allow(bindings_with_variant_name)] // RISC-V has Feature::f #[allow(bindings_with_variant_name)] // RISC-V has Feature::f
let f: Feature = unsafe { core::mem::transmute(discriminant) }; 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); let enabled: bool = check_for(f);
(name, enabled) (name, enabled)
}) })
} else {
None.into_iter()
} }
_ => None.into_iter(),
} }
} }

View File

@@ -2,17 +2,20 @@
mod auxvec; mod auxvec;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_arch = "aarch64")] { target_arch = "aarch64" => {
mod aarch64; mod aarch64;
pub(crate) use self::aarch64::detect_features; pub(crate) use self::aarch64::detect_features;
} else if #[cfg(target_arch = "arm")] { }
target_arch = "arm" => {
mod arm; mod arm;
pub(crate) use self::arm::detect_features; pub(crate) use self::arm::detect_features;
} else if #[cfg(target_arch = "powerpc64")] { }
target_arch = "powerpc64" => {
mod powerpc; mod powerpc;
pub(crate) use self::powerpc::detect_features; pub(crate) use self::powerpc::detect_features;
} else { }
_ => {
use crate::detect::cache; use crate::detect::cache;
/// Performs run-time feature detection. /// Performs run-time feature detection.
pub(crate) fn detect_features() -> cache::Initializer { pub(crate) fn detect_features() -> cache::Initializer {

View File

@@ -131,15 +131,15 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> {
/// `getauxval` function. If the function is not linked, this function return `Err`. /// `getauxval` function. If the function is not linked, this function return `Err`.
fn getauxval(key: usize) -> Result<usize, ()> { fn getauxval(key: usize) -> Result<usize, ()> {
type F = unsafe extern "C" fn(libc::c_ulong) -> libc::c_ulong; type F = unsafe extern "C" fn(libc::c_ulong) -> libc::c_ulong;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(all( all(
feature = "std_detect_dlsym_getauxval", feature = "std_detect_dlsym_getauxval",
not(all( not(all(
target_os = "linux", target_os = "linux",
any(target_env = "gnu", target_env = "musl", target_env = "ohos"), any(target_env = "gnu", target_env = "musl", target_env = "ohos"),
)), )),
not(target_os = "android"), not(target_os = "android"),
))] { ) => {
let ffi_getauxval: F = unsafe { let ffi_getauxval: F = unsafe {
let ptr = libc::dlsym(libc::RTLD_DEFAULT, c"getauxval".as_ptr()); let ptr = libc::dlsym(libc::RTLD_DEFAULT, c"getauxval".as_ptr());
if ptr.is_null() { if ptr.is_null() {
@@ -147,7 +147,8 @@ fn getauxval(key: usize) -> Result<usize, ()> {
} }
core::mem::transmute(ptr) core::mem::transmute(ptr)
}; };
} else { }
_ => {
let ffi_getauxval: F = libc::getauxval; let ffi_getauxval: F = libc::getauxval;
} }
} }

View File

@@ -42,8 +42,8 @@ fn auxv_dump() {
} }
#[cfg(feature = "std_detect_file_io")] #[cfg(feature = "std_detect_file_io")]
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_arch = "arm")] { target_arch = "arm" => {
// The tests below can be executed under qemu, where we do not have access to the test // 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!`. // files on disk, so we need to embed them with `include_bytes!`.
#[test] #[test]
@@ -62,7 +62,8 @@ cfg_if::cfg_if! {
assert_eq!(v.hwcap, 126614527); assert_eq!(v.hwcap, 126614527);
assert_eq!(v.hwcap2, 0); assert_eq!(v.hwcap2, 0);
} }
} else if #[cfg(target_arch = "aarch64")] { }
target_arch = "aarch64" => {
#[cfg(target_endian = "little")] #[cfg(target_endian = "little")]
#[test] #[test]
fn linux_artificial_aarch64() { fn linux_artificial_aarch64() {
@@ -81,6 +82,7 @@ cfg_if::cfg_if! {
assert_eq!(v.hwcap2, 0); assert_eq!(v.hwcap2, 0);
} }
} }
_ => {}
} }
#[test] #[test]

View File

@@ -37,29 +37,36 @@ fn read_file(orig_path: &str) -> Result<Vec<u8>, alloc::string::String> {
} }
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_arch = "aarch64")] { target_arch = "aarch64" => {
mod aarch64; mod aarch64;
pub(crate) use self::aarch64::detect_features; pub(crate) use self::aarch64::detect_features;
} else if #[cfg(target_arch = "arm")] { }
target_arch = "arm" => {
mod arm; mod arm;
pub(crate) use self::arm::detect_features; 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; mod riscv;
pub(crate) use self::riscv::detect_features; 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; mod mips;
pub(crate) use self::mips::detect_features; 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; mod powerpc;
pub(crate) use self::powerpc::detect_features; 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; mod loongarch;
pub(crate) use self::loongarch::detect_features; pub(crate) use self::loongarch::detect_features;
} else if #[cfg(target_arch = "s390x")] { }
target_arch = "s390x" => {
mod s390x; mod s390x;
pub(crate) use self::s390x::detect_features; pub(crate) use self::s390x::detect_features;
} else { }
_ => {
use crate::detect::cache; use crate::detect::cache;
/// Performs run-time feature detection. /// Performs run-time feature detection.
pub(crate) fn detect_features() -> cache::Initializer { pub(crate) fn detect_features() -> cache::Initializer {

View File

@@ -15,7 +15,7 @@
//! * `s390x`: [`is_s390x_feature_detected`] //! * `s390x`: [`is_s390x_feature_detected`]
#![unstable(feature = "stdarch_internal", issue = "none")] #![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)] #![deny(rust_2018_idioms)]
#![allow(clippy::shadow_reuse)] #![allow(clippy::shadow_reuse)]
#![cfg_attr(test, allow(unused_imports))] #![cfg_attr(test, allow(unused_imports))]

View File

@@ -14,7 +14,6 @@ bench = false
doc = false doc = false
[dependencies] [dependencies]
cfg-if = "1.0"
core = { path = "../rustc-std-workspace-core", package = "rustc-std-workspace-core" } core = { path = "../rustc-std-workspace-core", package = "rustc-std-workspace-core" }
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]

View File

@@ -1,6 +1,7 @@
#![no_std] #![no_std]
#![unstable(feature = "panic_unwind", issue = "32837")] #![unstable(feature = "panic_unwind", issue = "32837")]
#![feature(cfg_emscripten_wasm_eh)] #![feature(cfg_emscripten_wasm_eh)]
#![feature(cfg_select)]
#![feature(link_cfg)] #![feature(link_cfg)]
#![feature(staged_api)] #![feature(staged_api)]
#![cfg_attr(not(target_env = "msvc"), feature(libc))] #![cfg_attr(not(target_env = "msvc"), feature(libc))]
@@ -15,32 +16,37 @@
#[cfg(not(all(windows, target_env = "msvc")))] #[cfg(not(all(windows, target_env = "msvc")))]
extern crate libc as _; extern crate libc as _;
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_env = "msvc")] { target_env = "msvc" => {
// Windows MSVC no extra unwinder support needed // Windows MSVC no extra unwinder support needed
} else if #[cfg(any( }
any(
target_os = "l4re", target_os = "l4re",
target_os = "none", target_os = "none",
target_os = "espidf", target_os = "espidf",
target_os = "nuttx", target_os = "nuttx",
))] { ) => {
// These "unix" family members do not have unwinder. // These "unix" family members do not have unwinder.
} else if #[cfg(any( }
any(
unix, unix,
windows, windows,
target_os = "psp", target_os = "psp",
target_os = "solid_asp3", target_os = "solid_asp3",
all(target_vendor = "fortanix", target_env = "sgx"), all(target_vendor = "fortanix", target_env = "sgx"),
))] { ) => {
mod libunwind; mod libunwind;
pub use libunwind::*; pub use libunwind::*;
} else if #[cfg(target_os = "xous")] { }
target_os = "xous" => {
mod unwinding; mod unwinding;
pub use unwinding::*; pub use unwinding::*;
} else if #[cfg(target_family = "wasm")] { }
target_family = "wasm" => {
mod wasm; mod wasm;
pub use wasm::*; pub use wasm::*;
} else { }
_ => {
// no unwinder on the system! // no unwinder on the system!
// - os=none ("bare metal" targets) // - os=none ("bare metal" targets)
// - os=hermit // - os=hermit
@@ -52,17 +58,20 @@ cfg_if::cfg_if! {
} }
#[cfg(target_env = "musl")] #[cfg(target_env = "musl")]
cfg_if::cfg_if! { cfg_select! {
if #[cfg(all(feature = "llvm-libunwind", feature = "system-llvm-libunwind"))] { all(feature = "llvm-libunwind", feature = "system-llvm-libunwind") => {
compile_error!("`llvm-libunwind` and `system-llvm-libunwind` cannot be enabled at the same time"); 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")] #[link(name = "unwind", kind = "static", modifiers = "-bundle")]
unsafe extern "C" {} 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", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
#[link(name = "unwind", cfg(not(target_feature = "crt-static")))] #[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
unsafe extern "C" {} unsafe extern "C" {}
} else { }
_ => {
#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
unsafe extern "C" {} 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 // This is the same as musl except that we default to using the system libunwind
// instead of libgcc. // instead of libgcc.
#[cfg(target_env = "ohos")] #[cfg(target_env = "ohos")]
cfg_if::cfg_if! { cfg_select! {
if #[cfg(all(feature = "llvm-libunwind", feature = "system-llvm-libunwind"))] { all(feature = "llvm-libunwind", feature = "system-llvm-libunwind") => {
compile_error!("`llvm-libunwind` and `system-llvm-libunwind` cannot be enabled at the same time"); 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")] #[link(name = "unwind", kind = "static", modifiers = "-bundle")]
unsafe extern "C" {} unsafe extern "C" {}
} else { }
_ => {
#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
#[link(name = "unwind", cfg(not(target_feature = "crt-static")))] #[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
unsafe extern "C" {} unsafe extern "C" {}
@@ -86,10 +97,11 @@ cfg_if::cfg_if! {
} }
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
cfg_if::cfg_if! { cfg_select! {
if #[cfg(feature = "llvm-libunwind")] { feature = "llvm-libunwind" => {
compile_error!("`llvm-libunwind` is not supported for Android targets"); 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", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
#[link(name = "unwind", cfg(not(target_feature = "crt-static")))] #[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
unsafe extern "C" {} unsafe extern "C" {}
@@ -166,11 +178,12 @@ unsafe extern "C" {}
unsafe extern "C" {} unsafe extern "C" {}
#[cfg(target_os = "nto")] #[cfg(target_os = "nto")]
cfg_if::cfg_if! { cfg_select! {
if #[cfg(target_env = "nto70")] { target_env = "nto70" => {
#[link(name = "gcc")] #[link(name = "gcc")]
unsafe extern "C" {} unsafe extern "C" {}
} else { }
_ => {
#[link(name = "gcc_s")] #[link(name = "gcc_s")]
unsafe extern "C" {} unsafe extern "C" {}
} }

View File

@@ -122,8 +122,8 @@ unsafe extern "C" {
pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr; pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
} }
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "arm")))] { any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "arm")) => {
// Not ARM EHABI // Not ARM EHABI
// //
// 32-bit ARM on iOS/tvOS/watchOS use either DWARF/Compact unwinding or // 32-bit ARM on iOS/tvOS/watchOS use either DWARF/Compact unwinding or
@@ -150,7 +150,8 @@ if #[cfg(any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "a
pub fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void; pub fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void;
} }
} else { }
_ => {
// ARM EHABI // ARM EHABI
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq)]
@@ -257,10 +258,10 @@ if #[cfg(any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "a
pc pc
} }
} }
} // cfg_if! } // cfg_select!
cfg_if::cfg_if! { cfg_select! {
if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm"))] { all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm") => {
// 32-bit ARM Apple (except for watchOS armv7k specifically) uses SjLj and // 32-bit ARM Apple (except for watchOS armv7k specifically) uses SjLj and
// does not provide _Unwind_Backtrace() // does not provide _Unwind_Backtrace()
unsafe extern "C-unwind" { unsafe extern "C-unwind" {
@@ -268,7 +269,8 @@ if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch =
} }
pub use _Unwind_SjLj_RaiseException as _Unwind_RaiseException; pub use _Unwind_SjLj_RaiseException as _Unwind_RaiseException;
} else { }
_ => {
#[cfg_attr( #[cfg_attr(
all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")), all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")),
link(name = "unwind", kind = "static", modifiers = "-bundle") link(name = "unwind", kind = "static", modifiers = "-bundle")
@@ -286,13 +288,13 @@ if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch =
-> _Unwind_Reason_Code; -> _Unwind_Reason_Code;
} }
} }
} // cfg_if! } // cfg_select!
cfg_if::cfg_if! { cfg_select! {
if #[cfg(any( any(
all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"), all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"),
target_os = "cygwin", target_os = "cygwin",
))] { ) => {
// We declare these as opaque types. This is fine since you just need to // We declare these as opaque types. This is fine since you just need to
// pass them to _GCC_specific_handler and forget about them. // pass them to _GCC_specific_handler and forget about them.
pub enum EXCEPTION_RECORD {} pub enum EXCEPTION_RECORD {}
@@ -316,4 +318,5 @@ if #[cfg(any(
-> EXCEPTION_DISPOSITION; -> EXCEPTION_DISPOSITION;
} }
} }
} // cfg_if! _ => {}
} // cfg_select!

View File

@@ -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(). // 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, // 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. // 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 // 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 // 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 // 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 // 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. // 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 // corresponds with llvm::WebAssembly::Tag::CPP_EXCEPTION
// in llvm-project/llvm/include/llvm/CodeGen/WasmEHFuncInfo.h // in llvm-project/llvm/include/llvm/CodeGen/WasmEHFuncInfo.h
const CPP_EXCEPTION_TAG: i32 = 0; const CPP_EXCEPTION_TAG: i32 = 0;
core::arch::wasm::throw::<CPP_EXCEPTION_TAG>(exception.cast()) core::arch::wasm::throw::<CPP_EXCEPTION_TAG>(exception.cast())
} else { }
_ => {
let _ = exception; let _ = exception;
core::arch::wasm::unreachable() core::arch::wasm::unreachable()
} }