Skip to content

Commit 5088fe3

Browse files
committed
Auto merge of #127639 - matthiaskrgr:rollup-pfmhack, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #124980 (Generalize `fn allocator` for Rc/Arc.) - #126639 (Add AMX target-features and `x86_amx_intrinsics` feature flag) - #126827 (Use pidfd_spawn for faster process spawning when a PidFd is requested) - #127397 (fix interleaved output in the default panic hook when multiple threads panic simultaneously) - #127433 (Stabilize const_cstr_from_ptr (CStr::from_ptr, CStr::count_bytes)) - #127613 (Update dist-riscv64-linux to binutils 2.40) - #127632 (Implement `precise_capturing` support for rustdoc) r? `@ghost` `@rustbot` modify labels: rollup
2 parents b286722 + 14e17b8 commit 5088fe3

File tree

34 files changed

+524
-67
lines changed

34 files changed

+524
-67
lines changed

compiler/rustc_codegen_ssa/src/target_features.rs

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub fn from_target_feature(
8080
Some(sym::loongarch_target_feature) => rust_features.loongarch_target_feature,
8181
Some(sym::lahfsahf_target_feature) => rust_features.lahfsahf_target_feature,
8282
Some(sym::prfchw_target_feature) => rust_features.prfchw_target_feature,
83+
Some(sym::x86_amx_intrinsics) => rust_features.x86_amx_intrinsics,
8384
Some(name) => bug!("unknown target feature gate {}", name),
8485
None => true,
8586
};

compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,8 @@ declare_features! (
640640
(unstable, unsized_tuple_coercion, "1.20.0", Some(42877)),
641641
/// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
642642
(unstable, used_with_arg, "1.60.0", Some(93798)),
643+
/// Allows use of x86 `AMX` target-feature attributes and intrinsics
644+
(unstable, x86_amx_intrinsics, "CURRENT_RUSTC_VERSION", Some(126622)),
643645
/// Allows `do yeet` expressions
644646
(unstable, yeet_expr, "1.62.0", Some(96373)),
645647
// !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!!

compiler/rustc_hir/src/hir.rs

+7
Original file line numberDiff line numberDiff line change
@@ -2708,6 +2708,13 @@ impl PreciseCapturingArg<'_> {
27082708
PreciseCapturingArg::Param(param) => param.hir_id,
27092709
}
27102710
}
2711+
2712+
pub fn name(self) -> Symbol {
2713+
match self {
2714+
PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
2715+
PreciseCapturingArg::Param(param) => param.ident.name,
2716+
}
2717+
}
27112718
}
27122719

27132720
/// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2072,6 +2072,7 @@ symbols! {
20722072
write_str,
20732073
write_via_move,
20742074
writeln_macro,
2075+
x86_amx_intrinsics,
20752076
x87_reg,
20762077
xer,
20772078
xmm_reg,

compiler/rustc_target/src/target_features.rs

