Skip to content

Commit 8f117dc

Browse files
Rollup merge of rust-lang#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 rust-lang#117733
2 parents b4dee53 + eaaa290 commit 8f117dc

5 files changed

+27
-8
lines changed

compiler/rustc_mir_transform/src/coroutine.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -527,12 +527,26 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
527527
resume_arg
528528
};
529529

530+
let storage_liveness: GrowableBitSet<Local> =
531+
self.storage_liveness[block].clone().unwrap().into();
532+
533+
for i in 0..self.always_live_locals.domain_size() {
534+
let l = Local::new(i);
535+
let needs_storage_dead = storage_liveness.contains(l)
536+
&& !self.remap.contains_key(&l)
537+
&& !self.always_live_locals.contains(l);
538+
if needs_storage_dead {
539+
data.statements
540+
.push(Statement { source_info, kind: StatementKind::StorageDead(l) });
541+
}
542+
}
543+
530544
self.suspension_points.push(SuspensionPoint {
531545
state,
532546
resume,
533547
resume_arg,
534548
drop,
535-
storage_liveness: self.storage_liveness[block].clone().unwrap().into(),
549+
storage_liveness,
536550
});
537551

538552
VariantIdx::new(state)
@@ -1496,13 +1510,6 @@ fn create_cases<'tcx>(
14961510

14971511
// Create StorageLive instructions for locals with live storage
14981512
for i in 0..(body.local_decls.len()) {
1499-
if i == 2 {
1500-
// The resume argument is live on function entry. Don't insert a
1501-
// `StorageLive`, or the following `Assign` will read from uninitialized
1502-
// memory.
1503-
continue;
1504-
}
1505-
15061513
let l = Local::new(i);
15071514
let needs_storage_live = point.storage_liveness.contains(l)
15081515
&& !transform.remap.contains_key(&l)

tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir

+7
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
178178
StorageLive(_20);
179179
_20 = ();
180180
_0 = Poll::<()>::Pending;
181+
StorageDead(_3);
182+
StorageDead(_4);
183+
StorageDead(_19);
184+
StorageDead(_20);
181185
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 3;
182186
return;
183187
}
@@ -276,6 +280,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
276280
StorageLive(_36);
277281
_36 = ();
278282
_0 = Poll::<()>::Pending;
283+
StorageDead(_21);
284+
StorageDead(_35);
285+
StorageDead(_36);
279286
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 4;
280287
return;
281288
}

tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24
5555
StorageLive(_7);
5656
_7 = ();
5757
_0 = CoroutineState::<(), ()>::Yielded(move _7);
58+
StorageDead(_4);
59+
StorageDead(_6);
60+
StorageDead(_7);
5861
discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24}))) = 3;
5962
return;
6063
}

tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
+
9090
+ bb6: {
9191
+ _1 = CoroutineState::<i32, bool>::Yielded(move _8);
92+
+ StorageDead(_8);
9293
+ discriminant((*_6)) = 3;
9394
+ goto -> bb2;
9495
+ }

tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
+
104104
+ bb8: {
105105
+ _1 = CoroutineState::<i32, bool>::Yielded(move _8);
106+
+ StorageDead(_8);
106107
+ discriminant((*_6)) = 3;
107108
+ goto -> bb4;
108109
+ }

0 commit comments

Comments
 (0)