mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 15:32:06 +00:00
Rollup merge of #118797 - tmiasko:dead-coro, r=davidtwco
End locals' live range before suspending coroutine State transforms retains storage statements for locals that are not stored inside a coroutine. It ensures those locals are live when resuming by inserting StorageLive as appropriate. It forgot to end the storage of those locals when suspending, which is fixed here. While the end of live range is implicit when executing return, it is nevertheless useful for inliner which would otherwise extend the live range beyond return. Fixes #117733
This commit is contained in:
commit
b862e7edce
@ -527,12 +527,26 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
|
||||
resume_arg
|
||||
};
|
||||
|
||||
let storage_liveness: GrowableBitSet<Local> =
|
||||
self.storage_liveness[block].clone().unwrap().into();
|
||||
|
||||
for i in 0..self.always_live_locals.domain_size() {
|
||||
let l = Local::new(i);
|
||||
let needs_storage_dead = storage_liveness.contains(l)
|
||||
&& !self.remap.contains_key(&l)
|
||||
&& !self.always_live_locals.contains(l);
|
||||
if needs_storage_dead {
|
||||
data.statements
|
||||
.push(Statement { source_info, kind: StatementKind::StorageDead(l) });
|
||||
}
|
||||
}
|
||||
|
||||
self.suspension_points.push(SuspensionPoint {
|
||||
state,
|
||||
resume,
|
||||
resume_arg,
|
||||
drop,
|
||||
storage_liveness: self.storage_liveness[block].clone().unwrap().into(),
|
||||
storage_liveness,
|
||||
});
|
||||
|
||||
VariantIdx::new(state)
|
||||
@ -1496,13 +1510,6 @@ fn create_cases<'tcx>(
|
||||
|
||||
// Create StorageLive instructions for locals with live storage
|
||||
for i in 0..(body.local_decls.len()) {
|
||||
if i == 2 {
|
||||
// The resume argument is live on function entry. Don't insert a
|
||||
// `StorageLive`, or the following `Assign` will read from uninitialized
|
||||
// memory.
|
||||
continue;
|
||||
}
|
||||
|
||||
let l = Local::new(i);
|
||||
let needs_storage_live = point.storage_liveness.contains(l)
|
||||
&& !transform.remap.contains_key(&l)
|
||||
|
@ -178,6 +178,10 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
|
||||
StorageLive(_20);
|
||||
_20 = ();
|
||||
_0 = Poll::<()>::Pending;
|
||||
StorageDead(_3);
|
||||
StorageDead(_4);
|
||||
StorageDead(_19);
|
||||
StorageDead(_20);
|
||||
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 3;
|
||||
return;
|
||||
}
|
||||
@ -276,6 +280,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
|
||||
StorageLive(_36);
|
||||
_36 = ();
|
||||
_0 = Poll::<()>::Pending;
|
||||
StorageDead(_21);
|
||||
StorageDead(_35);
|
||||
StorageDead(_36);
|
||||
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 4;
|
||||
return;
|
||||
}
|
||||
|
@ -55,6 +55,9 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24
|
||||
StorageLive(_7);
|
||||
_7 = ();
|
||||
_0 = CoroutineState::<(), ()>::Yielded(move _7);
|
||||
StorageDead(_4);
|
||||
StorageDead(_6);
|
||||
StorageDead(_7);
|
||||
discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24}))) = 3;
|
||||
return;
|
||||
}
|
||||
|
@ -89,6 +89,7 @@
|
||||
+
|
||||
+ bb6: {
|
||||
+ _1 = CoroutineState::<i32, bool>::Yielded(move _8);
|
||||
+ StorageDead(_8);
|
||||
+ discriminant((*_6)) = 3;
|
||||
+ goto -> bb2;
|
||||
+ }
|
||||
|
@ -103,6 +103,7 @@
|
||||
+
|
||||
+ bb8: {
|
||||
+ _1 = CoroutineState::<i32, bool>::Yielded(move _8);
|
||||
+ StorageDead(_8);
|
||||
+ discriminant((*_6)) = 3;
|
||||
+ goto -> bb4;
|
||||
+ }
|
||||
|
Loading…
Reference in New Issue
Block a user