From af2ce8b7022c92de0702bea09f2fb50b80343d2d Mon Sep 17 00:00:00 2001 From: Waffle Lapkin <waffle.lapkin@gmail.com> Date: Fri, 24 Jan 2025 06:11:23 +0100 Subject: [PATCH] don't drop types with no drop glue when tailcalling this is required as otherwise drops of `&mut` refs count as a usage of a 'two-phase temporary' causing an ICE. --- compiler/rustc_mir_build/src/builder/scope.rs | 9 +++++++++ .../tail_call_drops.f.ElaborateDrops.panic-abort.diff | 1 - .../tail_call_drops.f.ElaborateDrops.panic-unwind.diff | 1 - .../tail_call_drops.f.built.after.panic-abort.mir | 1 - .../tail_call_drops.f.built.after.panic-unwind.mir | 1 - ...call_drops.f_with_arg.ElaborateDrops.panic-abort.diff | 1 - ...all_drops.f_with_arg.ElaborateDrops.panic-unwind.diff | 1 - ...ail_call_drops.f_with_arg.built.after.panic-abort.mir | 1 - ...il_call_drops.f_with_arg.built.after.panic-unwind.mir | 1 - tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr | 7 +++---- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 20441530a47..945f02821d9 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -785,6 +785,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let local = place.as_local().unwrap_or_else(|| bug!("projection in tail call args")); + if !self.local_decls[local].ty.needs_drop(self.tcx, self.typing_env()) { + return None; + } + Some(DropData { source_info, local, kind: DropKind::Value }) } Operand::Constant(_) => None, @@ -795,6 +799,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.scopes.scopes.iter().rev().nth(1).unwrap().region_scope, DUMMY_SP, ); + let typing_env = self.typing_env(); let unwind_drops = &mut self.scopes.unwind_drops; // the innermost scope contains only the destructors for the tail call arguments @@ -805,6 +810,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let source_info = drop_data.source_info; let local = drop_data.local; + if !self.local_decls[local].ty.needs_drop(self.tcx, typing_env) { + continue; + } + match drop_data.kind { DropKind::Value => { // `unwind_to` should drop the value that we're about to diff --git a/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff index 17c64d4baf0..9a4f27a497d 100644 --- a/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff +++ b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff @@ -66,7 +66,6 @@ bb6: { + _8 = const false; StorageDead(_4); - StorageDead(_3); drop(_2) -> [return: bb7, unwind: bb12]; } diff --git a/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff index 58d8a87986d..f13ee78aa36 100644 --- a/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff +++ b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff @@ -66,7 +66,6 @@ bb6: { + _8 = const false; StorageDead(_4); - StorageDead(_3); - drop(_2) -> [return: bb7, unwind continue]; + drop(_2) -> [return: bb7, unwind: bb12]; } diff --git a/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir b/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir index 2c3d62491d7..e017424a4cc 100644 --- a/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir +++ b/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir @@ -63,7 +63,6 @@ fn f() -> () { bb6: { StorageDead(_4); - StorageDead(_3); drop(_2) -> [return: bb7, unwind: bb17]; } diff --git a/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir b/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir index 2c3d62491d7..e017424a4cc 100644 --- a/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir +++ b/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir @@ -63,7 +63,6 @@ fn f() -> () { bb6: { StorageDead(_4); - StorageDead(_3); drop(_2) -> [return: bb7, unwind: bb17]; } diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff index 1a51601bc56..a8c57d2cfe0 100644 --- a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff +++ b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff @@ -80,7 +80,6 @@ bb8: { + _12 = const false; StorageDead(_6); - StorageDead(_5); drop(_4) -> [return: bb9, unwind: bb16]; } diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff index 1a51601bc56..a8c57d2cfe0 100644 --- a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff +++ b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff @@ -80,7 +80,6 @@ bb8: { + _12 = const false; StorageDead(_6); - StorageDead(_5); drop(_4) -> [return: bb9, unwind: bb16]; } diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir index 744f1989acc..f89b98a3205 100644 --- a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir +++ b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir @@ -77,7 +77,6 @@ fn f_with_arg(_1: String, _2: String) -> () { bb8: { StorageDead(_6); - StorageDead(_5); drop(_4) -> [return: bb9, unwind: bb23]; } diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir index 744f1989acc..f89b98a3205 100644 --- a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir +++ b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir @@ -77,7 +77,6 @@ fn f_with_arg(_1: String, _2: String) -> () { bb8: { StorageDead(_6); - StorageDead(_5); drop(_4) -> [return: bb9, unwind: bb23]; } diff --git a/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr b/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr index 75fb13c378c..ece581dc626 100644 --- a/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr +++ b/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr @@ -4,10 +4,9 @@ error[E0597]: `local` does not live long enough LL | let local = Type; | ----- binding `local` declared here LL | become takes_borrow(&local); - | ^^^^^^ borrowed value does not live long enough -LL | -LL | } - | - `local` dropped here while still borrowed + | ^^^^^^- `local` dropped here while still borrowed + | | + | borrowed value does not live long enough error: aborting due to 1 previous error