From 2a0cd874a977bbe49077ca0e46805ed6201d7d30 Mon Sep 17 00:00:00 2001 From: Berrysoft Date: Wed, 12 Mar 2025 17:50:02 +0800 Subject: [PATCH 1/7] Add stack overflow handler for cygwin --- .../std/src/sys/pal/unix/stack_overflow.rs | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index 0ecccdc8812dd..4bd0cedd44ccb 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -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 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(""); + 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) {} +} From 244e92ba5c6e8031da1471229151abd44f383eb9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Mar 2025 10:33:47 +0100 Subject: [PATCH 2/7] catch_unwind intrinsic: document return value --- library/core/src/intrinsics/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index cf03c07b6a564..81e59a1f349ec 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3002,6 +3002,7 @@ pub const fn discriminant_value(v: &T) -> ::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. /// From 2c77a0775c8e398296b14798504f40c968eaf55d Mon Sep 17 00:00:00 2001 From: Karol Zwolak Date: Fri, 21 Mar 2025 12:36:01 +0100 Subject: [PATCH 3/7] test(ui): add tuple-struct-where-clause-suggestion ui test for #91520 --- ...le-struct-where-clause-suggestion-91520.rs | 17 +++++++++++++++ ...truct-where-clause-suggestion-91520.stderr | 21 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.rs create mode 100644 tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.stderr diff --git a/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.rs b/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.rs new file mode 100644 index 0000000000000..b7086325d5f88 --- /dev/null +++ b/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.rs @@ -0,0 +1,17 @@ +// Verify that the `where` clause suggestion is in the correct place +// Previously, the suggestion to add `where` clause was placed inside the derive +// like `#[derive(Clone where Inner: Clone)]` +// instead of `struct Outer(Inner) where Inner: Clone` + +#![crate_type = "lib"] + +struct Inner(T); +//~^ HELP consider annotating `Inner` with `#[derive(Clone)]` +impl Clone for Inner<()> { + fn clone(&self) -> Self { todo!() } +} + +#[derive(Clone)] +struct Outer(Inner); +//~^ ERROR the trait bound `Inner: Clone` is not satisfied [E0277] +//~| HELP consider introducing a `where` clause diff --git a/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.stderr b/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.stderr new file mode 100644 index 0000000000000..577b090ce1b4f --- /dev/null +++ b/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `Inner: Clone` is not satisfied + --> $DIR/tuple-struct-where-clause-suggestion-91520.rs:15:17 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct Outer(Inner); + | ^^^^^^^^ the trait `Clone` is not implemented for `Inner` + | +help: consider annotating `Inner` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct Inner(T); + | +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | struct Outer(Inner) where Inner: Clone; + | +++++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 0ac2801f25335b017da63f3bff1c2b46a39ee12d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 21 Mar 2025 18:14:27 +0300 Subject: [PATCH 4/7] expand: Do not report `cfg_attr` traces on macros as unused attributes --- compiler/rustc_expand/src/expand.rs | 2 +- tests/ui/lint/inert-attr-macro.rs | 7 +++++++ tests/ui/lint/inert-attr-macro.stderr | 14 +++++++------- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 87f01be26c25e..e2a557528504a 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -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, diff --git a/tests/ui/lint/inert-attr-macro.rs b/tests/ui/lint/inert-attr-macro.rs index 90303a1fc3d1c..5d4133d6c7748 100644 --- a/tests/ui/lint/inert-attr-macro.rs +++ b/tests/ui/lint/inert-attr-macro.rs @@ -1,5 +1,6 @@ //@ check-pass +#![feature(cfg_boolean_literals)] #![warn(unused)] macro_rules! foo { @@ -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!(); } diff --git a/tests/ui/lint/inert-attr-macro.stderr b/tests/ui/lint/inert-attr-macro.stderr index 5ccb4ffe79298..b85b0319e7126 100644 --- a/tests/ui/lint/inert-attr-macro.stderr +++ b/tests/ui/lint/inert-attr-macro.stderr @@ -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!(); | ^^^ From eb2a2f86bb7b018afaabb1b42d55086470780bfa Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 21 Mar 2025 20:51:06 +0000 Subject: [PATCH 5/7] Allow inlining for `Atomic*::from_ptr` Currently this cannot be inlined, which among other things means it can't be used in `compiler-builtins` [1]. These are trivial functions that should be inlineable, so add `#[inline]`. [1]: https://github.com/rust-lang/compiler-builtins/pull/790#issuecomment-2744371738 --- library/core/src/sync/atomic.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 88bee62203101..9b1b13e7129ee 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -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 AtomicPtr { /// /// [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 { @@ -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 { From f0c0862a2b7734a4bc222d8ab88a5a12cce291d7 Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 21 Mar 2025 15:05:35 -0500 Subject: [PATCH 6/7] triagebot: add autolabel rules for D-* and L-* fixes #138565 --- triagebot.toml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 293ad259910fd..c3ed32ce09e36 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -308,6 +308,23 @@ exclude_labels = [ "T-*", ] +trigger_labels = [ + "D-*", + "A-diagnostics", +] + +[autolabel."A-diagnostics"] + +trigger_labels = [ + "D-*", +] + +[autolabel."A-lints"] + +trigger_labels = [ + "L-*", +] + [autolabel."T-libs"] trigger_files = [ "library/alloc", From 5e6b4592d2da0df6b4a83695fd30d232bc7eb902 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 17 Mar 2025 21:40:20 -0600 Subject: [PATCH 7/7] cleaned and organized 3 tests in `./tests/ui/issues` --- src/tools/tidy/src/issues.txt | 3 -- src/tools/tidy/src/ui_tests.rs | 2 +- .../ui/coercion/struct-coerce-vec-to-slice.rs | 20 ++++++++++ ...al-field-type-coercion-to-expected-type.rs | 16 ++++++++ tests/ui/issues/issue-28777.rs | 22 ----------- tests/ui/issues/issue-31260.rs | 15 -------- tests/ui/issues/issue-9382.rs | 37 ------------------- .../operator-precedence-braces-exprs.rs | 28 ++++++++++++++ 8 files changed, 65 insertions(+), 78 deletions(-) create mode 100644 tests/ui/coercion/struct-coerce-vec-to-slice.rs create mode 100644 tests/ui/coercion/struct-literal-field-type-coercion-to-expected-type.rs delete mode 100644 tests/ui/issues/issue-28777.rs delete mode 100644 tests/ui/issues/issue-31260.rs delete mode 100644 tests/ui/issues/issue-9382.rs create mode 100644 tests/ui/parser/operator-precedence-braces-exprs.rs diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 2b9ae19547856..4a929a376d782 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -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 @@ -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 @@ -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 diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index fe51231c48100..61728d0553fde 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -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 diff --git a/tests/ui/coercion/struct-coerce-vec-to-slice.rs b/tests/ui/coercion/struct-coerce-vec-to-slice.rs new file mode 100644 index 0000000000000..9ef20ac4ea630 --- /dev/null +++ b/tests/ui/coercion/struct-coerce-vec-to-slice.rs @@ -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], + bar: Box, +} + +struct Thing2<'a> { + baz: &'a [Box], + 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 }; +} diff --git a/tests/ui/coercion/struct-literal-field-type-coercion-to-expected-type.rs b/tests/ui/coercion/struct-literal-field-type-coercion-to-expected-type.rs new file mode 100644 index 0000000000000..0b8ec7dc07a73 --- /dev/null +++ b/tests/ui/coercion/struct-literal-field-type-coercion-to-expected-type.rs @@ -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: + +//@ check-pass + +pub struct Struct { + pub field: K, +} + +static STRUCT: Struct<&'static [u8]> = Struct { field: { &[1] } }; + +static STRUCT2: Struct<&'static [u8]> = Struct { field: &[1] }; + +fn main() {} diff --git a/tests/ui/issues/issue-28777.rs b/tests/ui/issues/issue-28777.rs deleted file mode 100644 index f67e11e369466..0000000000000 --- a/tests/ui/issues/issue-28777.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ 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); -} diff --git a/tests/ui/issues/issue-31260.rs b/tests/ui/issues/issue-31260.rs deleted file mode 100644 index 5e9fffb195c64..0000000000000 --- a/tests/ui/issues/issue-31260.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -pub struct Struct { - pub field: K, -} - -static STRUCT: Struct<&'static [u8]> = Struct { - field: {&[1]} -}; - -static STRUCT2: Struct<&'static [u8]> = Struct { - field: &[1] -}; - -fn main() {} diff --git a/tests/ui/issues/issue-9382.rs b/tests/ui/issues/issue-9382.rs deleted file mode 100644 index 27f9ab577437f..0000000000000 --- a/tests/ui/issues/issue-9382.rs +++ /dev/null @@ -1,37 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -// Tests for a previous bug that occurred due to an interaction -// between struct field initialization and the auto-coercion -// from a vector to a slice. The drop glue was being invoked on -// the temporary slice with a wrong type, triggering an LLVM assert. - - -struct Thing1<'a> { - baz: &'a [Box], - bar: Box, -} - -struct Thing2<'a> { - baz: &'a [Box], - bar: u64, -} - -pub fn main() { - let _t1_fixed = Thing1 { - baz: &[], - bar: Box::new(32), - }; - Thing1 { - baz: &Vec::new(), - bar: Box::new(32), - }; - let _t2_fixed = Thing2 { - baz: &[], - bar: 32, - }; - Thing2 { - baz: &Vec::new(), - bar: 32, - }; -} diff --git a/tests/ui/parser/operator-precedence-braces-exprs.rs b/tests/ui/parser/operator-precedence-braces-exprs.rs new file mode 100644 index 0000000000000..d6f44ef879ce8 --- /dev/null +++ b/tests/ui/parser/operator-precedence-braces-exprs.rs @@ -0,0 +1,28 @@ +//! Regression test for ensuring that operator precedence is correctly handled in the presence of +//! braces +//! +//! Issue: + +//@ 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); +}