@@ -126,92 +126,84 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
126126
127127 let mut field_remapping = UnordMap :: default ( ) ;
128128
129- // One parent capture may correspond to several child captures if we end up
130- // refining the set of captures via edition-2021 precise captures. We want to
131- // match up any number of child captures with one parent capture, so we keep
132- // peeking off this `Peekable` until the child doesn't match anymore.
133- let mut parent_captures =
134- tcx. closure_captures ( parent_def_id) . iter ( ) . copied ( ) . enumerate ( ) . peekable ( ) ;
135- // Make sure we use every field at least once, b/c why are we capturing something
136- // if it's not used in the inner coroutine.
137- let mut field_used_at_least_once = false ;
138-
139- for ( child_field_idx, child_capture) in tcx
129+ let mut child_captures = tcx
140130 . closure_captures ( coroutine_def_id)
141131 . iter ( )
142132 . copied ( )
143133 // By construction we capture all the args first.
144134 . skip ( num_args)
145135 . enumerate ( )
136+ . peekable ( ) ;
137+
138+ // One parent capture may correspond to several child captures if we end up
139+ // refining the set of captures via edition-2021 precise captures. We want to
140+ // match up any number of child captures with one parent capture, so we keep
141+ // peeking off this `Peekable` until the child doesn't match anymore.
142+ for ( parent_field_idx, parent_capture) in
143+ tcx. closure_captures ( parent_def_id) . iter ( ) . copied ( ) . enumerate ( )
146144 {
147- let ( mut parent_field_idx, mut parent_capture) ;
148- loop {
149- ( parent_field_idx, parent_capture) =
150- * parent_captures. peek ( ) . expect ( "we ran out of parent captures!" ) ;
151- // A parent matches a child they share the same prefix of projections.
152- // The child may have more, if it is capturing sub-fields out of
153- // something that is captured by-move in the parent closure.
154- if child_prefix_matches_parent_projections ( parent_capture, child_capture) {
155- break ;
156- }
157- // Make sure the field was used at least once.
158- assert ! (
159- field_used_at_least_once,
160- "we captured {parent_capture:#?} but it was not used in the child coroutine?"
161- ) ;
162- field_used_at_least_once = false ;
163- // Skip this field.
164- let _ = parent_captures. next ( ) . unwrap ( ) ;
165- }
145+ // Make sure we use every field at least once, b/c why are we capturing something
146+ // if it's not used in the inner coroutine.
147+ let mut field_used_at_least_once = false ;
148+
149+ // A parent matches a child if they share the same prefix of projections.
150+ // The child may have more, if it is capturing sub-fields out of
151+ // something that is captured by-move in the parent closure.
152+ while child_captures. peek ( ) . map_or ( false , |( _, child_capture) | {
153+ child_prefix_matches_parent_projections ( parent_capture, child_capture)
154+ } ) {
155+ let ( child_field_idx, child_capture) = child_captures. next ( ) . unwrap ( ) ;
166156
167- // Store this set of additional projections (fields and derefs).
168- // We need to re-apply them later.
169- let child_precise_captures =
170- & child_capture. place . projections [ parent_capture. place . projections . len ( ) ..] ;
157+ // Store this set of additional projections (fields and derefs).
158+ // We need to re-apply them later.
159+ let child_precise_captures =
160+ & child_capture. place . projections [ parent_capture. place . projections . len ( ) ..] ;
171161
172- // If the parent captures by-move, and the child captures by-ref, then we
173- // need to peel an additional `deref` off of the body of the child.
174- let needs_deref = child_capture. is_by_ref ( ) && !parent_capture. is_by_ref ( ) ;
175- if needs_deref {
176- assert_ne ! (
177- coroutine_kind,
178- ty:: ClosureKind :: FnOnce ,
179- "`FnOnce` coroutine-closures return coroutines that capture from \
162+ // If the parent captures by-move, and the child captures by-ref, then we
163+ // need to peel an additional `deref` off of the body of the child.
164+ let needs_deref = child_capture. is_by_ref ( ) && !parent_capture. is_by_ref ( ) ;
165+ if needs_deref {
166+ assert_ne ! (
167+ coroutine_kind,
168+ ty:: ClosureKind :: FnOnce ,
169+ "`FnOnce` coroutine-closures return coroutines that capture from \
180170 their body; it will always result in a borrowck error!"
181- ) ;
182- }
171+ ) ;
172+ }
183173
184- // Finally, store the type of the parent's captured place. We need
185- // this when building the field projection in the MIR body later on.
186- let mut parent_capture_ty = parent_capture. place . ty ( ) ;
187- parent_capture_ty = match parent_capture. info . capture_kind {
188- ty:: UpvarCapture :: ByValue => parent_capture_ty,
189- ty:: UpvarCapture :: ByRef ( kind) => Ty :: new_ref (
190- tcx,
191- tcx. lifetimes . re_erased ,
192- parent_capture_ty,
193- kind. to_mutbl_lossy ( ) ,
194- ) ,
195- } ;
174+ // Finally, store the type of the parent's captured place. We need
175+ // this when building the field projection in the MIR body later on.
176+ let mut parent_capture_ty = parent_capture. place . ty ( ) ;
177+ parent_capture_ty = match parent_capture. info . capture_kind {
178+ ty:: UpvarCapture :: ByValue => parent_capture_ty,
179+ ty:: UpvarCapture :: ByRef ( kind) => Ty :: new_ref (
180+ tcx,
181+ tcx. lifetimes . re_erased ,
182+ parent_capture_ty,
183+ kind. to_mutbl_lossy ( ) ,
184+ ) ,
185+ } ;
196186
197- field_remapping. insert (
198- FieldIdx :: from_usize ( child_field_idx + num_args) ,
199- (
200- FieldIdx :: from_usize ( parent_field_idx + num_args) ,
201- parent_capture_ty,
202- needs_deref,
203- child_precise_captures,
204- ) ,
205- ) ;
187+ field_remapping. insert (
188+ FieldIdx :: from_usize ( child_field_idx + num_args) ,
189+ (
190+ FieldIdx :: from_usize ( parent_field_idx + num_args) ,
191+ parent_capture_ty,
192+ needs_deref,
193+ child_precise_captures,
194+ ) ,
195+ ) ;
206196
207- field_used_at_least_once = true ;
208- }
197+ field_used_at_least_once = true ;
198+ }
209199
210- // Pop the last parent capture
211- if field_used_at_least_once {
212- let _ = parent_captures. next ( ) . unwrap ( ) ;
200+ // Make sure the field was used at least once.
201+ assert ! (
202+ field_used_at_least_once,
203+ "we captured {parent_capture:#?} but it was not used in the child coroutine?"
204+ ) ;
213205 }
214- assert_eq ! ( parent_captures . next( ) , None , "leftover parent captures?" ) ;
206+ assert_eq ! ( child_captures . next( ) , None , "leftover child captures?" ) ;
215207
216208 if coroutine_kind == ty:: ClosureKind :: FnOnce {
217209 assert_eq ! ( field_remapping. len( ) , tcx. closure_captures( parent_def_id) . len( ) ) ;
0 commit comments