diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index db2d752cfde..cddf4f6f399 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -372,6 +372,7 @@ extern "Rust" { #[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")] #[cfg(all(not(no_global_oom_handling), not(test)))] #[cold] +#[optimize(size)] pub const fn handle_alloc_error(layout: Layout) -> ! { const fn ct_error(_: Layout) -> ! { panic!("allocation failed"); diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 3e44adf73f0..856cb2b54f4 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -185,6 +185,7 @@ #![feature(multiple_supertrait_upcastable)] #![feature(negative_impls)] #![feature(never_type)] +#![feature(optimize_attribute)] #![feature(rustc_allow_const_fn_unstable)] #![feature(rustc_attrs)] #![feature(slice_internals)] diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 9c8fa7ceff4..a651ba067e4 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -782,6 +782,7 @@ where // Central function for reserve error handling. #[cfg(not(no_global_oom_handling))] #[cold] +#[optimize(size)] fn handle_error(e: TryReserveError) -> ! { match e.kind() { CapacityOverflow => capacity_overflow(), diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index b4e0bc5fcbe..bafd5579644 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1520,6 +1520,7 @@ impl Vec { #[cold] #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[track_caller] + #[optimize(size)] fn assert_failed(index: usize, len: usize) -> ! { panic!("swap_remove index (is {index}) should be < len (is {len})"); } @@ -1568,6 +1569,7 @@ impl Vec { #[cold] #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[track_caller] + #[optimize(size)] fn assert_failed(index: usize, len: usize) -> ! { panic!("insertion index (is {index}) should be <= len (is {len})"); } @@ -1630,6 +1632,7 @@ impl Vec { #[cold] #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[track_caller] + #[optimize(size)] fn assert_failed(index: usize, len: usize) -> ! { panic!("removal index (is {index}) should be < len (is {len})"); } @@ -2318,6 +2321,7 @@ impl Vec { #[cold] #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[track_caller] + #[optimize(size)] fn assert_failed(at: usize, len: usize) -> ! { panic!("`at` split index (is {at}) should be <= len (is {len})"); } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 07daa32afa8..997cea03334 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -233,6 +233,7 @@ #![feature(never_type)] #![feature(no_core)] #![feature(no_sanitize)] +#![feature(optimize_attribute)] #![feature(prelude_import)] #![feature(repr_simd)] #![feature(rustc_allow_const_fn_unstable)] diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 7affe638257..e4a62304087 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -264,7 +264,7 @@ pub const fn panic_display(x: &T) -> ! { panic_fmt(format_args!("{}", *x)); } -#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] #[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access @@ -276,7 +276,7 @@ fn panic_bounds_check(index: usize, len: usize) -> ! { panic!("index out of bounds: the len is {len} but the index is {index}") } -#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] #[lang = "panic_misaligned_pointer_dereference"] // needed by codegen for panic on misaligned pointer deref @@ -301,7 +301,7 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! { /// /// This function is called directly by the codegen backend, and must not have /// any extra arguments (including those synthesized by track_caller). -#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[lang = "panic_cannot_unwind"] // needed by codegen for panic in nounwind function #[rustc_nounwind] @@ -317,7 +317,7 @@ fn panic_cannot_unwind() -> ! { /// /// This function is called directly by the codegen backend, and must not have /// any extra arguments (including those synthesized by track_caller). -#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[lang = "panic_in_cleanup"] // needed by codegen for panic in nounwind function #[rustc_nounwind] @@ -350,7 +350,7 @@ pub enum AssertKind { } /// Internal function for `assert_eq!` and `assert_ne!` macros -#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] #[doc(hidden)] @@ -368,7 +368,7 @@ where } /// Internal function for `assert_match!` -#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] #[doc(hidden)] @@ -388,7 +388,7 @@ pub fn assert_matches_failed( } /// Non-generic version of the above functions, to avoid code bloat. -#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] fn assert_failed_inner( diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 93a74ef739b..cae84fa88ac 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -306,10 +306,12 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(no_sanitize)] +#![feature(optimize_attribute)] #![feature(prelude_import)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(staged_api)] +#![feature(stmt_expr_attributes)] #![feature(thread_local)] #![feature(try_blocks)] #![feature(type_alias_impl_trait)] diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index e818b448270..b420445807f 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -231,6 +231,7 @@ where } /// The default panic handler. +#[optimize(size)] fn default_hook(info: &PanicHookInfo<'_>) { // If this is a double panic, make sure that we print a backtrace // for this panic. Otherwise only print it if logging is enabled. @@ -249,7 +250,8 @@ fn default_hook(info: &PanicHookInfo<'_>) { let thread = thread::try_current(); let name = thread.as_ref().and_then(|t| t.name()).unwrap_or(""); - let write = |err: &mut dyn crate::io::Write| { + let write = #[optimize(size)] + |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(); @@ -527,6 +529,7 @@ pub unsafe fn r#try R>(f: F) -> Result> // optimizer (in most cases this function is not inlined even as a normal, // non-cold function, though, as of the writing of this comment). #[cold] + #[optimize(size)] unsafe fn cleanup(payload: *mut u8) -> Box { // SAFETY: The whole unsafe block hinges on a correct implementation of // the panic handler `__rust_panic_cleanup`. As such we can only @@ -686,7 +689,7 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { // lang item for CTFE panic support // never inline unless panic_immediate_abort to avoid code // bloat at the call sites as much as possible -#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] #[rustc_do_not_const_check] // hooked by const-eval @@ -756,6 +759,7 @@ fn payload_as_str(payload: &dyn Any) -> &str { /// Executes the primary logic for a panic, including checking for recursive /// panics, panic hooks, and finally dispatching to the panic runtime to either /// abort or unwind. +#[optimize(size)] fn rust_panic_with_hook( payload: &mut dyn PanicPayload, location: &Location<'_>, diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index 56cf877ddc6..a51e5c1b76b 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -498,6 +498,7 @@ impl OnceLock { } #[cold] + #[optimize(size)] fn initialize(&self, f: F) -> Result<(), E> where F: FnOnce() -> Result,