+5
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[
192192
// tidy-alphabetical-start
193193
("adx", Stable),
194194
("aes", Stable),
195+
("amx-bf16", Unstable(sym::x86_amx_intrinsics)),
196+
("amx-complex", Unstable(sym::x86_amx_intrinsics)),
197+
("amx-fp16", Unstable(sym::x86_amx_intrinsics)),
198+
("amx-int8", Unstable(sym::x86_amx_intrinsics)),
199+
("amx-tile", Unstable(sym::x86_amx_intrinsics)),
195200
("avx", Stable),
196201
("avx2", Stable),
197202
("avx512bf16", Unstable(sym::avx512_target_feature)),

library/alloc/src/rc.rs

+18-10
Original file line numberDiff line numberDiff line change
@@ -665,16 +665,6 @@ impl<T> Rc<T> {
665665
}
666666

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

13331323
impl<T: ?Sized, A: Allocator> Rc<T, A> {
1324+
/// Returns a reference to the underlying allocator.
1325+
///
1326+
/// Note: this is an associated function, which means that you have
1327+
/// to call it as `Rc::allocator(&r)` instead of `r.allocator()`. This
1328+
/// is so that there is no conflict with a method on the inner type.
1329+
#[inline]
1330+
#[unstable(feature = "allocator_api", issue = "32838")]
1331+
pub fn allocator(this: &Self) -> &A {
1332+
&this.alloc
1333+
}
1334+
13341335
/// Consumes the `Rc`, returning the wrapped pointer.
13351336
///
13361337
/// To avoid a memory leak the pointer must be converted back to an `Rc` using
@@ -2994,6 +2995,13 @@ impl<T: ?Sized> Weak<T> {
29942995
}
29952996

29962997
impl<T: ?Sized, A: Allocator> Weak<T, A> {
2998+
/// Returns a reference to the underlying allocator.
2999+
#[inline]
3000+
#[unstable(feature = "allocator_api", issue = "32838")]
3001+
pub fn allocator(&self) -> &A {
3002+
&self.alloc
3003+
}
3004+
29973005
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
29983006
///
29993007
/// The pointer is valid only if there are some strong references. The pointer may be dangling,

library/alloc/src/sync.rs

+18-10
Original file line numberDiff line numberDiff line change
@@ -677,16 +677,6 @@ impl<T> Arc<T> {
677677
}
678678

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

14721462
impl<T: ?Sized, A: Allocator> Arc<T, A> {
1463+
/// Returns a reference to the underlying allocator.
1464+
///
1465+
/// Note: this is an associated function, which means that you have
1466+
/// to call it as `Arc::allocator(&a)` instead of `a.allocator()`. This
1467+
/// is so that there is no conflict with a method on the inner type.
1468+
#[inline]
1469+
#[unstable(feature = "allocator_api", issue = "32838")]
1470+
pub fn allocator(this: &Self) -> &A {
1471+
&this.alloc
1472+
}
1473+
14731474
/// Consumes the `Arc`, returning the wrapped pointer.
14741475
///
14751476
/// To avoid a memory leak the pointer must be converted back to an `Arc` using
@@ -2715,6 +2716,13 @@ impl<T: ?Sized> Weak<T> {
27152716
}
27162717

27172718
impl<T: ?Sized, A: Allocator> Weak<T, A> {
2719+
/// Returns a reference to the underlying allocator.
2720+
#[inline]
2721+
#[unstable(feature = "allocator_api", issue = "32838")]
2722+
pub fn allocator(&self) -> &A {
2723+
&self.alloc
2724+
}
2725+
27182726
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
27192727
///
27202728
/// The pointer is valid only if there are some strong references. The pointer may be dangling,

library/core/src/ffi/c_str.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,6 @@ impl CStr {
263263
/// ```
264264
///
265265
/// ```
266-
/// #![feature(const_cstr_from_ptr)]
267-
///
268266
/// use std::ffi::{c_char, CStr};
269267
///
270268
/// const HELLO_PTR: *const c_char = {
@@ -280,7 +278,7 @@ impl CStr {
280278
#[inline] // inline is necessary for codegen to see strlen.
281279
#[must_use]
282280
#[stable(feature = "rust1", since = "1.0.0")]
283-
#[rustc_const_unstable(feature = "const_cstr_from_ptr", issue = "113219")]
281+
#[rustc_const_stable(feature = "const_cstr_from_ptr", since = "CURRENT_RUSTC_VERSION")]
284282
pub const unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
285283
// SAFETY: The caller has provided a pointer that points to a valid C
286284
// string with a NUL terminator less than `isize::MAX` from `ptr`.
@@ -542,7 +540,7 @@ impl CStr {
542540
#[must_use]
543541
#[doc(alias("len", "strlen"))]
544542
#[stable(feature = "cstr_count_bytes", since = "1.79.0")]
545-
#[rustc_const_unstable(feature = "const_cstr_from_ptr", issue = "113219")]
543+
#[rustc_const_stable(feature = "const_cstr_from_ptr", since = "CURRENT_RUSTC_VERSION")]
546544
pub const fn count_bytes(&self) -> usize {
547545
self.inner.len() - 1
548546
}
@@ -742,6 +740,9 @@ impl AsRef<CStr> for CStr {
742740
/// The pointer must point to a valid buffer that contains a NUL terminator. The NUL must be
743741
/// located within `isize::MAX` from `ptr`.
744742
#[inline]
743+
#[unstable(feature = "cstr_internals", issue = "none")]
744+
#[rustc_const_stable(feature = "const_cstr_from_ptr", since = "CURRENT_RUSTC_VERSION")]
745+
#[rustc_allow_const_fn_unstable(const_eval_select)]
745746
const unsafe fn const_strlen(ptr: *const c_char) -> usize {
746747
const fn strlen_ct(s: *const c_char) -> usize {
747748
let mut len = 0;

library/std/src/panicking.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -253,16 +253,20 @@ fn default_hook(info: &PanicHookInfo<'_>) {
253253
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
254254

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

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

260263
match backtrace {
264+
// SAFETY: we took out a lock just a second ago.
261265
Some(BacktraceStyle::Short) => {
262-
drop(backtrace::print(err, crate::backtrace_rs::PrintFmt::Short))
266+
drop(lock.print(err, crate::backtrace_rs::PrintFmt::Short))
263267
}
264268
Some(BacktraceStyle::Full) => {
265-
drop(backtrace::print(err, crate::backtrace_rs::PrintFmt::Full))
269+
drop(lock.print(err, crate::backtrace_rs::PrintFmt::Full))
266270
}
267271
Some(BacktraceStyle::Off) => {
268272
if FIRST_PANIC.swap(false, Ordering::Relaxed) {

library/std/src/sys/backtrace.rs

+25-28
Original file line numberDiff line numberDiff line change
@@ -7,44 +7,41 @@ use crate::fmt;
77
use crate::io;
88
use crate::io::prelude::*;
99
use crate::path::{self, Path, PathBuf};
10-
use crate::sync::{Mutex, PoisonError};
10+
use crate::sync::{Mutex, MutexGuard, PoisonError};
1111

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

15-
pub fn lock() -> impl Drop {
15+
pub(crate) struct BacktraceLock<'a>(#[allow(dead_code)] MutexGuard<'a, ()>);
16+
17+
pub(crate) fn lock<'a>() -> BacktraceLock<'a> {
1618
static LOCK: Mutex<()> = Mutex::new(());
17-
LOCK.lock().unwrap_or_else(PoisonError::into_inner)
19+
BacktraceLock(LOCK.lock().unwrap_or_else(PoisonError::into_inner))
1820
}
1921

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

38-
unsafe fn _print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
39-
struct DisplayBacktrace {
40-
format: PrintFmt,
41-
}
42-
impl fmt::Display for DisplayBacktrace {
43-
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
44-
unsafe { _print_fmt(fmt, self.format) }
35+
struct DisplayBacktrace {
36+
format: PrintFmt,
37+
}
38+
impl fmt::Display for DisplayBacktrace {
39+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
40+
unsafe { _print_fmt(fmt, self.format) }
41+
}
4542
}
43+
write!(w, "{}", DisplayBacktrace { format })
4644
}
47-
write!(w, "{}", DisplayBacktrace { format })
4845
}
4946

5047
unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::Result {

library/std/src/sys/pal/unix/linux/pidfd/tests.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::assert_matches::assert_matches;
22
use crate::os::fd::{AsRawFd, RawFd};
3-
use crate::os::linux::process::{ChildExt, CommandExt};
4-
use crate::os::unix::process::ExitStatusExt;
3+
use crate::os::linux::process::{ChildExt, CommandExt as _};
4+
use crate::os::unix::process::{CommandExt as _, ExitStatusExt};
55
use crate::process::Command;
66

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

@@ -42,6 +43,17 @@ fn test_command_pidfd() {
4243
.unwrap()
4344
.pidfd()
4445
.expect_err("pidfd should not have been created");
46+
47+
// exercise the fork/exec path since the earlier attempts may have used pidfd_spawnp()
48+
let mut child =
49+
unsafe { Command::new("false").pre_exec(|| Ok(())) }.create_pidfd(true).spawn().unwrap();
50+
51+
assert!(child.id() > 0 && child.id() < -1i32 as u32);
52+
53+
if pidfd_open_available {
54+
assert!(child.pidfd().is_ok())
55+
}
56+
child.wait().expect("error waiting on child");
4557
}
4658

4759
#[test]

library/std/src/sys/pal/unix/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,13 @@ macro_rules! impl_is_minus_one {
305305

306306
impl_is_minus_one! { i8 i16 i32 i64 isize }
307307

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

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

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

0 commit comments

Comments
 (0)