From 8ca39104f1af6871ccc6119ddfda37aa76f628fb Mon Sep 17 00:00:00 2001 From: Henry Jiang Date: Tue, 22 Oct 2024 20:18:11 -0400 Subject: [PATCH 1/6] AIX use /dev/urandom for impl --- library/std/src/random.rs | 2 +- library/std/src/sys/random/mod.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/library/std/src/random.rs b/library/std/src/random.rs index cdb88c795bfd4..45f51dd37b041 100644 --- a/library/std/src/random.rs +++ b/library/std/src/random.rs @@ -38,7 +38,7 @@ use crate::sys::random as sys; /// Vita | `arc4random_buf` /// Hermit | `read_entropy` /// Horizon | `getrandom` shim -/// Hurd, L4Re, QNX | `/dev/urandom` +/// AIX, Hurd, L4Re, QNX | `/dev/urandom` /// Redox | `/scheme/rand` /// RTEMS | [`arc4random_buf`](https://docs.rtems.org/branches/master/bsp-howto/getentropy.html) /// SGX | [`rdrand`](https://en.wikipedia.org/wiki/RDRAND) diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index edc2cacdfd874..f42351deb92c0 100644 --- a/library/std/src/sys/random/mod.rs +++ b/library/std/src/sys/random/mod.rs @@ -40,6 +40,7 @@ cfg_if::cfg_if! { mod horizon; pub use horizon::fill_bytes; } else if #[cfg(any( + target_os = "aix", target_os = "hurd", target_os = "l4re", target_os = "nto", From 464b2425d810a97450bf2e45f39fc70b5203268c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:03:22 +0800 Subject: [PATCH 2/6] compiletest: suppress Windows Error Reporting (WER) for `run-make` tests --- src/tools/compiletest/src/runtest.rs | 20 +++++++++++++------ src/tools/compiletest/src/runtest/run_make.rs | 6 +++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7db37af60d2c5..74e5ce67f5b31 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -59,7 +59,7 @@ fn disable_error_reporting R, R>(f: F) -> R { use std::sync::Mutex; use windows::Win32::System::Diagnostics::Debug::{ - SEM_NOGPFAULTERRORBOX, SetErrorMode, THREAD_ERROR_MODE, + SEM_FAILCRITICALERRORS, SEM_NOGPFAULTERRORBOX, SetErrorMode, THREAD_ERROR_MODE, }; static LOCK: Mutex<()> = Mutex::new(()); @@ -67,13 +67,21 @@ fn disable_error_reporting R, R>(f: F) -> R { // Error mode is a global variable, so lock it so only one thread will change it let _lock = LOCK.lock().unwrap(); - // Tell Windows to not show any UI on errors (such as terminating abnormally). - // This is important for running tests, since some of them use abnormal - // termination by design. This mode is inherited by all child processes. + // Tell Windows to not show any UI on errors (such as terminating abnormally). This is important + // for running tests, since some of them use abnormal termination by design. This mode is + // inherited by all child processes. + // + // Note that `run-make` tests require `SEM_FAILCRITICALERRORS` in addition to suppress Windows + // Error Reporting (WER) error dialogues that come from "critical failures" such as missing + // DLLs. + // + // See and + // . unsafe { - let old_mode = SetErrorMode(SEM_NOGPFAULTERRORBOX); // read inherited flags + // read inherited flags + let old_mode = SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); let old_mode = THREAD_ERROR_MODE(old_mode); - SetErrorMode(old_mode | SEM_NOGPFAULTERRORBOX); + SetErrorMode(old_mode | SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); let r = f(); SetErrorMode(old_mode); r diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index f8ffd0fbe3f70..e7ae773ffa1d3 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -2,7 +2,7 @@ use std::path::Path; use std::process::{Command, Output, Stdio}; use std::{env, fs}; -use super::{ProcRes, TestCx}; +use super::{ProcRes, TestCx, disable_error_reporting}; use crate::util::{copy_dir_all, dylib_env_var}; impl TestCx<'_> { @@ -514,8 +514,8 @@ impl TestCx<'_> { } } - let (Output { stdout, stderr, status }, truncated) = - self.read2_abbreviated(cmd.spawn().expect("failed to spawn `rmake`")); + let proc = disable_error_reporting(|| cmd.spawn().expect("failed to spawn `rmake`")); + let (Output { stdout, stderr, status }, truncated) = self.read2_abbreviated(proc); if !status.success() { let res = ProcRes { status, From 7f74c894b0e31f370b5321d94f2ca2830e1d30fd Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 17 Oct 2024 12:38:32 -0700 Subject: [PATCH 3/6] [musl] use posix_spawn if a directory change was requested Currently, not all libcs have the `posix_spawn_file_actions_addchdir_np` symbol available to them. So we attempt to do a weak symbol lookup for that function. But that only works if libc is a dynamic library -- with statically linked musl binaries the symbol lookup would never work, so we would never be able to use it even if the musl in use supported the symbol. Now that Rust has a minimum musl version of 1.2.3, all supported musl versions now include this symbol, so we can unconditionally expect it to be there. This symbol was added to libc in https://github.com/rust-lang/libc/pull/3949 -- use it here. I couldn't find any tests for whether the posix_spawn path is used, but I've verified with cargo-nextest that this change works. This is a substantial improvement to nextest's performance with musl. On my workstation with a Ryzen 7950x, against https://github.com/clap-rs/clap at 61f5ee514f8f60ed8f04c6494bdf36c19e7a8126: Before: ``` Summary [ 1.071s] 879 tests run: 879 passed, 0 skipped ``` After: ``` Summary [ 0.392s] 879 tests run: 879 passed, 0 skipped ``` Fixes #99740. --- library/std/src/process/tests.rs | 14 +++++ .../src/sys/pal/unix/process/process_unix.rs | 54 +++++++++++++++---- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs index 88cc95caf4073..fb0b495961c36 100644 --- a/library/std/src/process/tests.rs +++ b/library/std/src/process/tests.rs @@ -96,9 +96,23 @@ fn stdout_works() { #[test] #[cfg_attr(any(windows, target_os = "vxworks"), ignore)] fn set_current_dir_works() { + // On many Unix platforms this will use the posix_spawn path. let mut cmd = shell_cmd(); cmd.arg("-c").arg("pwd").current_dir("/").stdout(Stdio::piped()); assert_eq!(run_output(cmd), "/\n"); + + // Also test the fork/exec path by setting a pre_exec function. + #[cfg(unix)] + { + use crate::os::unix::process::CommandExt; + + let mut cmd = shell_cmd(); + cmd.arg("-c").arg("pwd").current_dir("/").stdout(Stdio::piped()); + unsafe { + cmd.pre_exec(|| Ok(())); + } + assert_eq!(run_output(cmd), "/\n"); + } } #[test] diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index 4551d49e841f7..8faf1fda5464d 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -448,7 +448,6 @@ impl Command { use core::sync::atomic::{AtomicU8, Ordering}; use crate::mem::MaybeUninit; - use crate::sys::weak::weak; use crate::sys::{self, cvt_nz, on_broken_pipe_flag_used}; if self.get_gid().is_some() @@ -462,6 +461,8 @@ impl Command { cfg_if::cfg_if! { if #[cfg(target_os = "linux")] { + use crate::sys::weak::weak; + weak! { fn pidfd_spawnp( *mut libc::c_int, @@ -575,16 +576,44 @@ impl Command { } } - // Solaris, glibc 2.29+, and musl 1.24+ can set a new working directory, - // and maybe others will gain this non-POSIX function too. We'll check - // for this weak symbol as soon as it's needed, so we can return early - // otherwise to do a manual chdir before exec. - weak! { - fn posix_spawn_file_actions_addchdir_np( - *mut libc::posix_spawn_file_actions_t, - *const libc::c_char - ) -> libc::c_int + type PosixSpawnAddChdirFn = unsafe extern "C" fn( + *mut libc::posix_spawn_file_actions_t, + *const libc::c_char, + ) -> libc::c_int; + + /// Get the function pointer for adding a chdir action to a + /// `posix_spawn_file_actions_t`, if available, assuming a dynamic libc. + /// + /// Some platforms can set a new working directory for a spawned process in the + /// `posix_spawn` path. This function looks up the function pointer for adding + /// such an action to a `posix_spawn_file_actions_t` struct. + #[cfg(not(all(target_os = "linux", target_env = "musl")))] + fn get_posix_spawn_addchdir() -> Option { + use crate::sys::weak::weak; + + weak! { + fn posix_spawn_file_actions_addchdir_np( + *mut libc::posix_spawn_file_actions_t, + *const libc::c_char + ) -> libc::c_int + } + + posix_spawn_file_actions_addchdir_np.get() + } + + /// Get the function pointer for adding a chdir action to a + /// `posix_spawn_file_actions_t`, if available, on platforms where the function + /// is known to exist. + /// + /// Weak symbol lookup doesn't work with statically linked libcs, so in cases + /// where static linking is possible we need to either check for the presence + /// of the symbol at compile time or know about it upfront. + #[cfg(all(target_os = "linux", target_env = "musl"))] + fn get_posix_spawn_addchdir() -> Option { + // Our minimum required musl supports this function, so we can just use it. + Some(libc::posix_spawn_file_actions_addchdir_np) } + let addchdir = match self.get_cwd() { Some(cwd) => { if cfg!(target_vendor = "apple") { @@ -597,7 +626,10 @@ impl Command { return Ok(None); } } - match posix_spawn_file_actions_addchdir_np.get() { + // Check for the availability of the posix_spawn addchdir + // function now. If it isn't available, bail and use the + // fork/exec path. + match get_posix_spawn_addchdir() { Some(f) => Some((f, cwd)), None => return Ok(None), } From 689101f8a3ea26f70902b10ab99b9860f565d9dc Mon Sep 17 00:00:00 2001 From: Laiho Date: Thu, 24 Oct 2024 19:08:41 +0300 Subject: [PATCH 4/6] provide default impl for as_utf8_pattern --- library/core/src/str/pattern.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs index eb60effe8138f..f68465c9bdac6 100644 --- a/library/core/src/str/pattern.rs +++ b/library/core/src/str/pattern.rs @@ -162,7 +162,9 @@ pub trait Pattern: Sized { } /// Returns the pattern as utf-8 bytes if possible. - fn as_utf8_pattern(&self) -> Option>; + fn as_utf8_pattern(&self) -> Option> { + None + } } /// Result of calling [`Pattern::as_utf8_pattern()`]. /// Can be used for inspecting the contents of a [`Pattern`] in cases @@ -675,11 +677,6 @@ impl Pattern for MultiCharEqPattern { fn into_searcher(self, haystack: &str) -> MultiCharEqSearcher<'_, C> { MultiCharEqSearcher { haystack, char_eq: self.0, char_indices: haystack.char_indices() } } - - #[inline] - fn as_utf8_pattern(&self) -> Option> { - None - } } unsafe impl<'a, C: MultiCharEq> Searcher<'a> for MultiCharEqSearcher<'a, C> { @@ -770,11 +767,6 @@ macro_rules! pattern_methods { { ($pmap)(self).strip_suffix_of(haystack) } - - #[inline] - fn as_utf8_pattern(&self) -> Option> { - None - } }; } From 4e487689085ba8b490fbf735163250cc4edb05ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tau=20G=C3=A4rtli?= Date: Thu, 24 Oct 2024 18:50:55 +0200 Subject: [PATCH 5/6] rustdoc: Extend fake_variadic to "wrapped" tuples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows impls such as `impl QueryData for OneOf<(T,)>` to be displayed as variadic: `impl QueryData for OneOf<(T₁, T₂, …, Tₙ)>`. See question on zulip: --- compiler/rustc_passes/src/check_attr.rs | 24 +++++++++++++++++------ src/librustdoc/html/format.rs | 18 +++++++++++++++++ tests/rustdoc/primitive-tuple-variadic.rs | 19 ++++++++++++++++++ 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 61e196bdebe66..62c502f952429 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -918,12 +918,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }; match item_kind { Some(ItemKind::Impl(i)) => { - let is_valid = matches!(&i.self_ty.kind, hir::TyKind::Tup([_])) - || if let hir::TyKind::BareFn(bare_fn_ty) = &i.self_ty.kind { - bare_fn_ty.decl.inputs.len() == 1 - } else { - false - } + let is_valid = doc_fake_variadic_is_allowed_self_ty(i.self_ty) || if let Some(&[hir::GenericArg::Type(ty)]) = i .of_trait .as_ref() @@ -2630,3 +2625,20 @@ fn check_duplicates( }, } } + +fn doc_fake_variadic_is_allowed_self_ty(self_ty: &hir::Ty<'_>) -> bool { + matches!(&self_ty.kind, hir::TyKind::Tup([_])) + || if let hir::TyKind::BareFn(bare_fn_ty) = &self_ty.kind { + bare_fn_ty.decl.inputs.len() == 1 + } else { + false + } + || (if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &self_ty.kind + && let Some(&[hir::GenericArg::Type(ty)]) = + path.segments.last().map(|last| last.args().args) + { + doc_fake_variadic_is_allowed_self_ty(ty) + } else { + false + }) +} diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 5c599f20f9fdb..ea2f930ab8376 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1368,6 +1368,24 @@ impl clean::Impl { write!(f, " -> ")?; fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?; } + } else if let clean::Type::Path { path } = type_ + && let Some(generics) = path.generics() + && generics.len() == 1 + && self.kind.is_fake_variadic() + { + let ty = generics[0]; + let wrapper = anchor(path.def_id(), path.last(), cx); + if f.alternate() { + write!(f, "{wrapper:#}<")?; + } else { + write!(f, "{wrapper}<")?; + } + self.print_type(ty, f, use_absolute, cx)?; + if f.alternate() { + write!(f, ">")?; + } else { + write!(f, ">")?; + } } else { fmt_type(&type_, f, use_absolute, cx)?; } diff --git a/tests/rustdoc/primitive-tuple-variadic.rs b/tests/rustdoc/primitive-tuple-variadic.rs index b15e996f929a9..d142729d2a8bc 100644 --- a/tests/rustdoc/primitive-tuple-variadic.rs +++ b/tests/rustdoc/primitive-tuple-variadic.rs @@ -33,3 +33,22 @@ impl Baz<[T; 1]> for (T,) {} //@ has - '//section[@id="impl-Baz%3CT%3E-for-(T,)"]/h3' 'impl Baz for (T₁, T₂, …, Tₙ)' #[doc(fake_variadic)] impl Baz for (T,) {} + +pub trait Qux {} + +pub struct NewType(T); + +//@ has foo/trait.Qux.html +//@ has - '//section[@id="impl-Qux-for-NewType%3C(T,)%3E"]/h3' 'impl Qux for NewType<(T₁, T₂, …, Tₙ)>' +#[doc(fake_variadic)] +impl Qux for NewType<(T,)> {} + +//@ has foo/trait.Qux.html +//@ has - '//section[@id="impl-Qux-for-NewType%3CNewType%3C(T,)%3E%3E"]/h3' 'impl Qux for NewType>' +#[doc(fake_variadic)] +impl Qux for NewType> {} + +//@ has foo/trait.Qux.html +//@ has - '//section[@id="impl-Qux-for-NewType%3Cfn(T)+-%3E+Out%3E"]/h3' 'impl Qux for NewType Out>' +#[doc(fake_variadic)] +impl Qux for NewType Out> {} From 5368b120a1742893460c515bb198342d6f0a3800 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 24 Oct 2024 17:50:19 +0900 Subject: [PATCH 6/6] Avoid use imports in thread_local_inner! in statik Fixes #131863 for wasm targets All other macros were done in #131866, but this sub module is missed. --- library/std/src/sys/thread_local/statik.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/thread_local/statik.rs b/library/std/src/sys/thread_local/statik.rs index ba94caa669027..4da01a84acf68 100644 --- a/library/std/src/sys/thread_local/statik.rs +++ b/library/std/src/sys/thread_local/statik.rs @@ -14,12 +14,11 @@ pub macro thread_local_inner { (@key $t:ty, const $init:expr) => {{ const __INIT: $t = $init; + // NOTE: Please update the shadowing test in `tests/thread.rs` if these types are renamed. unsafe { - use $crate::thread::LocalKey; - use $crate::thread::local_impl::EagerStorage; - - LocalKey::new(|_| { - static VAL: EagerStorage<$t> = EagerStorage { value: __INIT }; + $crate::thread::LocalKey::new(|_| { + static VAL: $crate::thread::local_impl::EagerStorage<$t> = + $crate::thread::local_impl::EagerStorage { value: __INIT }; &VAL.value }) }