Skip to content

Commit 486bc27

Browse files
committed
Auto merge of rust-lang#127293 - ldm0:ldm_coroutine, r=saethlin
Use `IndexVec` for coroutine local mapping Resolves a old FIXME
2 parents f6fa358 + a9194f3 commit 486bc27

File tree

2 files changed

+21
-19
lines changed

2 files changed

+21
-19
lines changed

compiler/rustc_index/src/vec.rs

+5
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@ impl<I: Idx, T> IndexVec<I, Option<T>> {
208208
pub fn remove(&mut self, index: I) -> Option<T> {
209209
self.get_mut(index)?.take()
210210
}
211+
212+
#[inline]
213+
pub fn contains(&self, index: I) -> bool {
214+
self.get(index).and_then(Option::as_ref).is_some()
215+
}
211216
}
212217

213218
impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> {

compiler/rustc_mir_transform/src/coroutine.rs

+16-19
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use crate::deref_separator::deref_finder;
5858
use crate::errors;
5959
use crate::pass_manager as pm;
6060
use crate::simplify;
61-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
61+
use rustc_data_structures::fx::FxHashSet;
6262
use rustc_errors::pluralize;
6363
use rustc_hir as hir;
6464
use rustc_hir::lang_items::LangItem;
@@ -233,8 +233,7 @@ struct TransformVisitor<'tcx> {
233233
discr_ty: Ty<'tcx>,
234234

235235
// Mapping from Local to (type of local, coroutine struct index)
236-
// FIXME(eddyb) This should use `IndexVec<Local, Option<_>>`.
237-
remap: FxHashMap<Local, (Ty<'tcx>, VariantIdx, FieldIdx)>,
236+
remap: IndexVec<Local, Option<(Ty<'tcx>, VariantIdx, FieldIdx)>>,
238237

239238
// A map from a suspension point in a block to the locals which have live storage at that point
240239
storage_liveness: IndexVec<BasicBlock, Option<BitSet<Local>>>,
@@ -482,7 +481,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
482481
}
483482

484483
fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) {
485-
assert_eq!(self.remap.get(local), None);
484+
assert!(!self.remap.contains(*local));
486485
}
487486

488487
fn visit_place(
@@ -492,7 +491,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
492491
_location: Location,
493492
) {
494493
// Replace an Local in the remap with a coroutine struct access
495-
if let Some(&(ty, variant_index, idx)) = self.remap.get(&place.local) {
494+
if let Some(&Some((ty, variant_index, idx))) = self.remap.get(place.local) {
496495
replace_base(place, self.make_field(variant_index, idx, ty), self.tcx);
497496
}
498497
}
@@ -501,7 +500,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
501500
// Remove StorageLive and StorageDead statements for remapped locals
502501
data.retain_statements(|s| match s.kind {
503502
StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => {
504-
!self.remap.contains_key(&l)
503+
!self.remap.contains(l)
505504
}
506505
_ => true,
507506
});
@@ -526,21 +525,17 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
526525

527526
// The resume arg target location might itself be remapped if its base local is
528527
// live across a yield.
529-
let resume_arg =
530-
if let Some(&(ty, variant, idx)) = self.remap.get(&resume_arg.local) {
531-
replace_base(&mut resume_arg, self.make_field(variant, idx, ty), self.tcx);
532-
resume_arg
533-
} else {
534-
resume_arg
535-
};
528+
if let Some(&Some((ty, variant, idx))) = self.remap.get(resume_arg.local) {
529+
replace_base(&mut resume_arg, self.make_field(variant, idx, ty), self.tcx);
530+
}
536531

537532
let storage_liveness: GrowableBitSet<Local> =
538533
self.storage_liveness[block].clone().unwrap().into();
539534

540535
for i in 0..self.always_live_locals.domain_size() {
541536
let l = Local::new(i);
542537
let needs_storage_dead = storage_liveness.contains(l)
543-
&& !self.remap.contains_key(&l)
538+
&& !self.remap.contains(l)
544539
&& !self.always_live_locals.contains(l);
545540
if needs_storage_dead {
546541
data.statements
@@ -1034,7 +1029,7 @@ fn compute_layout<'tcx>(
10341029
liveness: LivenessInfo,
10351030
body: &Body<'tcx>,
10361031
) -> (
1037-
FxHashMap<Local, (Ty<'tcx>, VariantIdx, FieldIdx)>,
1032+
IndexVec<Local, Option<(Ty<'tcx>, VariantIdx, FieldIdx)>>,
10381033
CoroutineLayout<'tcx>,
10391034
IndexVec<BasicBlock, Option<BitSet<Local>>>,
10401035
) {
@@ -1095,7 +1090,7 @@ fn compute_layout<'tcx>(
10951090
// Create a map from local indices to coroutine struct indices.
10961091
let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> =
10971092
iter::repeat(IndexVec::new()).take(RESERVED_VARIANTS).collect();
1098-
let mut remap = FxHashMap::default();
1093+
let mut remap = IndexVec::from_elem_n(None, saved_locals.domain_size());
10991094
for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() {
11001095
let variant_index = VariantIdx::from(RESERVED_VARIANTS + suspension_point_idx);
11011096
let mut fields = IndexVec::new();
@@ -1106,7 +1101,7 @@ fn compute_layout<'tcx>(
11061101
// around inside coroutines, so it doesn't matter which variant
11071102
// index we access them by.
11081103
let idx = FieldIdx::from_usize(idx);
1109-
remap.entry(locals[saved_local]).or_insert((tys[saved_local].ty, variant_index, idx));
1104+
remap[locals[saved_local]] = Some((tys[saved_local].ty, variant_index, idx));
11101105
}
11111106
variant_fields.push(fields);
11121107
variant_source_info.push(source_info_at_suspension_points[suspension_point_idx]);
@@ -1118,7 +1113,9 @@ fn compute_layout<'tcx>(
11181113
for var in &body.var_debug_info {
11191114
let VarDebugInfoContents::Place(place) = &var.value else { continue };
11201115
let Some(local) = place.as_local() else { continue };
1121-
let Some(&(_, variant, field)) = remap.get(&local) else { continue };
1116+
let Some(&Some((_, variant, field))) = remap.get(local) else {
1117+
continue;
1118+
};
11221119

11231120
let saved_local = variant_fields[variant][field];
11241121
field_names.get_or_insert_with(saved_local, || var.name);
@@ -1521,7 +1518,7 @@ fn create_cases<'tcx>(
15211518
for i in 0..(body.local_decls.len()) {
15221519
let l = Local::new(i);
15231520
let needs_storage_live = point.storage_liveness.contains(l)
1524-
&& !transform.remap.contains_key(&l)
1521+
&& !transform.remap.contains(l)
15251522
&& !transform.always_live_locals.contains(l);
15261523
if needs_storage_live {
15271524
statements

0 commit comments

Comments
 (0)