| 
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