|
52 | 52 |
|
53 | 53 | mod by_move_body; |
54 | 54 | mod drop; |
55 | | -use std::{iter, ops}; |
| 55 | +use std::ops; |
56 | 56 |
|
57 | 57 | pub(super) use by_move_body::coroutine_by_move_body_def_id; |
58 | 58 | use drop::{ |
59 | 59 | cleanup_async_drops, create_coroutine_drop_shim, create_coroutine_drop_shim_async, |
60 | 60 | create_coroutine_drop_shim_proxy_async, elaborate_coroutine_drops, expand_async_drops, |
61 | 61 | has_expandable_async_drops, insert_clean_drop, |
62 | 62 | }; |
| 63 | +use itertools::izip; |
63 | 64 | use rustc_abi::{FieldIdx, VariantIdx}; |
64 | 65 | use rustc_data_structures::fx::FxHashSet; |
65 | 66 | use rustc_errors::pluralize; |
@@ -982,8 +983,8 @@ fn compute_layout<'tcx>( |
982 | 983 | } = liveness; |
983 | 984 |
|
984 | 985 | // Gather live local types and their indices. |
985 | | - let mut locals = IndexVec::<CoroutineSavedLocal, _>::new(); |
986 | | - let mut tys = IndexVec::<CoroutineSavedLocal, _>::new(); |
| 986 | + let mut locals = IndexVec::<CoroutineSavedLocal, _>::with_capacity(saved_locals.domain_size()); |
| 987 | + let mut tys = IndexVec::<CoroutineSavedLocal, _>::with_capacity(saved_locals.domain_size()); |
987 | 988 | for (saved_local, local) in saved_locals.iter_enumerated() { |
988 | 989 | debug!("coroutine saved local {:?} => {:?}", saved_local, local); |
989 | 990 |
|
@@ -1017,38 +1018,39 @@ fn compute_layout<'tcx>( |
1017 | 1018 | // In debuginfo, these will correspond to the beginning (UNRESUMED) or end |
1018 | 1019 | // (RETURNED, POISONED) of the function. |
1019 | 1020 | let body_span = body.source_scopes[OUTERMOST_SOURCE_SCOPE].span; |
1020 | | - let mut variant_source_info: IndexVec<VariantIdx, SourceInfo> = [ |
| 1021 | + let mut variant_source_info: IndexVec<VariantIdx, SourceInfo> = IndexVec::with_capacity( |
| 1022 | + CoroutineArgs::RESERVED_VARIANTS + live_locals_at_suspension_points.len(), |
| 1023 | + ); |
| 1024 | + variant_source_info.extend([ |
1021 | 1025 | SourceInfo::outermost(body_span.shrink_to_lo()), |
1022 | 1026 | SourceInfo::outermost(body_span.shrink_to_hi()), |
1023 | 1027 | SourceInfo::outermost(body_span.shrink_to_hi()), |
1024 | | - ] |
1025 | | - .iter() |
1026 | | - .copied() |
1027 | | - .collect(); |
| 1028 | + ]); |
1028 | 1029 |
|
1029 | 1030 | // Build the coroutine variant field list. |
1030 | 1031 | // Create a map from local indices to coroutine struct indices. |
1031 | | - let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> = |
1032 | | - iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect(); |
| 1032 | + let mut variant_fields: IndexVec<VariantIdx, _> = IndexVec::from_elem_n( |
| 1033 | + IndexVec::new(), |
| 1034 | + CoroutineArgs::RESERVED_VARIANTS + live_locals_at_suspension_points.len(), |
| 1035 | + ); |
1033 | 1036 | let mut remap = IndexVec::from_elem_n(None, saved_locals.domain_size()); |
1034 | | - for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() { |
1035 | | - let variant_index = |
1036 | | - VariantIdx::from(CoroutineArgs::RESERVED_VARIANTS + suspension_point_idx); |
1037 | | - let mut fields = IndexVec::new(); |
1038 | | - for (idx, saved_local) in live_locals.iter().enumerate() { |
1039 | | - fields.push(saved_local); |
| 1037 | + for (live_locals, &source_info_at_suspension_point, (variant_index, fields)) in izip!( |
| 1038 | + &live_locals_at_suspension_points, |
| 1039 | + &source_info_at_suspension_points, |
| 1040 | + variant_fields.iter_enumerated_mut().skip(CoroutineArgs::RESERVED_VARIANTS) |
| 1041 | + ) { |
| 1042 | + *fields = live_locals.iter().collect(); |
| 1043 | + for (idx, &saved_local) in fields.iter_enumerated() { |
1040 | 1044 | // Note that if a field is included in multiple variants, we will |
1041 | 1045 | // just use the first one here. That's fine; fields do not move |
1042 | 1046 | // around inside coroutines, so it doesn't matter which variant |
1043 | 1047 | // index we access them by. |
1044 | | - let idx = FieldIdx::from_usize(idx); |
1045 | 1048 | remap[locals[saved_local]] = Some((tys[saved_local].ty, variant_index, idx)); |
1046 | 1049 | } |
1047 | | - variant_fields.push(fields); |
1048 | | - variant_source_info.push(source_info_at_suspension_points[suspension_point_idx]); |
| 1050 | + variant_source_info.push(source_info_at_suspension_point); |
1049 | 1051 | } |
1050 | | - debug!("coroutine variant_fields = {:?}", variant_fields); |
1051 | | - debug!("coroutine storage_conflicts = {:#?}", storage_conflicts); |
| 1052 | + debug!(?variant_fields); |
| 1053 | + debug!(?storage_conflicts); |
1052 | 1054 |
|
1053 | 1055 | let mut field_names = IndexVec::from_elem(None, &tys); |
1054 | 1056 | for var in &body.var_debug_info { |
|
0 commit comments