From cf94bdc0742c13e2a0cac864c478b8626b266e1b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:38 +0200 Subject: Merging upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- .../rustc_mir_build/src/build/expr/as_place.rs | 76 +++++++++++----------- 1 file changed, 37 insertions(+), 39 deletions(-) (limited to 'compiler/rustc_mir_build/src/build/expr/as_place.rs') diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index ebb56e5a2..396782d45 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -17,6 +17,7 @@ use rustc_target::abi::VariantIdx; use rustc_index::vec::Idx; +use std::assert_matches::assert_matches; use std::iter; /// The "outermost" place that holds this value. @@ -69,7 +70,7 @@ pub(crate) enum PlaceBase { /// This is used internally when building a place for an expression like `a.b.c`. The fields `b` /// and `c` can be progressively pushed onto the place builder that is created when converting `a`. #[derive(Clone, Debug, PartialEq)] -pub(crate) struct PlaceBuilder<'tcx> { +pub(in crate::build) struct PlaceBuilder<'tcx> { base: PlaceBase, projection: Vec>, } @@ -102,6 +103,8 @@ fn convert_to_hir_projections_and_truncate_for_capture<'tcx>( variant = Some(*idx); continue; } + // These do not affect anything, they just make sure we know the right type. + ProjectionElem::OpaqueCast(_) => continue, ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { @@ -168,22 +171,22 @@ fn find_capture_matching_projections<'a, 'tcx>( /// `PlaceBuilder` now starts from `PlaceBase::Local`. /// /// Returns a Result with the error being the PlaceBuilder (`from_builder`) that was not found. -fn to_upvars_resolved_place_builder<'a, 'tcx>( +#[instrument(level = "trace", skip(cx), ret)] +fn to_upvars_resolved_place_builder<'tcx>( from_builder: PlaceBuilder<'tcx>, - tcx: TyCtxt<'tcx>, - upvars: &'a CaptureMap<'tcx>, + cx: &Builder<'_, 'tcx>, ) -> Result, PlaceBuilder<'tcx>> { match from_builder.base { PlaceBase::Local(_) => Ok(from_builder), PlaceBase::Upvar { var_hir_id, closure_def_id } => { let Some((capture_index, capture)) = find_capture_matching_projections( - upvars, + &cx.upvars, var_hir_id, &from_builder.projection, ) else { - let closure_span = tcx.def_span(closure_def_id); - if !enable_precise_capture(tcx, closure_span) { + let closure_span = cx.tcx.def_span(closure_def_id); + if !enable_precise_capture(cx.tcx, closure_span) { bug!( "No associated capture found for {:?}[{:#?}] even though \ capture_disjoint_fields isn't enabled", @@ -200,12 +203,13 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>( }; // Access the capture by accessing the field within the Closure struct. - let capture_info = &upvars[capture_index]; + let capture_info = &cx.upvars[capture_index]; let mut upvar_resolved_place_builder = PlaceBuilder::from(capture_info.use_place); // We used some of the projections to build the capture itself, // now we apply the remaining to the upvar resolved place. + trace!(?capture.captured_place, ?from_builder.projection); let remaining_projections = strip_prefix( capture.captured_place.place.base_ty, from_builder.projection, @@ -229,17 +233,20 @@ fn strip_prefix<'tcx>( projections: Vec>, prefix_projections: &[HirProjection<'tcx>], ) -> impl Iterator> { - let mut iter = projections.into_iter(); + let mut iter = projections + .into_iter() + // Filter out opaque casts, they are unnecessary in the prefix. + .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(..))); for projection in prefix_projections { match projection.kind { HirProjectionKind::Deref => { - assert!(matches!(iter.next(), Some(ProjectionElem::Deref))); + assert_matches!(iter.next(), Some(ProjectionElem::Deref)); } HirProjectionKind::Field(..) => { if base_ty.is_enum() { - assert!(matches!(iter.next(), Some(ProjectionElem::Downcast(..)))); + assert_matches!(iter.next(), Some(ProjectionElem::Downcast(..))); } - assert!(matches!(iter.next(), Some(ProjectionElem::Field(..)))); + assert_matches!(iter.next(), Some(ProjectionElem::Field(..))); } HirProjectionKind::Index | HirProjectionKind::Subslice => { bug!("unexpected projection kind: {:?}", projection); @@ -251,24 +258,16 @@ fn strip_prefix<'tcx>( } impl<'tcx> PlaceBuilder<'tcx> { - pub(in crate::build) fn into_place<'a>( - self, - tcx: TyCtxt<'tcx>, - upvars: &'a CaptureMap<'tcx>, - ) -> Place<'tcx> { + pub(in crate::build) fn into_place(self, cx: &Builder<'_, 'tcx>) -> Place<'tcx> { if let PlaceBase::Local(local) = self.base { - Place { local, projection: tcx.intern_place_elems(&self.projection) } + Place { local, projection: cx.tcx.intern_place_elems(&self.projection) } } else { - self.expect_upvars_resolved(tcx, upvars).into_place(tcx, upvars) + self.expect_upvars_resolved(cx).into_place(cx) } } - fn expect_upvars_resolved<'a>( - self, - tcx: TyCtxt<'tcx>, - upvars: &'a CaptureMap<'tcx>, - ) -> PlaceBuilder<'tcx> { - to_upvars_resolved_place_builder(self, tcx, upvars).unwrap() + fn expect_upvars_resolved(self, cx: &Builder<'_, 'tcx>) -> PlaceBuilder<'tcx> { + to_upvars_resolved_place_builder(self, cx).unwrap() } /// Attempts to resolve the `PlaceBuilder`. @@ -282,18 +281,21 @@ impl<'tcx> PlaceBuilder<'tcx> { /// not captured. This can happen because the final mir that will be /// generated doesn't require a read for this place. Failures will only /// happen inside closures. - pub(in crate::build) fn try_upvars_resolved<'a>( + pub(in crate::build) fn try_upvars_resolved( self, - tcx: TyCtxt<'tcx>, - upvars: &'a CaptureMap<'tcx>, + cx: &Builder<'_, 'tcx>, ) -> Result, PlaceBuilder<'tcx>> { - to_upvars_resolved_place_builder(self, tcx, upvars) + to_upvars_resolved_place_builder(self, cx) } pub(crate) fn base(&self) -> PlaceBase { self.base } + pub(crate) fn projection(&self) -> &[PlaceElem<'tcx>] { + &self.projection + } + pub(crate) fn field(self, f: Field, ty: Ty<'tcx>) -> Self { self.project(PlaceElem::Field(f, ty)) } @@ -353,7 +355,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr: &Expr<'tcx>, ) -> BlockAnd> { let place_builder = unpack!(block = self.as_place_builder(block, expr)); - block.and(place_builder.into_place(self.tcx, &self.upvars)) + block.and(place_builder.into_place(self)) } /// This is used when constructing a compound `Place`, so that we can avoid creating @@ -377,7 +379,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr: &Expr<'tcx>, ) -> BlockAnd> { let place_builder = unpack!(block = self.as_read_only_place_builder(block, expr)); - block.and(place_builder.into_place(self.tcx, &self.upvars)) + block.and(place_builder.into_place(self)) } /// This is used when constructing a compound `Place`, so that we can avoid creating @@ -472,7 +474,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { inferred_ty: expr.ty, }); - let place = place_builder.clone().into_place(this.tcx, &this.upvars); + let place = place_builder.clone().into_place(this); this.cfg.push( block, Statement { @@ -610,7 +612,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if is_outermost_index { self.read_fake_borrows(block, fake_borrow_temps, source_info) } else { - base_place = base_place.expect_upvars_resolved(self.tcx, &self.upvars); + base_place = base_place.expect_upvars_resolved(self); self.add_fake_borrows_of_base( &base_place, block, @@ -638,12 +640,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let lt = self.temp(bool_ty, expr_span); // len = len(slice) - self.cfg.push_assign( - block, - source_info, - len, - Rvalue::Len(slice.into_place(self.tcx, &self.upvars)), - ); + self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice.into_place(self))); // lt = idx < len self.cfg.push_assign( block, @@ -723,6 +720,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ProjectionElem::Field(..) | ProjectionElem::Downcast(..) + | ProjectionElem::OpaqueCast(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => (), } -- cgit v1.2.3