From cb76e42b05bde0c5ef3b596412002bceee3d185f Mon Sep 17 00:00:00 2001 From: kotauskas Date: Thu, 20 Nov 2025 15:47:15 +0300 Subject: [PATCH 1/4] Disable inlining of packed `io::Error` destructor --- library/std/src/io/error/repr_bitpacked.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs index 716da37168d01..7b2980263d1b1 100644 --- a/library/std/src/io/error/repr_bitpacked.rs +++ b/library/std/src/io/error/repr_bitpacked.rs @@ -235,7 +235,13 @@ impl Repr { } impl Drop for Repr { - #[inline] + // This was #[inline] previously. Inlining the destructor of ErrorData is in + // no way helpful in real programs (as the source of the error will not be + // inlined, so there will not be any match assumptions to gain). The cost, + // meanwhile, is a code size increase by a factor of up to 5.4 in the case + // of dropping multiple io::Results in the same function + // (https://godbolt.org/z/8hfGchjsT). + #[inline(never)] fn drop(&mut self) { // Safety: We're a Repr, decode_repr is fine. The `Box::from_raw` is // safe because we're being dropped. From 09a34c801fad6f7566beb8c4afbd0e7766640dac Mon Sep 17 00:00:00 2001 From: kotauskas Date: Sun, 4 Jan 2026 02:39:23 +0300 Subject: [PATCH 2/4] Soft-disable `io::Error` destructor inlining --- library/std/src/io/error/repr_bitpacked.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs index 7b2980263d1b1..556a6177e0868 100644 --- a/library/std/src/io/error/repr_bitpacked.rs +++ b/library/std/src/io/error/repr_bitpacked.rs @@ -241,7 +241,6 @@ impl Drop for Repr { // meanwhile, is a code size increase by a factor of up to 5.4 in the case // of dropping multiple io::Results in the same function // (https://godbolt.org/z/8hfGchjsT). - #[inline(never)] fn drop(&mut self) { // Safety: We're a Repr, decode_repr is fine. The `Box::from_raw` is // safe because we're being dropped. From cc2a6812e3c1b4ac410c73472f04d408aa4a7e14 Mon Sep 17 00:00:00 2001 From: kotauskas Date: Sun, 4 Jan 2026 16:29:03 +0300 Subject: [PATCH 3/4] Revert `io::Error` destructor to `#[inline(never)]` perf run: https://perf.rust-lang.org/compare.html?start=f280e764d51976d62da12033ddcbf72d0076a969&end=2263b424045c4752a7f2c143e498337a87ee306d&stat=instructions:u Removing `#[inline(never)]` seems to place it in a neither-here-nor-there state that fails to reduce code size. --- library/std/src/io/error/repr_bitpacked.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs index 556a6177e0868..7b2980263d1b1 100644 --- a/library/std/src/io/error/repr_bitpacked.rs +++ b/library/std/src/io/error/repr_bitpacked.rs @@ -241,6 +241,7 @@ impl Drop for Repr { // meanwhile, is a code size increase by a factor of up to 5.4 in the case // of dropping multiple io::Results in the same function // (https://godbolt.org/z/8hfGchjsT). + #[inline(never)] fn drop(&mut self) { // Safety: We're a Repr, decode_repr is fine. The `Box::from_raw` is // safe because we're being dropped. From 646ad315ea428eae01918b6111e5f8e5aeae55ee Mon Sep 17 00:00:00 2001 From: kotauskas Date: Mon, 5 Jan 2026 14:25:32 +0300 Subject: [PATCH 4/4] Add `FIXME` to `io::Error` destructor --- library/std/src/io/error/repr_bitpacked.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs index 7b2980263d1b1..8f6bb8d097e46 100644 --- a/library/std/src/io/error/repr_bitpacked.rs +++ b/library/std/src/io/error/repr_bitpacked.rs @@ -241,6 +241,10 @@ impl Drop for Repr { // meanwhile, is a code size increase by a factor of up to 5.4 in the case // of dropping multiple io::Results in the same function // (https://godbolt.org/z/8hfGchjsT). + // + // FIXME this is not the optimal place for this hint (notably, we cannot + // apply it to the 32-bit variant). See the discussion in + // https://github.com/rust-lang/rust/pull/149146 #[inline(never)] fn drop(&mut self) { // Safety: We're a Repr, decode_repr is fine. The `Box::from_raw` is