Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #138831

Merged
merged 14 commits into from
Mar 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1941,7 +1941,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
let attr_name = attr.ident().unwrap().name;
// `#[cfg]` and `#[cfg_attr]` are special - they are
// eagerly evaluated.
if attr_name != sym::cfg && attr_name != sym::cfg_attr {
if attr_name != sym::cfg && attr_name != sym::cfg_attr_trace {
self.cx.sess.psess.buffer_lint(
UNUSED_ATTRIBUTES,
attr.span,
Expand Down
1 change: 1 addition & 0 deletions library/core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down
3 changes: 3 additions & 0 deletions library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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 {
Expand Down
87 changes: 87 additions & 0 deletions library/std/src/sys/pal/unix/stack_overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ mod imp {
target_os = "openbsd",
target_os = "solaris",
target_os = "illumos",
target_os = "cygwin",
)))]
mod imp {
pub unsafe fn init() {}
Expand All @@ -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) {}
}
3 changes: 0 additions & 3 deletions src/tools/tidy/src/issues.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2000,7 +2000,6 @@ ui/issues/issue-28586.rs
ui/issues/issue-28600.rs
ui/issues/issue-28625.rs
ui/issues/issue-28776.rs
ui/issues/issue-28777.rs
ui/issues/issue-28828.rs
ui/issues/issue-28839.rs
ui/issues/issue-28936.rs
Expand Down Expand Up @@ -2063,7 +2062,6 @@ ui/issues/issue-3091.rs
ui/issues/issue-31011.rs
ui/issues/issue-3109.rs
ui/issues/issue-3121.rs
ui/issues/issue-31260.rs
ui/issues/issue-31267-additional.rs
ui/issues/issue-31267.rs
ui/issues/issue-31299.rs
Expand Down Expand Up @@ -2608,7 +2606,6 @@ ui/issues/issue-9243.rs
ui/issues/issue-9249.rs
ui/issues/issue-9259.rs
ui/issues/issue-92741.rs
ui/issues/issue-9382.rs
ui/issues/issue-9446.rs
ui/issues/issue-9719.rs
ui/issues/issue-9725.rs
Expand Down
2 changes: 1 addition & 1 deletion src/tools/tidy/src/ui_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use ignore::Walk;
const ENTRY_LIMIT: u32 = 901;
// FIXME: The following limits should be reduced eventually.

const ISSUES_ENTRY_LIMIT: u32 = 1634;
const ISSUES_ENTRY_LIMIT: u32 = 1631;

const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
"rs", // test source files
Expand Down
20 changes: 20 additions & 0 deletions tests/ui/coercion/struct-coerce-vec-to-slice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! Regression test that ensures struct field literals can be coerced into slice and `Box` types

//@ check-pass

struct Thing1<'a> {
baz: &'a [Box<isize>],
bar: Box<u64>,
}

struct Thing2<'a> {
baz: &'a [Box<isize>],
bar: u64,
}

pub fn main() {
let _a = Thing1 { baz: &[], bar: Box::new(32) };
let _b = Thing1 { baz: &Vec::new(), bar: Box::new(32) };
let _c = Thing2 { baz: &[], bar: 32 };
let _d = Thing2 { baz: &Vec::new(), bar: 32 };
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! Regression test to check that literal expressions in a struct field can be coerced to the
//! expected field type, including block expressions.
//!
//! Issue: <https://github.com/rust-lang/rust/issues/31260>

//@ check-pass

pub struct Struct<K: 'static> {
pub field: K,
}

static STRUCT: Struct<&'static [u8]> = Struct { field: { &[1] } };

static STRUCT2: Struct<&'static [u8]> = Struct { field: &[1] };

fn main() {}
22 changes: 0 additions & 22 deletions tests/ui/issues/issue-28777.rs

This file was deleted.

15 changes: 0 additions & 15 deletions tests/ui/issues/issue-31260.rs

This file was deleted.

37 changes: 0 additions & 37 deletions tests/ui/issues/issue-9382.rs

This file was deleted.

7 changes: 7 additions & 0 deletions tests/ui/lint/inert-attr-macro.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//@ check-pass

#![feature(cfg_boolean_literals)]
#![warn(unused)]

macro_rules! foo {
Expand All @@ -17,4 +18,10 @@ fn main() {
// This does work, since the attribute is on a parent
// of the macro invocation.
#[allow(warnings)] { #[inline] foo!(); }

// Ok, `cfg` and `cfg_attr` are expanded eagerly and do not warn.
#[cfg(true)] foo!();
#[cfg(false)] foo!();
#[cfg_attr(true, cfg(true))] foo!();
#[cfg_attr(false, nonexistent)] foo!();
}
14 changes: 7 additions & 7 deletions tests/ui/lint/inert-attr-macro.stderr
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
warning: unused attribute `inline`
--> $DIR/inert-attr-macro.rs:10:5
--> $DIR/inert-attr-macro.rs:11:5
|
LL | #[inline] foo!();
| ^^^^^^^^^
|
note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo`
--> $DIR/inert-attr-macro.rs:10:15
--> $DIR/inert-attr-macro.rs:11:15
|
LL | #[inline] foo!();
| ^^^
note: the lint level is defined here
--> $DIR/inert-attr-macro.rs:3:9
--> $DIR/inert-attr-macro.rs:4:9
|
LL | #![warn(unused)]
| ^^^^^^
= note: `#[warn(unused_attributes)]` implied by `#[warn(unused)]`

warning: unused attribute `allow`
--> $DIR/inert-attr-macro.rs:14:5
--> $DIR/inert-attr-macro.rs:15:5
|
LL | #[allow(warnings)] #[inline] foo!();
| ^^^^^^^^^^^^^^^^^^
|
note: the built-in attribute `allow` will be ignored, since it's applied to the macro invocation `foo`
--> $DIR/inert-attr-macro.rs:14:34
--> $DIR/inert-attr-macro.rs:15:34
|
LL | #[allow(warnings)] #[inline] foo!();
| ^^^

warning: unused attribute `inline`
--> $DIR/inert-attr-macro.rs:14:24
--> $DIR/inert-attr-macro.rs:15:24
|
LL | #[allow(warnings)] #[inline] foo!();
| ^^^^^^^^^
|
note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo`
--> $DIR/inert-attr-macro.rs:14:34
--> $DIR/inert-attr-macro.rs:15:34
|
LL | #[allow(warnings)] #[inline] foo!();
| ^^^
Expand Down
28 changes: 28 additions & 0 deletions tests/ui/parser/operator-precedence-braces-exprs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! Regression test for ensuring that operator precedence is correctly handled in the presence of
//! braces
//!
//! Issue: <https://github.com/rust-lang/rust/issues/28777>

//@ run-pass

#[allow(unused_braces)]
fn main() {
let v1 = { 1 + { 2 } * { 3 } };
let v2 = 1 + { 2 } * { 3 };

assert_eq!(7, v1);
assert_eq!(7, v2);

let v3;
v3 = { 1 + { 2 } * { 3 } };
let v4;
v4 = 1 + { 2 } * { 3 };
assert_eq!(7, v3);
assert_eq!(7, v4);

let v5 = { 1 + { 2 } * 3 };
assert_eq!(7, v5);

let v9 = { 1 + if 1 > 2 { 1 } else { 2 } * { 3 } };
assert_eq!(7, v9);
}
Loading
Loading