mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
![]() Don't drop types with no drop glue when building drops for tailcalls this is required as otherwise drops of `&mut` refs count as a usage of a 'two-phase temporary' causing an ICE. fixes #128097 The underlying issue is that the current code generates drops for `&mut` which are later counted as a second use of a two-phase temporary: `bat t.rs -p` ```rust #![expect(incomplete_features)] #![feature(explicit_tail_calls)] fn f(x: &mut ()) { let _y = String::new(); become f(x); } fn main() {} ``` `rustc t.rs -Zdump_mir=f` ```text error: internal compiler error: compiler/rustc_borrowck/src/borrow_set.rs:298:17: found two uses for 2-phase borrow temporary _4: bb2[1] and bb3[0] --> t.rs:6:5 | 6 | become f(x); | ^^^^^^^^^^^ thread 'rustc' panicked at compiler/rustc_borrowck/src/borrow_set.rs:298:17: Box<dyn Any> stack backtrace: [REDACTED] error: aborting due to 1 previous error ``` `bat ./mir_dump/t.f.-------.renumber.0.mir -p -lrust` ```rust // MIR for `f` 0 renumber fn f(_1: &mut ()) -> () { debug x => _1; let mut _0: (); let mut _2: !; let _3: std::string::String; let mut _4: &mut (); scope 1 { debug _y => _3; } bb0: { StorageLive(_3); _3 = String::new() -> [return: bb1, unwind: bb4]; } bb1: { FakeRead(ForLet(None), _3); StorageLive(_4); _4 = &mut (*_1); drop(_3) -> [return: bb2, unwind: bb3]; } bb2: { StorageDead(_3); tailcall f(Spanned { node: move _4, span: t.rs:6:14: 6:15 (#0) }); } bb3 (cleanup): { drop(_4) -> [return: bb4, unwind terminate(cleanup)]; } bb4 (cleanup): { resume; } } ``` Note how `_4 is moved into the tail call in `bb2` and dropped in `bb3`. This PR adds a check that the locals we drop need dropping. r? `@oli-obk` (feel free to reassign, I'm not sure who would be a good reviewer, but thought you might have an idea) cc `@beepster4096,` since you wrote the original drop implementation. |
||
---|---|---|
.. | ||
rustc | ||
rustc_abi | ||
rustc_arena | ||
rustc_ast | ||
rustc_ast_ir | ||
rustc_ast_lowering | ||
rustc_ast_passes | ||
rustc_ast_pretty | ||
rustc_attr_data_structures | ||
rustc_attr_parsing | ||
rustc_baked_icu_data | ||
rustc_borrowck | ||
rustc_builtin_macros | ||
rustc_codegen_cranelift | ||
rustc_codegen_gcc | ||
rustc_codegen_llvm | ||
rustc_codegen_ssa | ||
rustc_const_eval | ||
rustc_data_structures | ||
rustc_driver | ||
rustc_driver_impl | ||
rustc_error_codes | ||
rustc_error_messages | ||
rustc_errors | ||
rustc_expand | ||
rustc_feature | ||
rustc_fluent_macro | ||
rustc_fs_util | ||
rustc_graphviz | ||
rustc_hir | ||
rustc_hir_analysis | ||
rustc_hir_pretty | ||
rustc_hir_typeck | ||
rustc_incremental | ||
rustc_index | ||
rustc_index_macros | ||
rustc_infer | ||
rustc_interface | ||
rustc_lexer | ||
rustc_lint | ||
rustc_lint_defs | ||
rustc_llvm | ||
rustc_log | ||
rustc_macros | ||
rustc_metadata | ||
rustc_middle | ||
rustc_mir_build | ||
rustc_mir_dataflow | ||
rustc_mir_transform | ||
rustc_monomorphize | ||
rustc_next_trait_solver | ||
rustc_parse | ||
rustc_parse_format | ||
rustc_passes | ||
rustc_pattern_analysis | ||
rustc_privacy | ||
rustc_query_impl | ||
rustc_query_system | ||
rustc_resolve | ||
rustc_sanitizers | ||
rustc_serialize | ||
rustc_session | ||
rustc_smir | ||
rustc_span | ||
rustc_symbol_mangling | ||
rustc_target | ||
rustc_trait_selection | ||
rustc_traits | ||
rustc_transmute | ||
rustc_ty_utils | ||
rustc_type_ir | ||
rustc_type_ir_macros | ||
stable_mir |