rust/compiler
bors 3c9faa0d03 Auto merge of #148190 - RalfJung:box_new, r=RalfJung
replace box_new with lower-level intrinsics

The `box_new` intrinsic is super special: during THIR construction it turns into an `ExprKind::Box` (formerly known as the `box` keyword), which then during MIR building turns into a special instruction sequence that invokes the exchange_malloc lang item (which has a name from a different time) and a special MIR statement to represent a shallowly-initialized `Box` (which raises [interesting opsem questions](https://github.com/rust-lang/rust/issues/97270)).

This PR is the n-th attempt to get rid of `box_new`. That's non-trivial because it usually causes a perf regression: replacing `box_new` by naive unsafe code will incur extra copies in debug builds, making the resulting binaries a lot slower, and will generate a lot more MIR, making compilation measurably slower. Furthermore, `vec!` is a macro, so the exact code it expands to is highly relevant for borrow checking, type inference, and temporary scopes.

To avoid those problems, this PR does its best to make the MIR almost exactly the same as what it was before. `box_new` is used in two places, `Box::new` and `vec!`:
- For `Box::new` that is fairly easy: the `move_by_value` intrinsic is basically all we need. However, to avoid the extra copy that would usually be generated for the argument of a function call, we need to special-case this intrinsic during MIR building. That's what the first commit does.
- `vec!` is a lot more tricky. As a macro, its details leak to stable code, so almost every variant I tried broke either type inference or the lifetimes of temporaries in some ui test or ended up accepting unsound code due to the borrow checker not enforcing all the constraints I hoped it would enforce. I ended up with a variant that involves a new intrinsic, `fn write_box_via_move<T>(b: Box<MaybeUninit<T>>, x: T) -> Box<MaybeUninit<T>>`, that writes a value into a `Box<MaybeUninit<T>>` and returns that box again. In exchange we can get rid of somewhat similar code in the lowering for `ExprKind::Box`, and the `exchange_malloc` lang item. (We can also get rid of `Rvalue::ShallowInitBox`; I didn't include that in this PR -- I think @cjgillot has a commit for this somewhere [around here](https://github.com/rust-lang/rust/pull/147862/commits).)

See [here](https://github.com/rust-lang/rust/pull/148190#issuecomment-3457454814) for the latest perf numbers. Most of the regressions are in deep-vector which consists entirely of an invocation of `vec!`, so any change to that macro affects this benchmark disproportionally.

This is my first time even looking at MIR building code, so I am very low confidence in that part of the patch, in particular when it comes to scopes and drops and things like that.

I also had do nerf some clippy tests because clippy gets confused by the new expansion of `vec!` so it makes fewer suggestions when `vec!` is involved.

### `vec!` FAQ

- Why does `write_box_via_move` return the `Box` again? Because we need to expand `vec!` to a bunch of method invocations without any blocks or let-statements, or else the temporary scopes (and type inference) don't work out.
- Why is `box_assume_init_into_vec_unsafe` (unsoundly!) a safe function? Because we can't use an unsafe block in `vec!` as that would necessarily also include the `$x` (due to it all being one big method invocation) and therefore interpret the user's code as being inside `unsafe`, which would be bad (and 10 years later, we still don't have safe blocks for macros like this).
- Why does `write_box_via_move` use `Box` as input/output type, and not, say, raw pointers? Because that is the only way to get the correct behavior when `$x` panics or has control effects: we need the `Box` to be dropped in that case. (As a nice side-effect this also makes the intrinsic safe, which is imported as explained in the previous bullet.)
- Can't we make it safe by having `write_box_via_move` return `Box<T>`? Yes we could, but there's no easy way for the intrinsic to convert its `Box<MaybeUninit<T>>` to a `Box<T>`. Transmuting would be unsound as the borrow checker would no longer properly enforce that lifetimes involved in a `vec!` invocation behave correctly.
- Is this macro truly cursed? Yes, yes it is.
2026-02-16 18:46:10 +00:00
..
rustc Return ExitCode from rustc_driver::main 2026-01-23 21:04:27 +00:00
rustc_abi Rollup merge of #152469 - mu001999-contrib:cleanup/unused-features, r=nadrieril,jdonszelmann 2026-02-13 13:34:58 +01:00
rustc_arena Replace some feature(core_intrinsics) with stable hints 2026-02-08 18:21:47 +11:00
rustc_ast Allow provisional mgca syntax of type const <IDENT> = <EXPR> to be reconized. 2026-02-09 07:59:24 -08:00
rustc_ast_ir Implement &pin patterns and ref pin bindings 2025-11-10 09:57:08 +08:00
rustc_ast_lowering Rename inline_fluent! to msg! 2026-02-14 13:47:52 +01:00
rustc_ast_passes feature-gate c-variadic definitions and calls in const contexts 2026-02-15 19:54:25 +01:00
rustc_ast_pretty Allow provisional mgca syntax of type const <IDENT> = <EXPR> to be reconized. 2026-02-09 07:59:24 -08:00
rustc_attr_parsing Port rustc_nonnull_optimization_guaranteed to the new attribute parser 2026-02-16 09:46:04 +01:00
rustc_baked_icu_data Unify the configuration of the compiler docs 2025-11-05 11:25:27 +00:00
rustc_borrowck Rename inline_fluent! to msg! 2026-02-14 13:47:52 +01:00
rustc_builtin_macros Auto merge of #152605 - scottmcm:box-drop-alignment, r=Mark-Simulacrum 2026-02-15 13:38:45 +00:00
rustc_codegen_cranelift Auto merge of #148190 - RalfJung:box_new, r=RalfJung 2026-02-16 18:46:10 +00:00
rustc_codegen_gcc add write_box_via_move intrinsic and use it for vec! 2026-02-16 17:27:40 +01:00
rustc_codegen_llvm Rollup merge of #152132 - folkertdev:carryless-mul, r=Mark-Simulacrum 2026-02-14 23:17:31 -05:00
rustc_codegen_ssa Remove code for ThinLTO from cg_gcc 2026-02-15 10:05:48 +00:00
rustc_const_eval Auto merge of #148190 - RalfJung:box_new, r=RalfJung 2026-02-16 18:46:10 +00:00
rustc_data_structures Auto merge of #152375 - Zoxc:rayon-scope-loops, r=jieyouxu,lqd 2026-02-15 09:55:40 +00:00
rustc_driver Unify the configuration of the compiler docs 2025-11-05 11:25:27 +00:00
rustc_driver_impl Rollup merge of #152250 - JonathanBrouwer:convert_finish, r=jdonszelmann 2026-02-08 19:15:25 +01:00
rustc_error_codes add write_box_via_move intrinsic and use it for vec! 2026-02-16 17:27:40 +01:00
rustc_error_messages Remove SubdiagMessage in favour of the identical DiagMessage 2026-02-10 09:13:45 +00:00
rustc_errors Rename inline_fluent! to msg! 2026-02-14 13:47:52 +01:00
rustc_expand Rollup merge of #152612 - JonathanBrouwer:rename_to_msg, r=jdonszelmann 2026-02-14 18:55:38 +01:00
rustc_feature feature-gate c-variadic definitions and calls in const contexts 2026-02-15 19:54:25 +01:00
rustc_fs_util Avoid using env::temp when linking a binary 2025-12-24 06:41:42 +00:00
rustc_graphviz change non-canonical clone impl to {*self}, fix some doc comments 2025-12-20 13:46:22 +00:00
rustc_hashes some cleanups in compiler 2025-10-12 08:08:30 +00:00
rustc_hir Auto merge of #148190 - RalfJung:box_new, r=RalfJung 2026-02-16 18:46:10 +00:00
rustc_hir_analysis add write_box_via_move intrinsic and use it for vec! 2026-02-16 17:27:40 +01:00
rustc_hir_id
rustc_hir_pretty Allow provisional mgca syntax of type const <IDENT> = <EXPR> to be reconized. 2026-02-09 07:59:24 -08:00
rustc_hir_typeck Auto merge of #148190 - RalfJung:box_new, r=RalfJung 2026-02-16 18:46:10 +00:00
rustc_incremental De-genericize the dep graph. 2026-02-15 13:07:37 +11:00
rustc_index Remove unused features in compiler 2026-02-13 09:25:39 +08:00
rustc_index_macros
rustc_infer Auto merge of #151380 - ShoyuVanilla:shallow-resolve-to-root-var, r=lcnr 2026-02-15 03:04:28 +00:00
rustc_interface Auto merge of #152636 - nnethercote:big-cleanups, r=Zalathar 2026-02-16 04:20:25 +00:00
rustc_lexer Remove rustc_lexer::cursor module. 2026-01-27 12:06:55 +11:00
rustc_lint Port rustc_nonnull_optimization_guaranteed to the new attribute parser 2026-02-16 09:46:04 +01:00
rustc_lint_defs Add FCW for derive helper attributes that will conflict with built-in attributes 2026-02-10 19:39:19 +00:00
rustc_llvm Fix multi-cgu+debug builds using autodiff by delaying autodiff till lto 2026-02-11 14:08:56 -05:00
rustc_log Restrict sysroot crate imports to those defined in this repo. 2025-10-15 13:17:25 +01:00
rustc_macros Remove code for ThinLTO from cg_gcc 2026-02-15 10:05:48 +00:00
rustc_metadata Rename inline_fluent! to msg! 2026-02-14 13:47:52 +01:00
rustc_middle Auto merge of #148190 - RalfJung:box_new, r=RalfJung 2026-02-16 18:46:10 +00:00
rustc_mir_build add helper to project to a field of a place 2026-02-16 17:27:40 +01:00
rustc_mir_dataflow Stabilize assert_matches 2026-02-11 14:13:44 +01:00
rustc_mir_transform Auto merge of #148190 - RalfJung:box_new, r=RalfJung 2026-02-16 18:46:10 +00:00
rustc_monomorphize Rollup merge of #152329 - Zoxc:simple-parallel-macro, r=nnethercote 2026-02-13 15:19:12 +11:00
rustc_next_trait_solver Rollup merge of #152383 - RalfJung:BikeshedGuaranteedNoDrop, r=TaKO8Ki 2026-02-11 13:48:50 +01:00
rustc_parse Rename inline_fluent! to msg! 2026-02-14 13:47:52 +01:00
rustc_parse_format rustc_parse_format: improve diagnostics for unsupported debug = syntax 2026-02-06 00:44:03 +05:30
rustc_passes Port rustc_nonnull_optimization_guaranteed to the new attribute parser 2026-02-16 09:46:04 +01:00
rustc_pattern_analysis Rollup merge of #152469 - mu001999-contrib:cleanup/unused-features, r=nadrieril,jdonszelmann 2026-02-13 13:34:58 +01:00
rustc_privacy Rollup merge of #151887 - scottmcm:homogeneous-try-in-compiler, r=jackh726 2026-02-08 16:58:23 +11:00
rustc_proc_macro Update literal-escaper version to 0.0.7 2026-01-08 14:10:33 +01:00
rustc_public Rollup merge of #150271 - Jamesbarford:chore/refactor-struct-placeholder-pt2, r=lcnr 2026-01-29 17:47:29 +01:00
rustc_public_bridge Remove unused features in compiler 2026-02-13 09:25:39 +08:00
rustc_query_impl Auto merge of #152636 - nnethercote:big-cleanups, r=Zalathar 2026-02-16 04:20:25 +00:00
rustc_query_system Move rustc_query_system::query::dep_graph to rustc_middle. 2026-02-14 18:46:05 +11:00
rustc_resolve Rename inline_fluent! to msg! 2026-02-14 13:47:52 +01:00
rustc_sanitizers Include assoc const projections in CFI trait object 2026-02-01 22:45:43 +08:00
rustc_serialize Remove unused features in compiler 2026-02-13 09:25:39 +08:00
rustc_session Remove code for ThinLTO from cg_gcc 2026-02-15 10:05:48 +00:00
rustc_span Auto merge of #148190 - RalfJung:box_new, r=RalfJung 2026-02-16 18:46:10 +00:00
rustc_symbol_mangling Stabilize assert_matches 2026-02-11 14:13:44 +01:00
rustc_target Rollup merge of #152552 - androm3da:hexagon-hvx-abi-rules, r=madsmtm 2026-02-13 15:19:15 +11:00
rustc_thread_pool Fix typos and grammar in compiler and build documentation 2026-02-10 10:22:05 -05:00
rustc_trait_selection Auto merge of #152636 - nnethercote:big-cleanups, r=Zalathar 2026-02-16 04:20:25 +00:00
rustc_traits implied bounds comments 2026-01-19 16:08:54 +00:00
rustc_transmute Clean up src/dst transmute mess. 2026-01-12 09:22:58 +11:00
rustc_ty_utils add write_box_via_move intrinsic and use it for vec! 2026-02-16 17:27:40 +01:00
rustc_type_ir Auto merge of #151380 - ShoyuVanilla:shallow-resolve-to-root-var, r=lcnr 2026-02-15 03:04:28 +00:00
rustc_type_ir_macros Provide an extended framework for type visit, for use in rust-analyzer 2025-12-16 01:47:28 +02:00
rustc_windows_rc