@@ -126,92 +126,84 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
126
126
127
127
let mut field_remapping = UnordMap :: default ( ) ;
128
128
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
140
130
. closure_captures ( coroutine_def_id)
141
131
. iter ( )
142
132
. copied ( )
143
133
// By construction we capture all the args first.
144
134
. skip ( num_args)
145
135
. 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 ( )
146
144
{
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 ( ) ;
166
156
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 ( ) ..] ;
171
161
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 \
180
170
their body; it will always result in a borrowck error!"
181
- ) ;
182
- }
171
+ ) ;
172
+ }
183
173
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
+ } ;
196
186
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
+ ) ;
206
196
207
- field_used_at_least_once = true ;
208
- }
197
+ field_used_at_least_once = true ;
198
+ }
209
199
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
+ ) ;
213
205
}
214
- assert_eq ! ( parent_captures . next( ) , None , "leftover parent captures?" ) ;
206
+ assert_eq ! ( child_captures . next( ) , None , "leftover child captures?" ) ;
215
207
216
208
if coroutine_kind == ty:: ClosureKind :: FnOnce {
217
209
assert_eq ! ( field_remapping. len( ) , tcx. closure_captures( parent_def_id) . len( ) ) ;
0 commit comments