Auto merge of #138831 - matthiaskrgr:rollup-3t0dqiz, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #138609 (Add stack overflow handler for cygwin)
 - #138639 (Clean UI tests 2 of n)
 - #138773 (catch_unwind intrinsic: document return value)
 - #138782 (test(ui): add tuple-struct-where-clause-suggestion ui test for #91520)
 - #138794 (expand: Do not report `cfg_attr` traces on macros as unused attributes)
 - #138801 (triagebot: add autolabel rules for D-* and L-*)
 - #138804 (Allow inlining for `Atomic*::from_ptr`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-03-22 20:52:30 +00:00
commit b48576b4db
17 changed files with 226 additions and 86 deletions

View file

@ -3002,6 +3002,7 @@ pub const fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discrimina
/// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the
/// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs.
/// Returns `1` if unwinding occurred and `catch_fn` was called; returns `0` otherwise.
///
/// `catch_fn` must not unwind.
///

View file

@ -469,6 +469,7 @@ impl AtomicBool {
///
/// [valid]: crate::ptr#safety
/// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
#[inline]
#[stable(feature = "atomic_from_ptr", since = "1.75.0")]
#[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool {
@ -1389,6 +1390,7 @@ impl<T> AtomicPtr<T> {
///
/// [valid]: crate::ptr#safety
/// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
#[inline]
#[stable(feature = "atomic_from_ptr", since = "1.75.0")]
#[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T> {
@ -2525,6 +2527,7 @@ macro_rules! atomic_int {
///
/// [valid]: crate::ptr#safety
/// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
#[inline]
#[stable(feature = "atomic_from_ptr", since = "1.75.0")]
#[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a $atomic_type {

View file

@ -585,6 +585,7 @@ mod imp {
target_os = "openbsd",
target_os = "solaris",
target_os = "illumos",
target_os = "cygwin",
)))]
mod imp {
pub unsafe fn init() {}
@ -597,3 +598,89 @@ mod imp {
pub unsafe fn drop_handler(_data: *mut libc::c_void) {}
}
#[cfg(target_os = "cygwin")]
mod imp {
mod c {
pub type PVECTORED_EXCEPTION_HANDLER =
Option<unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32>;
pub type NTSTATUS = i32;
pub type BOOL = i32;
unsafe extern "system" {
pub fn AddVectoredExceptionHandler(
first: u32,
handler: PVECTORED_EXCEPTION_HANDLER,
) -> *mut core::ffi::c_void;
pub fn SetThreadStackGuarantee(stacksizeinbytes: *mut u32) -> BOOL;
}
pub const EXCEPTION_STACK_OVERFLOW: NTSTATUS = 0xC00000FD_u32 as _;
pub const EXCEPTION_CONTINUE_SEARCH: i32 = 1i32;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct EXCEPTION_POINTERS {
pub ExceptionRecord: *mut EXCEPTION_RECORD,
// We don't need this field here
// pub Context: *mut CONTEXT,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct EXCEPTION_RECORD {
pub ExceptionCode: NTSTATUS,
pub ExceptionFlags: u32,
pub ExceptionRecord: *mut EXCEPTION_RECORD,
pub ExceptionAddress: *mut core::ffi::c_void,
pub NumberParameters: u32,
pub ExceptionInformation: [usize; 15],
}
}
/// Reserve stack space for use in stack overflow exceptions.
fn reserve_stack() {
let result = unsafe { c::SetThreadStackGuarantee(&mut 0x5000) };
// Reserving stack space is not critical so we allow it to fail in the released build of libstd.
// We still use debug assert here so that CI will test that we haven't made a mistake calling the function.
debug_assert_ne!(result, 0, "failed to reserve stack space for exception handling");
}
unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> i32 {
// SAFETY: It's up to the caller (which in this case is the OS) to ensure that `ExceptionInfo` is valid.
unsafe {
let rec = &(*(*ExceptionInfo).ExceptionRecord);
let code = rec.ExceptionCode;
if code == c::EXCEPTION_STACK_OVERFLOW {
crate::thread::with_current_name(|name| {
let name = name.unwrap_or("<unknown>");
rtprintpanic!("\nthread '{name}' has overflowed its stack\n");
});
}
c::EXCEPTION_CONTINUE_SEARCH
}
}
pub unsafe fn init() {
// SAFETY: `vectored_handler` has the correct ABI and is safe to call during exception handling.
unsafe {
let result = c::AddVectoredExceptionHandler(0, Some(vectored_handler));
// Similar to the above, adding the stack overflow handler is allowed to fail
// but a debug assert is used so CI will still test that it normally works.
debug_assert!(!result.is_null(), "failed to install exception handler");
}
// Set the thread stack guarantee for the main thread.
reserve_stack();
}
pub unsafe fn cleanup() {}
pub unsafe fn make_handler(main_thread: bool) -> super::Handler {
if !main_thread {
reserve_stack();
}
super::Handler::null()
}
pub unsafe fn drop_handler(_data: *mut libc::c_void) {}
}