diff options
| author | bors <bors@rust-lang.org> | 2024-04-11 15:46:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-04-11 15:46:42 +0000 |
| commit | df7daa815f4047a1cfe24ecfbc12cfd4f40fa928 (patch) | |
| tree | bb5a109cb3448f72eda68a555aeba02103bd7962 /compiler/rustc_mir_transform/src | |
| parent | 72fe8a0f0049873f4b1d0ab3c482170921819106 (diff) | |
| parent | 1620f336793f61ba558c3b2438ff936c7f3b3d46 (diff) | |
| download | rust-df7daa815f4047a1cfe24ecfbc12cfd4f40fa928.tar.gz rust-df7daa815f4047a1cfe24ecfbc12cfd4f40fa928.zip | |
Auto merge of #123795 - matthiaskrgr:rollup-deesd9c, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #123660 (Make the computation of `coroutine_captures_by_ref_ty` more sophisticated) - #123738 (Call lower_const_param instead of duplicating the code) - #123774 (Fix typo MaybeUnit -> MaybeUninit) - #123790 (correct the handling of `bootstrap-cache-path` option) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/coroutine/by_move_body.rs | 78 |
1 files changed, 10 insertions, 68 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 b26f968bf5e..3d6c1a95204 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::{PlaceBase, Projection, ProjectionKind}; +use rustc_middle::hir::place::{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}; @@ -124,44 +124,10 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody { .tuple_fields() .len(); - let mut field_remapping = UnordMap::default(); - - let mut child_captures = tcx - .closure_captures(coroutine_def_id) - .iter() - .copied() - // By construction we capture all the args first. - .skip(num_args) - .enumerate() - .peekable(); - - // One parent capture may correspond to several child captures if we end up - // refining the set of captures via edition-2021 precise captures. We want to - // match up any number of child captures with one parent capture, so we keep - // peeking off this `Peekable` until the child doesn't match anymore. - for (parent_field_idx, parent_capture) in - tcx.closure_captures(parent_def_id).iter().copied().enumerate() - { - // Make sure we use every field at least once, b/c why are we capturing something - // if it's not used in the inner coroutine. - let mut field_used_at_least_once = false; - - // A parent matches a child if 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. - while child_captures.peek().map_or(false, |(_, child_capture)| { - child_prefix_matches_parent_projections(parent_capture, child_capture) - }) { - let (child_field_idx, child_capture) = child_captures.next().unwrap(); - - // This analysis only makes sense if the parent capture is a - // prefix of the child capture. - assert!( - child_capture.place.projections.len() >= parent_capture.place.projections.len(), - "parent capture ({parent_capture:#?}) expected to be prefix of \ - child capture ({child_capture:#?})" - ); - + let field_remapping: UnordMap<_, _> = ty::analyze_coroutine_closure_captures( + tcx.closure_captures(parent_def_id).iter().copied(), + tcx.closure_captures(coroutine_def_id).iter().skip(num_args).copied(), + |(parent_field_idx, parent_capture), (child_field_idx, child_capture)| { // Store this set of additional projections (fields and derefs). // We need to re-apply them later. let child_precise_captures = @@ -192,7 +158,7 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody { ), }; - field_remapping.insert( + ( FieldIdx::from_usize(child_field_idx + num_args), ( FieldIdx::from_usize(parent_field_idx + num_args), @@ -200,18 +166,10 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody { needs_deref, child_precise_captures, ), - ); - - field_used_at_least_once = true; - } - - // Make sure the field was used at least once. - assert!( - field_used_at_least_once, - "we captured {parent_capture:#?} but it was not used in the child coroutine?" - ); - } - assert_eq!(child_captures.next(), None, "leftover child captures?"); + ) + }, + ) + .collect(); if coroutine_kind == ty::ClosureKind::FnOnce { assert_eq!(field_remapping.len(), tcx.closure_captures(parent_def_id).len()); @@ -241,22 +199,6 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody { } } -fn child_prefix_matches_parent_projections( - parent_capture: &ty::CapturedPlace<'_>, - child_capture: &ty::CapturedPlace<'_>, -) -> bool { - 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"); - }; - - 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) -} - struct MakeByMoveBody<'tcx> { tcx: TyCtxt<'tcx>, field_remapping: UnordMap<FieldIdx, (FieldIdx, Ty<'tcx>, bool, &'tcx [Projection<'tcx>])>, |
