Skip to content

Optimize DST size_of_val, align_of_val, and field projection codegen - #164492

Draft
joshlf wants to merge 1 commit into
rust-lang:mainfrom
joshlf:dst-layout-opt
Draft

joshlf wants to merge 1 commit into
rust-lang:mainfrom
joshlf:dst-layout-opt

Conversation

@joshlf

@joshlf joshlf commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Previously, rustc_codegen_ssa::size_of_val::size_and_align_of_dst (and its counterpart in rustc_codegen_cranelift) used a naive recursive algorithm that simultaneously computed both size and alignment at every level of struct/tuple nesting. This caused several codegen inefficiencies:

  1. Calling size_of_val or align_of_val computed both values and discarded half the work. In Layout::for_value_raw (used when dropping Box<T>, Rc<T>, and Arc<T>), calling size_of_val_raw followed by align_of_val_raw emitted the entire vtable load and alignment-rounding sequence twice (Dropping boxes with unsized tails generates a bunch of duplicate IR #152773).
  2. Nested slice-tailed DSTs emitted O(n) sequential alignment-rounding steps (add, sub, neg, and) instead of folding the layout hierarchy at compile time.
  3. Zero-offset align(1) wrappers around dyn Trait (such as ManuallyDrop<dyn Trait>, UnsafeCell<dyn Trait>, and Cell<dyn Trait>) loaded vtable.align and rounded vtable.size up to vtable.align even though vtable.size is already guaranteed to be a multiple of vtable.align.
  4. PlaceRef::project_field called size_and_align_of_dst and emitted dynamic alignment-rounding IR whenever projecting to any unsized field at a non-zero offset, even for slice-tailed DST fields whose alignment (and therefore field offset) is a compile-time constant.

Replace size_and_align_of_dst with decoupled size_of_dst, align_of_dst, and dst_field_offset routines in rustc_codegen_ssa and rustc_codegen_cranelift:

  • Decouple align_of_dst from size_of_dst:

    • For slice-tailed DSTs ([T], str), layout.align.abi already incorporates the element alignment alongside all outer fields, #[repr(align)], and #[repr(packed)], so align_of_dst returns it as a compile-time constant.
    • For dyn Trait-tailed DSTs, by distributivity of max and min on power-of-two alignments, the alignment of an arbitrarily nested wrapper chain collapses to max(layout.align.abi, min(vtable.align, min_pack)). When min_pack <= layout.align.abi, this is statically layout.align.abi with no vtable load.
  • Distill slice-tailed DSTs into O(1) parameters in size_of_dst:

    • Walk the wrapper chain from the [T]/str tail outward at compile time, folding steps into outer_offset + align_to(base + offset, align) via the identities align_to(c + align_to(x, a1), a2) == align_to(align_to(c, a1) + x, a2) (when a1 <= a2), align_to(c + align_to(x, a1), a2) == align_to(c, a2) + align_to(x, a1) (when a2 < a1), and divisibility by elem_size.
    • Emit at most one mul nuw nsw (omitted when elem_size == 1), one pre-mask add nuw nsw (omitted when the addend is 0), one bitwise and (omitted when elem_size % align == 0), and (only when an outer #[repr(packed)] struct places a dynamically-padded inner DST at an unaligned offset) one post-mask add nuw nsw. When elem_size == 0, fold the entire DST size to a compile-time constant.
    • Because DST sizes fit in isize and isize::MAX + 1 is a multiple of every valid alignment, base + offset + (align - 1) <= isize::MAX, allowing the use of unchecked_suadd (add nuw nsw). For DSTs with a non-zero header, this lets LLVM prove size > 0 and eliminate the dead size == 0 branch before __rust_dealloc in Box::drop, Rc::drop, and Arc::drop.
  • Collapse dyn Trait wrapper chains in size_of_dst:

    • Stream steps from innermost to outermost, skipping inner offset == 0 && align == 1 wrappers (ManuallyDrop<dyn Trait>, UnsafeCell<dyn Trait>, etc.) so size_of_val emits a single vtable.size load (a 2.18x speedup at -O3).
    • Merge adjacent wrappers when prev.align <= cur.align and either cur.offset == 0 && cur.pack == prev.pack or both steps have statically capped alignment (pack <= align).
    • When the innermost step has offset == 1 && align == 1 (e.g. struct S(u8, dyn Trait)), full_align divides vtable.align and thus divides vtable.size, so align_to(1 + vtable.size, full_align) simplifies to vtable.size + full_align without a bitmask.
  • Unify unsized field offset calculation into dst_field_offset:

    • Return None (using the static layout.fields.offset(i)) for all slice-tailed DST fields and for dyn Trait fields whose static offset is already a multiple of min_pack.
    • When dynamic rounding is needed for a dyn Trait field, exploit the fact that offset is already aligned to field.align.abi: when offset == field.align.abi, align_to(offset, effective_align) is effective_align itself; when offset > field.align.abi, all bits below field.align.abi in -offset are already 0, so clamping vtable.align up to field.align.abi before computing offset + (-offset & (align - 1)) is unnecessary.
  • Extend MIR InstSimplify (simplify_size_or_align_of_val):

    • Fold align_of_val on str and single-field unaligned/unpacked wrapper structs and 1-tuples around [T] or str (such as Path, OsStr, and CStr) to align_of::<Elem>() in MIR (a 1.50x speedup on Layout::for_value::<Path> at -O3).

Fixes #152773

Validation: ./x test --stage 1 tests/codegen-llvm tests/mir-opt tests/ui/packed tests/ui/extern tests/ui/dst tests/ui/layout

Agent-Authored-By: AI agent acting on Josh Liebow-Feeser's behalf

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 18, 2026
@joshlf

joshlf commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

@bors try @rust-timer queue

@rust-bors

rust-bors Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

@joshlf: 🔑 Insufficient privileges: not in try users

@rust-timer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@saethlin

Copy link
Copy Markdown
Member

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 18, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Oct 18, 2026
Optimize DST `size_of_val`, `align_of_val`, and field projection codegen
@asquared31415

Copy link
Copy Markdown
Contributor

The use of nuw nsw math in the calculation of user defined DST sizes is likely to regress the quality of the output code. LLVM is liable to emit very large immediate instructions for the and in particular.

@joshlf

joshlf commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

@bors try @rust-timer queue

Thanks @saethlin!

@rust-timer

This comment has been minimized.

@joshlf

joshlf commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

The use of nuw nsw math in the calculation of user defined DST sizes is likely to regress the quality of the output code. LLVM is liable to emit very large immediate instructions for the and in particular.

Ah okay cool thanks for the heads up. Any suggestions for how to do it better?

Previously, `rustc_codegen_ssa::size_of_val::size_and_align_of_dst` (and its
counterpart in `rustc_codegen_cranelift`) used a naive recursive algorithm that
simultaneously computed both size and alignment at every level of struct/tuple
nesting. This caused several codegen inefficiencies:

1. Calling `size_of_val` or `align_of_val` computed both values and discarded
   half the work. In `Layout::for_value_raw` (used when dropping `Box<T>`,
   `Rc<T>`, and `Arc<T>`), calling `size_of_val_raw` followed by
   `align_of_val_raw` emitted the entire vtable load and alignment-rounding
   sequence twice (rust-lang#152773).
2. Nested slice-tailed DSTs emitted `O(n)` sequential alignment-rounding steps
   (`add`, `sub`, `neg`, `and`) instead of folding the layout hierarchy at
   compile time.
3. Zero-offset `align(1)` wrappers around `dyn Trait` (such as
   `ManuallyDrop<dyn Trait>`, `UnsafeCell<dyn Trait>`, and `Cell<dyn Trait>`)
   loaded `vtable.align` and rounded `vtable.size` up to `vtable.align` even
   though `vtable.size` is already guaranteed to be a multiple of
   `vtable.align`.
4. `PlaceRef::project_field` called `size_and_align_of_dst` and emitted dynamic
   alignment-rounding IR whenever projecting to any unsized field at a non-zero
   offset, even for slice-tailed DST fields whose alignment (and therefore field
   offset) is a compile-time constant.

Replace `size_and_align_of_dst` with decoupled `size_of_dst`, `align_of_dst`,
and `dst_field_offset` routines in `rustc_codegen_ssa` and
`rustc_codegen_cranelift`:

- Decouple `align_of_dst` from `size_of_dst`:
  - For slice-tailed DSTs (`[T]`, `str`), `layout.align.abi` already
    incorporates the element alignment alongside all outer fields,
    `#[repr(align)]`, and `#[repr(packed)]`, so `align_of_dst` returns it as a
    compile-time constant.
  - For `dyn Trait`-tailed DSTs, by distributivity of `max` and `min` on
    power-of-two alignments, the alignment of an arbitrarily nested wrapper
    chain collapses to `max(layout.align.abi, min(vtable.align, min_pack))`.
    When `min_pack <= layout.align.abi`, this is statically `layout.align.abi`
    with no vtable load.

- Distill slice-tailed DSTs into `O(1)` parameters in `size_of_dst`:
  - Walk the wrapper chain from the `[T]`/`str` tail outward at compile time,
    folding steps into `outer_offset + align_to(base + offset, align)` via the
    identities `align_to(c + align_to(x, a1), a2) == align_to(align_to(c, a1) +
    x, a2)` (when `a1 <= a2`), `align_to(c + align_to(x, a1), a2) ==
    align_to(c, a2) + align_to(x, a1)` (when `a2 < a1`), and divisibility by
    `elem_size`.
  - Emit at most one `mul nuw nsw` (omitted when `elem_size == 1`), one
    pre-mask `add nuw nsw` (omitted when the addend is 0), one bitwise `and`
    (omitted when `elem_size % align == 0`), and (only when an outer
    `#[repr(packed)]` struct places a dynamically-padded inner DST at an
    unaligned offset) one post-mask `add nuw nsw`. When `elem_size == 0`, fold
    the entire DST size to a compile-time constant.
  - Because DST sizes fit in `isize` and `isize::MAX + 1` is a multiple of every
    valid alignment, `base + offset + (align - 1) <= isize::MAX`, allowing the
    use of `unchecked_suadd` (`add nuw nsw`). For DSTs with a non-zero header,
    this lets LLVM prove `size > 0` and eliminate the dead `size == 0` branch
    before `__rust_dealloc` in `Box::drop`, `Rc::drop`, and `Arc::drop`.

- Collapse `dyn Trait` wrapper chains in `size_of_dst`:
  - Stream steps from innermost to outermost, skipping inner `offset == 0 &&
    align == 1` wrappers (`ManuallyDrop<dyn Trait>`, `UnsafeCell<dyn Trait>`,
    etc.) so `size_of_val` emits a single `vtable.size` load (a 2.18x speedup at
    `-O3`).
  - Merge adjacent wrappers when `prev.align <= cur.align` and either
    `cur.offset == 0 && cur.pack == prev.pack` or both steps have statically
    capped alignment (`pack <= align`).
  - When the innermost step has `offset == 1 && align == 1` (e.g.
    `struct S(u8, dyn Trait)`), `full_align` divides `vtable.align` and thus
    divides `vtable.size`, so `align_to(1 + vtable.size, full_align)` simplifies
    to `vtable.size + full_align` without a bitmask.

- Unify unsized field offset calculation into `dst_field_offset`:
  - Return `None` (using the static `layout.fields.offset(i)`) for all
    slice-tailed DST fields and for `dyn Trait` fields whose static offset is
    already a multiple of `min_pack`.
  - When dynamic rounding is needed for a `dyn Trait` field, exploit the fact
    that `offset` is already aligned to `field.align.abi`: when
    `offset == field.align.abi`, `align_to(offset, effective_align)` is
    `effective_align` itself; when `offset > field.align.abi`, all bits below
    `field.align.abi` in `-offset` are already 0, so clamping `vtable.align` up
    to `field.align.abi` before computing `offset + (-offset & (align - 1))` is
    unnecessary.

- Extend MIR `InstSimplify` (`simplify_size_or_align_of_val`):
  - Fold `align_of_val` on `str` and single-field unaligned/unpacked wrapper
    structs and 1-tuples around `[T]` or `str` (such as `Path`, `OsStr`, and
    `CStr`) to `align_of::<Elem>()` in MIR (a 1.50x speedup on
    `Layout::for_value::<Path>` at `-O3`).

Fixes rust-lang#152773

Validation: ./x test --stage 1 tests/codegen-llvm tests/mir-opt tests/ui/packed tests/ui/extern tests/ui/dst tests/ui/layout

Agent-Authored-By: AI agent acting on Josh Liebow-Feeser's behalf
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job test-pr-check-2 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
   Compiling rustc-std-workspace-alloc v1.99.0 (/checkout/library/rustc-std-workspace-alloc)
   Compiling panic_abort v0.0.0 (/checkout/library/panic_abort)
   Compiling panic_unwind v0.0.0 (/checkout/library/panic_unwind)

thread 'rustc' (100565) panicked at compiler/rustc_codegen_llvm/src/common.rs:326:13:
assertion failed: i < (1 << bit_size)
stack backtrace:
   0:     0x7f4ca2010381 - <<std[617be2ca0a6fd877]::sys::backtrace::BacktraceLock>::print::DisplayBacktrace as core[a373ad73a504971]::fmt::Display>::fmt
   1:     0x7f4ca2056eea - core[a373ad73a504971]::fmt::write
   2:     0x7f4ca2021f1c - <std[617be2ca0a6fd877]::sys::stdio::unix::Stderr as core[a373ad73a504971]::io::write::Write>::write_fmt
   3:     0x7f4ca1fd98e6 - std[617be2ca0a6fd877]::panicking::default_hook::{closure#0}
   4:     0x7f4ca20012f1 - std[617be2ca0a6fd877]::panicking::default_hook
   5:     0x7f4c9d099e96 - std[617be2ca0a6fd877]::panicking::update_hook::<alloc[2e1b2a31b91974c5]::boxed::Box<rustc_driver_impl[e145e1fbc14ad0de]::install_ice_hook::{closure#1}>>::{closure#0}
   6:     0x7f4ca2001652 - std[617be2ca0a6fd877]::panicking::panic_with_hook
   7:     0x7f4ca1fd99c4 - std[617be2ca0a6fd877]::panicking::panic_handler::{closure#0}
   8:     0x7f4ca1fd0f59 - std[617be2ca0a6fd877]::sys::backtrace::__rust_end_short_backtrace::<std[617be2ca0a6fd877]::panicking::panic_handler::{closure#0}, !>
   9:     0x7f4ca1fdb47d - __rustc[ea4f61d10b84890b]::rust_begin_unwind
  10:     0x7f4ca205797c - core[a373ad73a504971]::panicking::panic_fmt
  11:     0x7f4ca2057942 - core[a373ad73a504971]::panicking::panic
  12:     0x7f4c9d638e0f - <rustc_codegen_llvm[9a4fdb25b26a9b7f]::context::GenericCx<rustc_codegen_llvm[9a4fdb25b26a9b7f]::context::FullCx> as rustc_codegen_ssa[1f33ddbf5ecbbf7d]::traits::consts::ConstCodegenMethods>::const_usize
  13:     0x7f4c9d5a808e - rustc_codegen_ssa[1f33ddbf5ecbbf7d]::size_of_val::emit_aligned_static_size::<rustc_codegen_llvm[9a4fdb25b26a9b7f]::builder::GenericBuilder<rustc_codegen_llvm[9a4fdb25b26a9b7f]::context::FullCx>>
  14:     0x7f4c9d5a6e2a - rustc_codegen_ssa[1f33ddbf5ecbbf7d]::size_of_val::size_of_dst::<rustc_codegen_llvm[9a4fdb25b26a9b7f]::builder::GenericBuilder<rustc_codegen_llvm[9a4fdb25b26a9b7f]::context::FullCx>>
  15:     0x7f4c9d43aa3d - <rustc_codegen_ssa[1f33ddbf5ecbbf7d]::mir::FunctionCx<rustc_codegen_llvm[9a4fdb25b26a9b7f]::builder::GenericBuilder<rustc_codegen_llvm[9a4fdb25b26a9b7f]::context::FullCx>>>::codegen_intrinsic_call
  16:     0x7f4c9d44c49f - <rustc_codegen_ssa[1f33ddbf5ecbbf7d]::mir::FunctionCx<rustc_codegen_llvm[9a4fdb25b26a9b7f]::builder::GenericBuilder<rustc_codegen_llvm[9a4fdb25b26a9b7f]::context::FullCx>>>::codegen_call_terminator
  17:     0x7f4c9d4473e0 - <rustc_codegen_ssa[1f33ddbf5ecbbf7d]::mir::FunctionCx<rustc_codegen_llvm[9a4fdb25b26a9b7f]::builder::GenericBuilder<rustc_codegen_llvm[9a4fdb25b26a9b7f]::context::FullCx>>>::codegen_terminator
  18:     0x7f4c9d42c6c3 - rustc_codegen_ssa[1f33ddbf5ecbbf7d]::mir::codegen_mir::<rustc_codegen_llvm[9a4fdb25b26a9b7f]::builder::GenericBuilder<rustc_codegen_llvm[9a4fdb25b26a9b7f]::context::FullCx>>
  19:     0x7f4c9d5aa99a - rustc_codegen_ssa[1f33ddbf5ecbbf7d]::base::codegen_instance::<rustc_codegen_llvm[9a4fdb25b26a9b7f]::builder::GenericBuilder<rustc_codegen_llvm[9a4fdb25b26a9b7f]::context::FullCx>>
  20:     0x7f4c9d542d0a - <rustc_middle[de29a1132a36d7f6]::mono::MonoItem as rustc_codegen_ssa[1f33ddbf5ecbbf7d]::mono_item::MonoItemExt>::define::<rustc_codegen_llvm[9a4fdb25b26a9b7f]::builder::GenericBuilder<rustc_codegen_llvm[9a4fdb25b26a9b7f]::context::FullCx>>
  21:     0x7f4c9d61bca3 - <rustc_codegen_llvm[9a4fdb25b26a9b7f]::back::llvm_backend::ModuleLlvm>::with_module_refs::<(), rustc_codegen_llvm[9a4fdb25b26a9b7f]::base::compile_codegen_unit::module_codegen::{closure#1}>
  22:     0x7f4c9d610c26 - rustc_codegen_llvm[9a4fdb25b26a9b7f]::base::compile_codegen_unit::module_codegen
  23:     0x7f4c9d6054ce - rustc_codegen_llvm[9a4fdb25b26a9b7f]::base::compile_codegen_unit
  24:     0x7f4c9d5aa05e - rustc_codegen_ssa[1f33ddbf5ecbbf7d]::base::codegen_crate::<rustc_codegen_llvm[9a4fdb25b26a9b7f]::back::llvm_backend::LlvmCodegenBackend, rustc_codegen_llvm[9a4fdb25b26a9b7f]::back::llvm_backend::ModuleLlvm>
  25:     0x7f4c9d63a605 - <rustc_codegen_llvm[9a4fdb25b26a9b7f]::back::llvm_backend::LlvmCodegenBackend as rustc_codegen_ssa[1f33ddbf5ecbbf7d]::traits::backend::CodegenBackend>::codegen_crate
  26:     0x7f4c9d308e51 - <rustc_session[a0b3a094c88f22f8]::session::Session>::time::<alloc[2e1b2a31b91974c5]::boxed::Box<dyn core[a373ad73a504971]::any::Any>, rustc_interface[d20ea33b8985951f]::passes::start_codegen::{closure#1}>
  27:     0x7f4c9d2a28c6 - rustc_interface[d20ea33b8985951f]::passes::start_codegen
  28:     0x7f4c9d3000a0 - <rustc_interface[d20ea33b8985951f]::queries::Linker>::codegen_and_build_linker
  29:     0x7f4c9d03e011 - <std[617be2ca0a6fd877]::thread::local::LocalKey<core[a373ad73a504971]::cell::Cell<*const ()>>>::with::<rustc_middle[de29a1132a36d7f6]::ty::context::tls::enter_context<<rustc_middle[de29a1132a36d7f6]::ty::context::GlobalCtxt>::enter<rustc_interface[d20ea33b8985951f]::passes::create_and_enter_global_ctxt<core[a373ad73a504971]::option::Option<rustc_interface[d20ea33b8985951f]::queries::Linker>, rustc_driver_impl[e145e1fbc14ad0de]::compiler_entrypoint::{closure#0}::{closure#1}>::{closure#2}, core[a373ad73a504971]::option::Option<rustc_interface[d20ea33b8985951f]::queries::Linker>>::{closure#1}, core[a373ad73a504971]::option::Option<rustc_interface[d20ea33b8985951f]::queries::Linker>>::{closure#0}, core[a373ad73a504971]::option::Option<rustc_interface[d20ea33b8985951f]::queries::Linker>>
  30:     0x7f4c9cf52c56 - <rustc_middle[de29a1132a36d7f6]::ty::context::TyCtxt>::create_global_ctxt::<core[a373ad73a504971]::option::Option<rustc_interface[d20ea33b8985951f]::queries::Linker>, rustc_interface[d20ea33b8985951f]::passes::create_and_enter_global_ctxt<core[a373ad73a504971]::option::Option<rustc_interface[d20ea33b8985951f]::queries::Linker>, rustc_driver_impl[e145e1fbc14ad0de]::compiler_entrypoint::{closure#0}::{closure#1}>::{closure#2}>
  31:     0x7f4c9d01ca1d - rustc_interface[d20ea33b8985951f]::passes::create_and_enter_global_ctxt::<core[a373ad73a504971]::option::Option<rustc_interface[d20ea33b8985951f]::queries::Linker>, rustc_driver_impl[e145e1fbc14ad0de]::compiler_entrypoint::{closure#0}::{closure#1}>
  32:     0x7f4c9d02b094 - <scoped_tls[91a4e12426fcc402]::ScopedKey<rustc_span[bb918a2c6d7f3a13]::SessionGlobals>>::set::<rustc_interface[d20ea33b8985951f]::util::run_in_thread_with_globals<rustc_interface[d20ea33b8985951f]::util::run_in_thread_pool_with_globals<rustc_interface[d20ea33b8985951f]::interface::run_compiler<(), rustc_driver_impl[e145e1fbc14ad0de]::compiler_entrypoint::{closure#0}>::{closure#2}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}::{closure#0}, ()>
  33:     0x7f4c9d069c3e - rustc_span[bb918a2c6d7f3a13]::create_session_globals_then::<(), rustc_interface[d20ea33b8985951f]::util::run_in_thread_with_globals<rustc_interface[d20ea33b8985951f]::util::run_in_thread_pool_with_globals<rustc_interface[d20ea33b8985951f]::interface::run_compiler<(), rustc_driver_impl[e145e1fbc14ad0de]::compiler_entrypoint::{closure#0}>::{closure#2}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}::{closure#0}>
  34:     0x7f4c9d099818 - std[617be2ca0a6fd877]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[d20ea33b8985951f]::util::run_in_thread_with_globals<rustc_interface[d20ea33b8985951f]::util::run_in_thread_pool_with_globals<rustc_interface[d20ea33b8985951f]::interface::run_compiler<(), rustc_driver_impl[e145e1fbc14ad0de]::compiler_entrypoint::{closure#0}>::{closure#2}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  35:     0x7f4c9d09a54c - <std[617be2ca0a6fd877]::thread::lifecycle::spawn_unchecked<rustc_interface[d20ea33b8985951f]::util::run_in_thread_with_globals<rustc_interface[d20ea33b8985951f]::util::run_in_thread_pool_with_globals<rustc_interface[d20ea33b8985951f]::interface::run_compiler<(), rustc_driver_impl[e145e1fbc14ad0de]::compiler_entrypoint::{closure#0}>::{closure#2}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[a373ad73a504971]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  36:     0x7f4ca200c8bf - <std[617be2ca0a6fd877]::sys::thread::unix::Thread>::new::thread_start
  37:     0x7f4c9ae6ba83 - <unknown>
  38:     0x7f4c9aefd8e0 - <unknown>
  39:                0x0 - <unknown>

error: the compiler unexpectedly panicked. This is a bug
---
warning: the ICE couldn't be written to `/checkout/rustc-ice-2026-10-18T03_40_16-100562.txt`: Read-only file system (os error 30)

note: rustc 1.101.0-nightly (00cb86415 2026-10-18) running on x86_64-unknown-linux-gnu

note: compiler flags: --crate-type lib -Z embed-metadata=no -C opt-level=3 -C embed-bitcode=no -C codegen-units=1 -C embed-bitcode=yes -Z unstable-options -C force-frame-pointers=non-leaf -C debug-assertions=on -Z unstable-options -Z annotate-moves -Z unstable-options -Z macro-backtrace -C split-debuginfo=off -C prefer-dynamic -Z validate-mir -Z mir-opt-level=3 -Z inline-mir -Z inline-mir-preserve-debug -Z mir_strip_debuginfo=locals-in-tiny-functions -Z crate-attr=doc(html_root_url="https://doc.rust-lang.org/nightly/") -Z binary-dep-depinfo -Z force-unstable-if-unmarked

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
end of query stack
---
[RUSTC-TIMING] alloc test:false 5.359
error: could not compile `alloc` (lib)

Caused by:
  process didn't exit successfully: `/checkout/obj/build/bootstrap/debug/rustc /checkout/obj/build/bootstrap/debug/rustc --crate-name alloc --edition=2024 library/alloc/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat,unused-externs-silent --crate-type lib --emit=dep-info,metadata,link -Z embed-metadata=no -C opt-level=3 -C embed-bitcode=no -C codegen-units=1 --warn=unexpected_cfgs --check-cfg 'cfg(no_global_oom_handling)' --check-cfg 'cfg(no_rc)' --check-cfg 'cfg(no_sync)' -Cembed-bitcode=yes -Zunstable-options -Cforce-frame-pointers=non-leaf -C debug-assertions=on --cfg 'feature="compiler-builtins-c"' --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values("compiler-builtins-c", "compiler-builtins-mem", "optimize_for_size"))' -C metadata=f144655d39f20f02 -C extra-filename=-a05844ecbbdcdde4 --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/wasm32-wasip3/dist/build/alloc/a05844ecbbdcdde4/out --target wasm32-wasip3 -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/wasm32-wasip3/dist/build/core/bd8d69429789a567/out -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/dist/build/alloc/a05844ecbbdcdde4/out --extern 'priv:compiler_builtins=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/wasm32-wasip3/dist/build/compiler_builtins/51489e22d834fce3/out/libcompiler_builtins-51489e22d834fce3.rmeta' --extern core=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/wasm32-wasip3/dist/build/core/bd8d69429789a567/out/libcore-bd8d69429789a567.rmeta -Z unstable-options -Zannotate-moves '--check-cfg=cfg(feature,values(any()))' -Zunstable-options -Zmacro-backtrace -Csplit-debuginfo=off -Cprefer-dynamic -Zvalidate-mir -Zmir-opt-level=3 -Zinline-mir -Zinline-mir-preserve-debug -Zmir_strip_debuginfo=locals-in-tiny-functions -Alinker-messages -L native=/wasi-sdk-34.0-x86_64-linux/share/wasi-sysroot/lib/wasm32-wasip3 '-Zcrate-attr=doc(html_root_url="https://doc.rust-lang.org/nightly/")' -Z binary-dep-depinfo --force-warn=unused_crate_dependencies -L native=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/wasm32-wasip3/dist/build/compiler_builtins/a61b0499d123b6d8/out` (exit status: 101)
warning: build failed, waiting for other jobs to finish...
[RUSTC-TIMING] miniz_oxide test:false 0.451
[RUSTC-TIMING] wit_bindgen test:false 0.843
[RUSTC-TIMING] gimli test:false 3.936
Bootstrap failed while executing `test --stage 1 tests/codegen-llvm --target wasm32-wasip3`

@rust-bors

rust-bors Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: dfc3d41 (dfc3d41ae3f9d6fd27dadc3fff8e6d733229b369)
Base parent: 02fb0a1 (02fb0a16311c3411fa373627706da085cd8fbd3c)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (dfc3d41): comparison URL.

Overall result: ✅ improvements - no action needed

Benchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up.

@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.4% [-0.4%, -0.4%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -0.4% [-0.4%, -0.4%] 1

Max RSS (memory usage)

Results (secondary -4.2%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-4.2% [-4.5%, -4.0%] 2
All ❌✅ (primary) - - 0

Cycles

Results (primary 2.5%, secondary 5.5%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
2.5% [2.5%, 2.5%] 1
Regressions ❌
(secondary)
5.5% [2.2%, 8.7%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 2.5% [2.5%, 2.5%] 1

Binary size

Results (primary -0.7%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
0.6% [0.6%, 0.6%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-1.1% [-1.1%, -1.1%] 3
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -0.7% [-1.1%, 0.6%] 4

Bootstrap: 489.75s -> 488.876s (-0.18%)
Artifact size: 409.00 MiB -> 408.96 MiB (-0.01%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 18, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dropping boxes with unsized tails generates a bunch of duplicate IR

6 participants