Skip to content

Commit

Permalink
Auto merge of rust-lang#127639 - matthiaskrgr:rollup-pfmhack, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#124980 (Generalize `fn allocator` for Rc/Arc.)
 - rust-lang#126639 (Add AMX target-features and `x86_amx_intrinsics` feature flag)
 - rust-lang#126827 (Use pidfd_spawn for faster process spawning when a PidFd is requested)
 - rust-lang#127397 (fix interleaved output in the default panic hook when multiple threads panic simultaneously)
 - rust-lang#127433 (Stabilize const_cstr_from_ptr (CStr::from_ptr, CStr::count_bytes))
 - rust-lang#127613 (Update dist-riscv64-linux to binutils 2.40)
 - rust-lang#127632 (Implement `precise_capturing` support for rustdoc)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jul 12, 2024
2 parents b286722 + 14e17b8 commit 5088fe3
Show file tree
Hide file tree
Showing 34 changed files with 524 additions and 67 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub fn from_target_feature(
Some(sym::loongarch_target_feature) => rust_features.loongarch_target_feature,
Some(sym::lahfsahf_target_feature) => rust_features.lahfsahf_target_feature,
Some(sym::prfchw_target_feature) => rust_features.prfchw_target_feature,
Some(sym::x86_amx_intrinsics) => rust_features.x86_amx_intrinsics,
Some(name) => bug!("unknown target feature gate {}", name),
None => true,
};
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,8 @@ declare_features! (
(unstable, unsized_tuple_coercion, "1.20.0", Some(42877)),
/// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
(unstable, used_with_arg, "1.60.0", Some(93798)),
/// Allows use of x86 `AMX` target-feature attributes and intrinsics
(unstable, x86_amx_intrinsics, "CURRENT_RUSTC_VERSION", Some(126622)),
/// Allows `do yeet` expressions
(unstable, yeet_expr, "1.62.0", Some(96373)),
// !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!!
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2708,6 +2708,13 @@ impl PreciseCapturingArg<'_> {
PreciseCapturingArg::Param(param) => param.hir_id,
}
}

pub fn name(self) -> Symbol {
match self {
PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
PreciseCapturingArg::Param(param) => param.ident.name,
}
}
}

/// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2072,6 +2072,7 @@ symbols! {
write_str,
write_via_move,
writeln_macro,
x86_amx_intrinsics,
x87_reg,
xer,
xmm_reg,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[
// tidy-alphabetical-start
("adx", Stable),
("aes", Stable),
("amx-bf16", Unstable(sym::x86_amx_intrinsics)),
("amx-complex", Unstable(sym::x86_amx_intrinsics)),
("amx-fp16", Unstable(sym::x86_amx_intrinsics)),
("amx-int8", Unstable(sym::x86_amx_intrinsics)),
("amx-tile", Unstable(sym::x86_amx_intrinsics)),
("avx", Stable),
("avx2", Stable),
("avx512bf16", Unstable(sym::avx512_target_feature)),
Expand Down
28 changes: 18 additions & 10 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,16 +665,6 @@ impl<T> Rc<T> {
}

impl<T, A: Allocator> Rc<T, A> {
/// Returns a reference to the underlying allocator.
///
/// Note: this is an associated function, which means that you have
/// to call it as `Rc::allocator(&r)` instead of `r.allocator()`. This
/// is so that there is no conflict with a method on the inner type.
#[inline]
#[unstable(feature = "allocator_api", issue = "32838")]
pub fn allocator(this: &Self) -> &A {
&this.alloc
}
/// Constructs a new `Rc` in the provided allocator.
///
/// # Examples
Expand Down Expand Up @@ -1331,6 +1321,17 @@ impl<T: ?Sized> Rc<T> {
}

impl<T: ?Sized, A: Allocator> Rc<T, A> {
/// Returns a reference to the underlying allocator.
///
/// Note: this is an associated function, which means that you have
/// to call it as `Rc::allocator(&r)` instead of `r.allocator()`. This
/// is so that there is no conflict with a method on the inner type.
#[inline]
#[unstable(feature = "allocator_api", issue = "32838")]
pub fn allocator(this: &Self) -> &A {
&this.alloc
}

/// Consumes the `Rc`, returning the wrapped pointer.
///
/// To avoid a memory leak the pointer must be converted back to an `Rc` using
Expand Down Expand Up @@ -2994,6 +2995,13 @@ impl<T: ?Sized> Weak<T> {
}

impl<T: ?Sized, A: Allocator> Weak<T, A> {
/// Returns a reference to the underlying allocator.
#[inline]
#[unstable(feature = "allocator_api", issue = "32838")]
pub fn allocator(&self) -> &A {
&self.alloc
}

/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
///
/// The pointer is valid only if there are some strong references. The pointer may be dangling,
Expand Down
28 changes: 18 additions & 10 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,16 +677,6 @@ impl<T> Arc<T> {
}

impl<T, A: Allocator> Arc<T, A> {
/// Returns a reference to the underlying allocator.
///
/// Note: this is an associated function, which means that you have
/// to call it as `Arc::allocator(&a)` instead of `a.allocator()`. This
/// is so that there is no conflict with a method on the inner type.
#[inline]
#[unstable(feature = "allocator_api", issue = "32838")]
pub fn allocator(this: &Self) -> &A {
&this.alloc
}
/// Constructs a new `Arc<T>` in the provided allocator.
///
/// # Examples
Expand Down Expand Up @@ -1470,6 +1460,17 @@ impl<T: ?Sized> Arc<T> {
}

impl<T: ?Sized, A: Allocator> Arc<T, A> {
/// Returns a reference to the underlying allocator.
///
/// Note: this is an associated function, which means that you have
/// to call it as `Arc::allocator(&a)` instead of `a.allocator()`. This
/// is so that there is no conflict with a method on the inner type.
#[inline]
#[unstable(feature = "allocator_api", issue = "32838")]
pub fn allocator(this: &Self) -> &A {
&this.alloc
}

/// Consumes the `Arc`, returning the wrapped pointer.
///
/// To avoid a memory leak the pointer must be converted back to an `Arc` using
Expand Down Expand Up @@ -2715,6 +2716,13 @@ impl<T: ?Sized> Weak<T> {
}

impl<T: ?Sized, A: Allocator> Weak<T, A> {
/// Returns a reference to the underlying allocator.
#[inline]
#[unstable(feature = "allocator_api", issue = "32838")]
pub fn allocator(&self) -> &A {
&self.alloc
}

/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
///
/// The pointer is valid only if there are some strong references. The pointer may be dangling,
Expand Down
9 changes: 5 additions & 4 deletions library/core/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,6 @@ impl CStr {
/// ```
///
/// ```
/// #![feature(const_cstr_from_ptr)]
///
/// use std::ffi::{c_char, CStr};
///
/// const HELLO_PTR: *const c_char = {
Expand All @@ -280,7 +278,7 @@ impl CStr {
#[inline] // inline is necessary for codegen to see strlen.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cstr_from_ptr", issue = "113219")]
#[rustc_const_stable(feature = "const_cstr_from_ptr", since = "CURRENT_RUSTC_VERSION")]
pub const unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
// SAFETY: The caller has provided a pointer that points to a valid C
// string with a NUL terminator less than `isize::MAX` from `ptr`.
Expand Down Expand Up @@ -542,7 +540,7 @@ impl CStr {
#[must_use]
#[doc(alias("len", "strlen"))]
#[stable(feature = "cstr_count_bytes", since = "1.79.0")]
#[rustc_const_unstable(feature = "const_cstr_from_ptr", issue = "113219")]
#[rustc_const_stable(feature = "const_cstr_from_ptr", since = "CURRENT_RUSTC_VERSION")]
pub const fn count_bytes(&self) -> usize {
self.inner.len() - 1
}
Expand Down Expand Up @@ -742,6 +740,9 @@ impl AsRef<CStr> for CStr {
/// The pointer must point to a valid buffer that contains a NUL terminator. The NUL must be
/// located within `isize::MAX` from `ptr`.
#[inline]
#[unstable(feature = "cstr_internals", issue = "none")]
#[rustc_const_stable(feature = "const_cstr_from_ptr", since = "CURRENT_RUSTC_VERSION")]
#[rustc_allow_const_fn_unstable(const_eval_select)]
const unsafe fn const_strlen(ptr: *const c_char) -> usize {
const fn strlen_ct(s: *const c_char) -> usize {
let mut len = 0;
Expand Down
8 changes: 6 additions & 2 deletions library/std/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,16 +253,20 @@ fn default_hook(info: &PanicHookInfo<'_>) {
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");

let write = |err: &mut dyn crate::io::Write| {
// Use a lock to prevent mixed output in multithreading context.
// Some platforms also require it when printing a backtrace, like `SymFromAddr` on Windows.
let mut lock = backtrace::lock();
let _ = writeln!(err, "thread '{name}' panicked at {location}:\n{msg}");

static FIRST_PANIC: AtomicBool = AtomicBool::new(true);

match backtrace {
// SAFETY: we took out a lock just a second ago.
Some(BacktraceStyle::Short) => {
drop(backtrace::print(err, crate::backtrace_rs::PrintFmt::Short))
drop(lock.print(err, crate::backtrace_rs::PrintFmt::Short))
}
Some(BacktraceStyle::Full) => {
drop(backtrace::print(err, crate::backtrace_rs::PrintFmt::Full))
drop(lock.print(err, crate::backtrace_rs::PrintFmt::Full))
}
Some(BacktraceStyle::Off) => {
if FIRST_PANIC.swap(false, Ordering::Relaxed) {
Expand Down
53 changes: 25 additions & 28 deletions library/std/src/sys/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,41 @@ use crate::fmt;
use crate::io;
use crate::io::prelude::*;
use crate::path::{self, Path, PathBuf};
use crate::sync::{Mutex, PoisonError};
use crate::sync::{Mutex, MutexGuard, PoisonError};

/// Max number of frames to print.
const MAX_NB_FRAMES: usize = 100;

pub fn lock() -> impl Drop {
pub(crate) struct BacktraceLock<'a>(#[allow(dead_code)] MutexGuard<'a, ()>);

pub(crate) fn lock<'a>() -> BacktraceLock<'a> {
static LOCK: Mutex<()> = Mutex::new(());
LOCK.lock().unwrap_or_else(PoisonError::into_inner)
BacktraceLock(LOCK.lock().unwrap_or_else(PoisonError::into_inner))
}

/// Prints the current backtrace.
pub fn print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
// There are issues currently linking libbacktrace into tests, and in
// general during std's own unit tests we're not testing this path. In
// test mode immediately return here to optimize away any references to the
// libbacktrace symbols
if cfg!(test) {
return Ok(());
}

// Use a lock to prevent mixed output in multithreading context.
// Some platforms also requires it, like `SymFromAddr` on Windows.
unsafe {
let _lock = lock();
_print(w, format)
}
}
impl BacktraceLock<'_> {
/// Prints the current backtrace.
///
/// NOTE: this function is not Sync. The caller must hold a mutex lock, or there must be only one thread in the program.
pub(crate) fn print(&mut self, w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
// There are issues currently linking libbacktrace into tests, and in
// general during std's own unit tests we're not testing this path. In
// test mode immediately return here to optimize away any references to the
// libbacktrace symbols
if cfg!(test) {
return Ok(());
}

unsafe fn _print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
struct DisplayBacktrace {
format: PrintFmt,
}
impl fmt::Display for DisplayBacktrace {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
unsafe { _print_fmt(fmt, self.format) }
struct DisplayBacktrace {
format: PrintFmt,
}
impl fmt::Display for DisplayBacktrace {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
unsafe { _print_fmt(fmt, self.format) }
}
}
write!(w, "{}", DisplayBacktrace { format })
}
write!(w, "{}", DisplayBacktrace { format })
}

unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::Result {
Expand Down
16 changes: 14 additions & 2 deletions library/std/src/sys/pal/unix/linux/pidfd/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::assert_matches::assert_matches;
use crate::os::fd::{AsRawFd, RawFd};
use crate::os::linux::process::{ChildExt, CommandExt};
use crate::os::unix::process::ExitStatusExt;
use crate::os::linux::process::{ChildExt, CommandExt as _};
use crate::os::unix::process::{CommandExt as _, ExitStatusExt};
use crate::process::Command;

#[test]
Expand All @@ -21,6 +21,7 @@ fn test_command_pidfd() {
let flags = super::cvt(unsafe { libc::fcntl(pidfd.as_raw_fd(), libc::F_GETFD) }).unwrap();
assert!(flags & libc::FD_CLOEXEC != 0);
}
assert!(child.id() > 0 && child.id() < -1i32 as u32);
let status = child.wait().expect("error waiting on pidfd");
assert_eq!(status.code(), Some(1));

Expand All @@ -42,6 +43,17 @@ fn test_command_pidfd() {
.unwrap()
.pidfd()
.expect_err("pidfd should not have been created");

// exercise the fork/exec path since the earlier attempts may have used pidfd_spawnp()
let mut child =
unsafe { Command::new("false").pre_exec(|| Ok(())) }.create_pidfd(true).spawn().unwrap();

assert!(child.id() > 0 && child.id() < -1i32 as u32);

if pidfd_open_available {
assert!(child.pidfd().is_ok())
}
child.wait().expect("error waiting on child");
}

#[test]
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/sys/pal/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,13 @@ macro_rules! impl_is_minus_one {

impl_is_minus_one! { i8 i16 i32 i64 isize }

/// Convert native return values to Result using the *-1 means error is in `errno`* convention.
/// Non-error values are `Ok`-wrapped.
pub fn cvt<T: IsMinusOne>(t: T) -> crate::io::Result<T> {
if t.is_minus_one() { Err(crate::io::Error::last_os_error()) } else { Ok(t) }
}

/// `-1` → look at `errno` → retry on `EINTR`. Otherwise `Ok()`-wrap the closure return value.
pub fn cvt_r<T, F>(mut f: F) -> crate::io::Result<T>
where
T: IsMinusOne,
Expand All @@ -323,6 +326,7 @@ where
}

#[allow(dead_code)] // Not used on all platforms.
/// Zero means `Ok()`, all other values are treated as raw OS errors. Does not look at `errno`.
pub fn cvt_nz(error: libc::c_int) -> crate::io::Result<()> {
if error == 0 { Ok(()) } else { Err(crate::io::Error::from_raw_os_error(error)) }
}
Expand Down
Loading

0 comments on commit 5088fe3

Please sign in to comment.