diff options
| author | Michael Goulet <michael@errs.io> | 2024-04-05 16:48:12 -0400 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-04-05 16:48:45 -0400 |
| commit | 49c4ebcc409b1537fb0cf99134f5166481096c5f (patch) | |
| tree | 2af3ebb61bc6a14fb325fe36141f3ee02a2835ef /compiler | |
| parent | 0f13bd436b8168efd5055d66b2a1aa6cae37fabb (diff) | |
| download | rust-49c4ebcc409b1537fb0cf99134f5166481096c5f.tar.gz rust-49c4ebcc409b1537fb0cf99134f5166481096c5f.zip | |
Check the base of the place too!
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_mir_transform/src/coroutine/by_move_body.rs | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index a62fe4af810..d94441b1413 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -71,7 +71,7 @@ use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; -use rustc_middle::hir::place::{Projection, ProjectionKind}; +use rustc_middle::hir::place::{PlaceBase, Projection, ProjectionKind}; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::{self, dump_mir, MirPass}; use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt, TypeVisitableExt}; @@ -149,17 +149,25 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody { bug!("we ran out of parent captures!") }; + let PlaceBase::Upvar(parent_base) = parent_capture.place.base else { + bug!("expected capture to be an upvar"); + }; + let PlaceBase::Upvar(child_base) = child_capture.place.base else { + bug!("expected capture to be an upvar"); + }; + assert!( child_capture.place.projections.len() >= parent_capture.place.projections.len() ); // A parent matches a child they share the same prefix of projections. // The child may have more, if it is capturing sub-fields out of // something that is captured by-move in the parent closure. - if !std::iter::zip( - &child_capture.place.projections, - &parent_capture.place.projections, - ) - .all(|(child, parent)| child.kind == parent.kind) + if parent_base.var_path.hir_id != child_base.var_path.hir_id + || !std::iter::zip( + &child_capture.place.projections, + &parent_capture.place.projections, + ) + .all(|(child, parent)| child.kind == parent.kind) { // Make sure the field was used at least once. assert!( @@ -217,6 +225,12 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody { } } + // Pop the last parent capture + if field_used_at_least_once { + let _ = parent_captures.next().unwrap(); + } + assert_eq!(parent_captures.next(), None, "leftover parent captures?"); + if coroutine_kind == ty::ClosureKind::FnOnce { assert_eq!(field_remapping.len(), tcx.closure_captures(parent_def_id).len()); return; |
