1
Fork 0

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.
This commit is contained in:
Waffle Lapkin 2025-01-24 06:11:23 +01:00
parent 99768c80a1
commit af2ce8b702
No known key found for this signature in database
10 changed files with 12 additions and 12 deletions

View file

@ -785,6 +785,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let local = let local =
place.as_local().unwrap_or_else(|| bug!("projection in tail call args")); 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 }) Some(DropData { source_info, local, kind: DropKind::Value })
} }
Operand::Constant(_) => None, Operand::Constant(_) => None,
@ -795,6 +799,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.scopes.scopes.iter().rev().nth(1).unwrap().region_scope, self.scopes.scopes.iter().rev().nth(1).unwrap().region_scope,
DUMMY_SP, DUMMY_SP,
); );
let typing_env = self.typing_env();
let unwind_drops = &mut self.scopes.unwind_drops; let unwind_drops = &mut self.scopes.unwind_drops;
// the innermost scope contains only the destructors for the tail call arguments // 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 source_info = drop_data.source_info;
let local = drop_data.local; let local = drop_data.local;
if !self.local_decls[local].ty.needs_drop(self.tcx, typing_env) {
continue;
}
match drop_data.kind { match drop_data.kind {
DropKind::Value => { DropKind::Value => {
// `unwind_to` should drop the value that we're about to // `unwind_to` should drop the value that we're about to

View file

@ -66,7 +66,6 @@
bb6: { bb6: {
+ _8 = const false; + _8 = const false;
StorageDead(_4); StorageDead(_4);
StorageDead(_3);
drop(_2) -> [return: bb7, unwind: bb12]; drop(_2) -> [return: bb7, unwind: bb12];
} }

View file

@ -66,7 +66,6 @@
bb6: { bb6: {
+ _8 = const false; + _8 = const false;
StorageDead(_4); StorageDead(_4);
StorageDead(_3);
- drop(_2) -> [return: bb7, unwind continue]; - drop(_2) -> [return: bb7, unwind continue];
+ drop(_2) -> [return: bb7, unwind: bb12]; + drop(_2) -> [return: bb7, unwind: bb12];
} }

View file

@ -63,7 +63,6 @@ fn f() -> () {
bb6: { bb6: {
StorageDead(_4); StorageDead(_4);
StorageDead(_3);
drop(_2) -> [return: bb7, unwind: bb17]; drop(_2) -> [return: bb7, unwind: bb17];
} }

View file

@ -63,7 +63,6 @@ fn f() -> () {
bb6: { bb6: {
StorageDead(_4); StorageDead(_4);
StorageDead(_3);
drop(_2) -> [return: bb7, unwind: bb17]; drop(_2) -> [return: bb7, unwind: bb17];
} }

View file

@ -80,7 +80,6 @@
bb8: { bb8: {
+ _12 = const false; + _12 = const false;
StorageDead(_6); StorageDead(_6);
StorageDead(_5);
drop(_4) -> [return: bb9, unwind: bb16]; drop(_4) -> [return: bb9, unwind: bb16];
} }

View file

@ -80,7 +80,6 @@
bb8: { bb8: {
+ _12 = const false; + _12 = const false;
StorageDead(_6); StorageDead(_6);
StorageDead(_5);
drop(_4) -> [return: bb9, unwind: bb16]; drop(_4) -> [return: bb9, unwind: bb16];
} }

View file

@ -77,7 +77,6 @@ fn f_with_arg(_1: String, _2: String) -> () {
bb8: { bb8: {
StorageDead(_6); StorageDead(_6);
StorageDead(_5);
drop(_4) -> [return: bb9, unwind: bb23]; drop(_4) -> [return: bb9, unwind: bb23];
} }

View file

@ -77,7 +77,6 @@ fn f_with_arg(_1: String, _2: String) -> () {
bb8: { bb8: {
StorageDead(_6); StorageDead(_6);
StorageDead(_5);
drop(_4) -> [return: bb9, unwind: bb23]; drop(_4) -> [return: bb9, unwind: bb23];
} }

View file

@ -4,10 +4,9 @@ error[E0597]: `local` does not live long enough
LL | let local = Type; LL | let local = Type;
| ----- binding `local` declared here | ----- binding `local` declared here
LL | become takes_borrow(&local); LL | become takes_borrow(&local);
| ^^^^^^ borrowed value does not live long enough | ^^^^^^- `local` dropped here while still borrowed
LL | | |
LL | } | borrowed value does not live long enough
| - `local` dropped here while still borrowed
error: aborting due to 1 previous error error: aborting due to 1 previous error