|
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