@@ -982,71 +982,70 @@ fn compute_layout<'tcx>(
982982 } = liveness;
983983
984984 // Gather live local types and their indices.
985- let mut locals = IndexVec :: < CoroutineSavedLocal , _ > :: new ( ) ;
986- let mut tys = IndexVec :: < CoroutineSavedLocal , _ > :: new ( ) ;
987- for ( saved_local, local) in saved_locals. iter_enumerated ( ) {
988- debug ! ( "coroutine saved local {:?} => {:?}" , saved_local, local) ;
989-
990- locals. push ( local) ;
991- let decl = & body. local_decls [ local] ;
992- debug ! ( ?decl) ;
993-
994- // Do not `unwrap_crate_local` here, as post-borrowck cleanup may have already cleared
995- // the information. This is alright, since `ignore_for_traits` is only relevant when
996- // this code runs on pre-cleanup MIR, and `ignore_for_traits = false` is the safer
997- // default.
998- let ignore_for_traits = match decl. local_info {
999- // Do not include raw pointers created from accessing `static` items, as those could
1000- // well be re-created by another access to the same static.
1001- ClearCrossCrate :: Set ( box LocalInfo :: StaticRef { is_thread_local, .. } ) => {
1002- !is_thread_local
1003- }
1004- // Fake borrows are only read by fake reads, so do not have any reality in
1005- // post-analysis MIR.
1006- ClearCrossCrate :: Set ( box LocalInfo :: FakeBorrow ) => true ,
1007- _ => false ,
1008- } ;
1009- let decl =
1010- CoroutineSavedTy { ty : decl. ty , source_info : decl. source_info , ignore_for_traits } ;
1011- debug ! ( ?decl) ;
985+ let ( locals, tys) : ( IndexVec < _ , _ > , IndexVec < _ , _ > ) = saved_locals
986+ . iter_enumerated ( )
987+ . map ( |( saved_local, local) | {
988+ debug ! ( "coroutine saved local {saved_local:?} => {local:?}" ) ;
1012989
1013- tys. push ( decl) ;
1014- }
990+ let decl = & body. local_decls [ local] ;
991+ debug ! ( ?decl) ;
992+
993+ // Do not `unwrap_crate_local` here, as post-borrowck cleanup may have already cleared
994+ // the information. This is alright, since `ignore_for_traits` is only relevant when
995+ // this code runs on pre-cleanup MIR, and `ignore_for_traits = false` is the safer
996+ // default.
997+ let ignore_for_traits = match decl. local_info {
998+ // Do not include raw pointers created from accessing `static` items, as those could
999+ // well be re-created by another access to the same static.
1000+ ClearCrossCrate :: Set ( box LocalInfo :: StaticRef { is_thread_local, .. } ) => {
1001+ !is_thread_local
1002+ }
1003+ // Fake borrows are only read by fake reads, so do not have any reality in
1004+ // post-analysis MIR.
1005+ ClearCrossCrate :: Set ( box LocalInfo :: FakeBorrow ) => true ,
1006+ _ => false ,
1007+ } ;
1008+ let decl =
1009+ CoroutineSavedTy { ty : decl. ty , source_info : decl. source_info , ignore_for_traits } ;
1010+ debug ! ( ?decl) ;
1011+
1012+ ( local, decl)
1013+ } )
1014+ . unzip ( ) ;
10151015
10161016 // Leave empty variants for the UNRESUMED, RETURNED, and POISONED states.
10171017 // In debuginfo, these will correspond to the beginning (UNRESUMED) or end
10181018 // (RETURNED, POISONED) of the function.
10191019 let body_span = body. source_scopes [ OUTERMOST_SOURCE_SCOPE ] . span ;
1020- let mut variant_source_info: IndexVec < VariantIdx , SourceInfo > = [
1020+ let variant_source_info: IndexVec < VariantIdx , SourceInfo > = [
10211021 SourceInfo :: outermost ( body_span. shrink_to_lo ( ) ) ,
10221022 SourceInfo :: outermost ( body_span. shrink_to_hi ( ) ) ,
10231023 SourceInfo :: outermost ( body_span. shrink_to_hi ( ) ) ,
10241024 ]
1025- . iter ( )
1026- . copied ( )
1025+ . into_iter ( )
1026+ . chain ( source_info_at_suspension_points )
10271027 . collect ( ) ;
10281028
10291029 // Build the coroutine variant field list.
10301030 // 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 ( ) ;
10331031 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) ;
1040- // Note that if a field is included in multiple variants, we will
1041- // just use the first one here. That's fine; fields do not move
1042- // around inside coroutines, so it doesn't matter which variant
1043- // index we access them by.
1044- let idx = FieldIdx :: from_usize ( idx) ;
1045- remap[ locals[ saved_local] ] = Some ( ( tys[ saved_local] . ty , variant_index, idx) ) ;
1046- }
1047- variant_fields. push ( fields) ;
1048- variant_source_info. push ( source_info_at_suspension_points[ suspension_point_idx] ) ;
1049- }
1032+ let variant_fields = iter:: repeat_n ( IndexVec :: new ( ) , CoroutineArgs :: RESERVED_VARIANTS )
1033+ . chain ( live_locals_at_suspension_points. into_iter ( ) . enumerate ( ) . map (
1034+ |( suspension_point_idx, live_locals) | {
1035+ let variant_index =
1036+ VariantIdx :: from ( CoroutineArgs :: RESERVED_VARIANTS + suspension_point_idx) ;
1037+ let fields = live_locals. iter ( ) . collect :: < IndexVec < FieldIdx , _ > > ( ) ;
1038+ for ( idx, & saved_local) in fields. iter_enumerated ( ) {
1039+ // Note that if a field is included in multiple variants, we will
1040+ // just use the first one here. That's fine; fields do not move
1041+ // around inside coroutines, so it doesn't matter which variant
1042+ // index we access them by.
1043+ remap[ locals[ saved_local] ] = Some ( ( tys[ saved_local] . ty , variant_index, idx) ) ;
1044+ }
1045+ fields
1046+ } ,
1047+ ) )
1048+ . collect :: < IndexVec < VariantIdx , _ > > ( ) ;
10501049 debug ! ( "coroutine variant_fields = {:?}" , variant_fields) ;
10511050 debug ! ( "coroutine storage_conflicts = {:#?}" , storage_conflicts) ;
10521051
0 commit comments