|
71 | 71 |
|
72 | 72 | use rustc_data_structures::unord::UnordMap;
|
73 | 73 | use rustc_hir as hir;
|
74 |
| -use rustc_middle::hir::place::{Projection, ProjectionKind}; |
| 74 | +use rustc_middle::hir::place::{PlaceBase, Projection, ProjectionKind}; |
75 | 75 | use rustc_middle::mir::visit::MutVisitor;
|
76 | 76 | use rustc_middle::mir::{self, dump_mir, MirPass};
|
77 | 77 | use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt, TypeVisitableExt};
|
@@ -149,17 +149,25 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
|
149 | 149 | bug!("we ran out of parent captures!")
|
150 | 150 | };
|
151 | 151 |
|
| 152 | + let PlaceBase::Upvar(parent_base) = parent_capture.place.base else { |
| 153 | + bug!("expected capture to be an upvar"); |
| 154 | + }; |
| 155 | + let PlaceBase::Upvar(child_base) = child_capture.place.base else { |
| 156 | + bug!("expected capture to be an upvar"); |
| 157 | + }; |
| 158 | + |
152 | 159 | assert!(
|
153 | 160 | child_capture.place.projections.len() >= parent_capture.place.projections.len()
|
154 | 161 | );
|
155 | 162 | // A parent matches a child they share the same prefix of projections.
|
156 | 163 | // The child may have more, if it is capturing sub-fields out of
|
157 | 164 | // something that is captured by-move in the parent closure.
|
158 |
| - if !std::iter::zip( |
159 |
| - &child_capture.place.projections, |
160 |
| - &parent_capture.place.projections, |
161 |
| - ) |
162 |
| - .all(|(child, parent)| child.kind == parent.kind) |
| 165 | + if parent_base.var_path.hir_id != child_base.var_path.hir_id |
| 166 | + || !std::iter::zip( |
| 167 | + &child_capture.place.projections, |
| 168 | + &parent_capture.place.projections, |
| 169 | + ) |
| 170 | + .all(|(child, parent)| child.kind == parent.kind) |
163 | 171 | {
|
164 | 172 | // Make sure the field was used at least once.
|
165 | 173 | assert!(
|
@@ -217,6 +225,12 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
|
217 | 225 | }
|
218 | 226 | }
|
219 | 227 |
|
| 228 | + // Pop the last parent capture |
| 229 | + if field_used_at_least_once { |
| 230 | + let _ = parent_captures.next().unwrap(); |
| 231 | + } |
| 232 | + assert_eq!(parent_captures.next(), None, "leftover parent captures?"); |
| 233 | + |
220 | 234 | if coroutine_kind == ty::ClosureKind::FnOnce {
|
221 | 235 | assert_eq!(field_remapping.len(), tcx.closure_captures(parent_def_id).len());
|
222 | 236 | return;
|
|
0 commit comments