mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Only compute captures once when building MIR.
This commit is contained in:
parent
a785176741
commit
389c6041a4
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::build::expr::category::Category;
|
||||
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
|
||||
use crate::build::{BlockAnd, BlockAndExtension, Builder};
|
||||
use crate::build::{BlockAnd, BlockAndExtension, Builder, Capture, CaptureMap};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_middle::hir::place::Projection as HirProjection;
|
||||
use rustc_middle::hir::place::ProjectionKind as HirProjectionKind;
|
||||
@ -59,8 +59,6 @@ pub(crate) enum PlaceBase {
|
||||
var_hir_id: LocalVarId,
|
||||
/// DefId of the closure
|
||||
closure_def_id: LocalDefId,
|
||||
/// The trait closure implements, `Fn`, `FnMut`, `FnOnce`
|
||||
closure_kind: ty::ClosureKind,
|
||||
},
|
||||
}
|
||||
|
||||
@ -145,27 +143,6 @@ fn is_ancestor_or_same_capture(
|
||||
iter::zip(proj_possible_ancestor, proj_capture).all(|(a, b)| a == b)
|
||||
}
|
||||
|
||||
/// Computes the index of a capture within the desugared closure provided the closure's
|
||||
/// `closure_min_captures` and the capture's index of the capture in the
|
||||
/// `ty::MinCaptureList` of the root variable `var_hir_id`.
|
||||
fn compute_capture_idx<'tcx>(
|
||||
closure_min_captures: &ty::RootVariableMinCaptureList<'tcx>,
|
||||
var_hir_id: LocalVarId,
|
||||
root_var_idx: usize,
|
||||
) -> usize {
|
||||
let mut res = 0;
|
||||
for (var_id, capture_list) in closure_min_captures {
|
||||
if *var_id == var_hir_id.0 {
|
||||
res += root_var_idx;
|
||||
break;
|
||||
} else {
|
||||
res += capture_list.len();
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
/// Given a closure, returns the index of a capture within the desugared closure struct and the
|
||||
/// `ty::CapturedPlace` which is the ancestor of the Place represented using the `var_hir_id`
|
||||
/// and `projection`.
|
||||
@ -174,27 +151,17 @@ fn compute_capture_idx<'tcx>(
|
||||
///
|
||||
/// Returns None, when the ancestor is not found.
|
||||
fn find_capture_matching_projections<'a, 'tcx>(
|
||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
upvars: &'a CaptureMap<'tcx>,
|
||||
var_hir_id: LocalVarId,
|
||||
closure_def_id: LocalDefId,
|
||||
projections: &[PlaceElem<'tcx>],
|
||||
) -> Option<(usize, &'a ty::CapturedPlace<'tcx>)> {
|
||||
let closure_min_captures = typeck_results.closure_min_captures.get(&closure_def_id)?;
|
||||
let root_variable_min_captures = closure_min_captures.get(&var_hir_id.0)?;
|
||||
|
||||
) -> Option<(usize, &'a Capture<'tcx>)> {
|
||||
let hir_projections = convert_to_hir_projections_and_truncate_for_capture(projections);
|
||||
|
||||
// If an ancestor is found, `idx` is the index within the list of captured places
|
||||
// for root variable `var_hir_id` and `capture` is the `ty::CapturedPlace` itself.
|
||||
let (idx, capture) = root_variable_min_captures.iter().enumerate().find(|(_, capture)| {
|
||||
upvars.get_by_key_enumerated(var_hir_id.0).find(|(_, capture)| {
|
||||
let possible_ancestor_proj_kinds: Vec<_> =
|
||||
capture.place.projections.iter().map(|proj| proj.kind).collect();
|
||||
capture.captured_place.place.projections.iter().map(|proj| proj.kind).collect();
|
||||
is_ancestor_or_same_capture(&possible_ancestor_proj_kinds, &hir_projections)
|
||||
})?;
|
||||
|
||||
// Convert index to be from the perspective of the entire closure_min_captures map
|
||||
// instead of just the root variable capture list
|
||||
Some((compute_capture_idx(closure_min_captures, var_hir_id, idx), capture))
|
||||
})
|
||||
}
|
||||
|
||||
/// Takes a PlaceBuilder and resolves the upvar (if any) within it, so that the
|
||||
@ -204,24 +171,15 @@ fn find_capture_matching_projections<'a, 'tcx>(
|
||||
fn to_upvars_resolved_place_builder<'a, 'tcx>(
|
||||
from_builder: PlaceBuilder<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
upvars: &'a CaptureMap<'tcx>,
|
||||
) -> Result<PlaceBuilder<'tcx>, PlaceBuilder<'tcx>> {
|
||||
match from_builder.base {
|
||||
PlaceBase::Local(_) => Ok(from_builder),
|
||||
PlaceBase::Upvar { var_hir_id, closure_def_id, closure_kind } => {
|
||||
let mut upvar_resolved_place_builder = PlaceBuilder::from(ty::CAPTURE_STRUCT_LOCAL);
|
||||
match closure_kind {
|
||||
ty::ClosureKind::Fn | ty::ClosureKind::FnMut => {
|
||||
upvar_resolved_place_builder = upvar_resolved_place_builder.deref();
|
||||
}
|
||||
ty::ClosureKind::FnOnce => {}
|
||||
}
|
||||
|
||||
PlaceBase::Upvar { var_hir_id, closure_def_id } => {
|
||||
let Some((capture_index, capture)) =
|
||||
find_capture_matching_projections(
|
||||
typeck_results,
|
||||
upvars,
|
||||
var_hir_id,
|
||||
closure_def_id,
|
||||
&from_builder.projection,
|
||||
) else {
|
||||
let closure_span = tcx.def_span(closure_def_id);
|
||||
@ -241,39 +199,17 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>(
|
||||
return Err(from_builder);
|
||||
};
|
||||
|
||||
// We won't be building MIR if the closure wasn't local
|
||||
let closure_hir_id = tcx.hir().local_def_id_to_hir_id(closure_def_id);
|
||||
let closure_ty = typeck_results.node_type(closure_hir_id);
|
||||
|
||||
let substs = match closure_ty.kind() {
|
||||
ty::Closure(_, substs) => ty::UpvarSubsts::Closure(substs),
|
||||
ty::Generator(_, substs, _) => ty::UpvarSubsts::Generator(substs),
|
||||
_ => bug!("Lowering capture for non-closure type {:?}", closure_ty),
|
||||
};
|
||||
|
||||
// Access the capture by accessing the field within the Closure struct.
|
||||
//
|
||||
// We must have inferred the capture types since we are building MIR, therefore
|
||||
// it's safe to call `tuple_element_ty` and we can unwrap here because
|
||||
// we know that the capture exists and is the `capture_index`-th capture.
|
||||
let var_ty = substs.tupled_upvars_ty().tuple_fields()[capture_index];
|
||||
let capture_info = &upvars[capture_index];
|
||||
|
||||
upvar_resolved_place_builder =
|
||||
upvar_resolved_place_builder.field(Field::new(capture_index), var_ty);
|
||||
|
||||
// If the variable is captured via ByRef(Immutable/Mutable) Borrow,
|
||||
// we need to deref it
|
||||
upvar_resolved_place_builder = match capture.info.capture_kind {
|
||||
ty::UpvarCapture::ByRef(_) => upvar_resolved_place_builder.deref(),
|
||||
ty::UpvarCapture::ByValue => upvar_resolved_place_builder,
|
||||
};
|
||||
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.
|
||||
let remaining_projections = strip_prefix(
|
||||
capture.place.base_ty,
|
||||
capture.captured_place.place.base_ty,
|
||||
from_builder.projection,
|
||||
&capture.place.projections,
|
||||
&capture.captured_place.place.projections,
|
||||
);
|
||||
upvar_resolved_place_builder.projection.extend(remaining_projections);
|
||||
|
||||
@ -315,24 +251,24 @@ fn strip_prefix<'tcx>(
|
||||
}
|
||||
|
||||
impl<'tcx> PlaceBuilder<'tcx> {
|
||||
pub(crate) fn into_place<'a>(
|
||||
pub(in crate::build) fn into_place<'a>(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
upvars: &'a CaptureMap<'tcx>,
|
||||
) -> Place<'tcx> {
|
||||
if let PlaceBase::Local(local) = self.base {
|
||||
Place { local, projection: tcx.intern_place_elems(&self.projection) }
|
||||
} else {
|
||||
self.expect_upvars_resolved(tcx, typeck_results).into_place(tcx, typeck_results)
|
||||
self.expect_upvars_resolved(tcx, upvars).into_place(tcx, upvars)
|
||||
}
|
||||
}
|
||||
|
||||
fn expect_upvars_resolved<'a>(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
upvars: &'a CaptureMap<'tcx>,
|
||||
) -> PlaceBuilder<'tcx> {
|
||||
to_upvars_resolved_place_builder(self, tcx, typeck_results).unwrap()
|
||||
to_upvars_resolved_place_builder(self, tcx, upvars).unwrap()
|
||||
}
|
||||
|
||||
/// Attempts to resolve the `PlaceBuilder`.
|
||||
@ -346,12 +282,12 @@ 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(crate) fn try_upvars_resolved<'a>(
|
||||
pub(in crate::build) fn try_upvars_resolved<'a>(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
upvars: &'a CaptureMap<'tcx>,
|
||||
) -> Result<PlaceBuilder<'tcx>, PlaceBuilder<'tcx>> {
|
||||
to_upvars_resolved_place_builder(self, tcx, typeck_results)
|
||||
to_upvars_resolved_place_builder(self, tcx, upvars)
|
||||
}
|
||||
|
||||
pub(crate) fn base(&self) -> PlaceBase {
|
||||
@ -392,6 +328,12 @@ impl<'tcx> From<PlaceBase> for PlaceBuilder<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> From<Place<'tcx>> for PlaceBuilder<'tcx> {
|
||||
fn from(p: Place<'tcx>) -> Self {
|
||||
Self { base: PlaceBase::Local(p.local), projection: p.projection.to_vec() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
/// Compile `expr`, yielding a place that we can move from etc.
|
||||
///
|
||||
@ -411,7 +353,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
expr: &Expr<'tcx>,
|
||||
) -> BlockAnd<Place<'tcx>> {
|
||||
let place_builder = unpack!(block = self.as_place_builder(block, expr));
|
||||
block.and(place_builder.into_place(self.tcx, self.typeck_results))
|
||||
block.and(place_builder.into_place(self.tcx, &self.upvars))
|
||||
}
|
||||
|
||||
/// This is used when constructing a compound `Place`, so that we can avoid creating
|
||||
@ -435,7 +377,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
expr: &Expr<'tcx>,
|
||||
) -> BlockAnd<Place<'tcx>> {
|
||||
let place_builder = unpack!(block = self.as_read_only_place_builder(block, expr));
|
||||
block.and(place_builder.into_place(self.tcx, self.typeck_results))
|
||||
block.and(place_builder.into_place(self.tcx, &self.upvars))
|
||||
}
|
||||
|
||||
/// This is used when constructing a compound `Place`, so that we can avoid creating
|
||||
@ -530,7 +472,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
inferred_ty: expr.ty,
|
||||
});
|
||||
|
||||
let place = place_builder.clone().into_place(this.tcx, this.typeck_results);
|
||||
let place = place_builder.clone().into_place(this.tcx, &this.upvars);
|
||||
this.cfg.push(
|
||||
block,
|
||||
Statement {
|
||||
@ -629,17 +571,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
closure_def_id: LocalDefId,
|
||||
var_hir_id: LocalVarId,
|
||||
) -> BlockAnd<PlaceBuilder<'tcx>> {
|
||||
let closure_ty =
|
||||
self.typeck_results.node_type(self.tcx.hir().local_def_id_to_hir_id(closure_def_id));
|
||||
|
||||
let closure_kind = if let ty::Closure(_, closure_substs) = closure_ty.kind() {
|
||||
self.infcx.closure_kind(closure_substs).unwrap()
|
||||
} else {
|
||||
// Generators are considered FnOnce.
|
||||
ty::ClosureKind::FnOnce
|
||||
};
|
||||
|
||||
block.and(PlaceBuilder::from(PlaceBase::Upvar { var_hir_id, closure_def_id, closure_kind }))
|
||||
block.and(PlaceBuilder::from(PlaceBase::Upvar { var_hir_id, closure_def_id }))
|
||||
}
|
||||
|
||||
/// Lower an index expression
|
||||
@ -678,7 +610,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.typeck_results);
|
||||
base_place = base_place.expect_upvars_resolved(self.tcx, &self.upvars);
|
||||
self.add_fake_borrows_of_base(
|
||||
&base_place,
|
||||
block,
|
||||
@ -710,7 +642,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
block,
|
||||
source_info,
|
||||
len,
|
||||
Rvalue::Len(slice.into_place(self.tcx, self.typeck_results)),
|
||||
Rvalue::Len(slice.into_place(self.tcx, &self.upvars)),
|
||||
);
|
||||
// lt = idx < len
|
||||
self.cfg.push_assign(
|
||||
|
@ -322,10 +322,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
unpack!(block = this.as_place_builder(block, &this.thir[*thir_place]));
|
||||
|
||||
if let Ok(place_builder_resolved) =
|
||||
place_builder.try_upvars_resolved(this.tcx, this.typeck_results)
|
||||
place_builder.try_upvars_resolved(this.tcx, &this.upvars)
|
||||
{
|
||||
let mir_place =
|
||||
place_builder_resolved.into_place(this.tcx, this.typeck_results);
|
||||
let mir_place = place_builder_resolved.into_place(this.tcx, &this.upvars);
|
||||
this.cfg.push_fake_read(
|
||||
block,
|
||||
this.source_info(this.tcx.hir().span(*hir_id)),
|
||||
@ -617,7 +616,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// is same as that of the capture in the parent closure.
|
||||
PlaceBase::Upvar { .. } => {
|
||||
let enclosing_upvars_resolved =
|
||||
arg_place_builder.clone().into_place(this.tcx, this.typeck_results);
|
||||
arg_place_builder.clone().into_place(this.tcx, &this.upvars);
|
||||
|
||||
match enclosing_upvars_resolved.as_ref() {
|
||||
PlaceRef {
|
||||
@ -637,12 +636,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
);
|
||||
// Not in a closure
|
||||
debug_assert!(
|
||||
this.upvar_mutbls.len() > upvar_index.index(),
|
||||
"Unexpected capture place, upvar_mutbls={:#?}, upvar_index={:?}",
|
||||
this.upvar_mutbls,
|
||||
this.upvars.len() > upvar_index.index(),
|
||||
"Unexpected capture place, upvars={:#?}, upvar_index={:?}",
|
||||
this.upvars,
|
||||
upvar_index
|
||||
);
|
||||
this.upvar_mutbls[upvar_index.index()]
|
||||
this.upvars[upvar_index.index()].mutability
|
||||
}
|
||||
_ => bug!("Unexpected capture place"),
|
||||
}
|
||||
@ -654,7 +653,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
Mutability::Mut => BorrowKind::Mut { allow_two_phase_borrow: false },
|
||||
};
|
||||
|
||||
let arg_place = arg_place_builder.into_place(this.tcx, this.typeck_results);
|
||||
let arg_place = arg_place_builder.into_place(this.tcx, &this.upvars);
|
||||
|
||||
this.cfg.push_assign(
|
||||
block,
|
||||
|
@ -366,9 +366,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
None => {
|
||||
let place_builder = place_builder.clone();
|
||||
this.consume_by_copy_or_move(
|
||||
place_builder
|
||||
.field(n, *ty)
|
||||
.into_place(this.tcx, this.typeck_results),
|
||||
place_builder.field(n, *ty).into_place(this.tcx, &this.upvars),
|
||||
)
|
||||
}
|
||||
})
|
||||
|
@ -221,9 +221,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let source_info = self.source_info(scrutinee_span);
|
||||
|
||||
if let Ok(scrutinee_builder) =
|
||||
scrutinee_place_builder.clone().try_upvars_resolved(self.tcx, self.typeck_results)
|
||||
scrutinee_place_builder.clone().try_upvars_resolved(self.tcx, &self.upvars)
|
||||
{
|
||||
let scrutinee_place = scrutinee_builder.into_place(self.tcx, self.typeck_results);
|
||||
let scrutinee_place = scrutinee_builder.into_place(self.tcx, &self.upvars);
|
||||
self.cfg.push_fake_read(block, source_info, cause_matched_place, scrutinee_place);
|
||||
}
|
||||
|
||||
@ -348,12 +348,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// ```
|
||||
let mut opt_scrutinee_place: Option<(Option<&Place<'tcx>>, Span)> = None;
|
||||
let scrutinee_place: Place<'tcx>;
|
||||
if let Ok(scrutinee_builder) = scrutinee_place_builder
|
||||
.clone()
|
||||
.try_upvars_resolved(this.tcx, this.typeck_results)
|
||||
if let Ok(scrutinee_builder) =
|
||||
scrutinee_place_builder.clone().try_upvars_resolved(this.tcx, &this.upvars)
|
||||
{
|
||||
scrutinee_place =
|
||||
scrutinee_builder.into_place(this.tcx, this.typeck_results);
|
||||
scrutinee_place = scrutinee_builder.into_place(this.tcx, &this.upvars);
|
||||
opt_scrutinee_place = Some((Some(&scrutinee_place), scrutinee_span));
|
||||
}
|
||||
let scope = this.declare_bindings(
|
||||
@ -623,9 +621,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// };
|
||||
// ```
|
||||
if let Ok(match_pair_resolved) =
|
||||
initializer.clone().try_upvars_resolved(self.tcx, self.typeck_results)
|
||||
initializer.clone().try_upvars_resolved(self.tcx, &self.upvars)
|
||||
{
|
||||
let place = match_pair_resolved.into_place(self.tcx, self.typeck_results);
|
||||
let place = match_pair_resolved.into_place(self.tcx, &self.upvars);
|
||||
*match_place = Some(place);
|
||||
}
|
||||
}
|
||||
@ -1605,9 +1603,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
// Insert a Shallow borrow of any places that is switched on.
|
||||
if let Some(fb) = fake_borrows && let Ok(match_place_resolved) =
|
||||
match_place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
|
||||
match_place.clone().try_upvars_resolved(self.tcx, &self.upvars)
|
||||
{
|
||||
let resolved_place = match_place_resolved.into_place(self.tcx, self.typeck_results);
|
||||
let resolved_place = match_place_resolved.into_place(self.tcx, &self.upvars);
|
||||
fb.insert(resolved_place);
|
||||
}
|
||||
|
||||
@ -1794,10 +1792,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
);
|
||||
let mut opt_expr_place: Option<(Option<&Place<'tcx>>, Span)> = None;
|
||||
let expr_place: Place<'tcx>;
|
||||
if let Ok(expr_builder) =
|
||||
expr_place_builder.try_upvars_resolved(self.tcx, self.typeck_results)
|
||||
{
|
||||
expr_place = expr_builder.into_place(self.tcx, self.typeck_results);
|
||||
if let Ok(expr_builder) = expr_place_builder.try_upvars_resolved(self.tcx, &self.upvars) {
|
||||
expr_place = expr_builder.into_place(self.tcx, &self.upvars);
|
||||
opt_expr_place = Some((Some(&expr_place), expr_span));
|
||||
}
|
||||
let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap();
|
||||
|
@ -156,11 +156,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
} => {
|
||||
// Apply the type ascription to the value at `match_pair.place`, which is the
|
||||
if let Ok(place_resolved) =
|
||||
match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
|
||||
match_pair.place.clone().try_upvars_resolved(self.tcx, &self.upvars)
|
||||
{
|
||||
candidate.ascriptions.push(Ascription {
|
||||
annotation: annotation.clone(),
|
||||
source: place_resolved.into_place(self.tcx, self.typeck_results),
|
||||
source: place_resolved.into_place(self.tcx, &self.upvars),
|
||||
variance,
|
||||
});
|
||||
}
|
||||
@ -185,11 +185,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
is_primary: _,
|
||||
} => {
|
||||
if let Ok(place_resolved) =
|
||||
match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
|
||||
match_pair.place.clone().try_upvars_resolved(self.tcx, &self.upvars)
|
||||
{
|
||||
candidate.bindings.push(Binding {
|
||||
span: match_pair.pattern.span,
|
||||
source: place_resolved.into_place(self.tcx, self.typeck_results),
|
||||
source: place_resolved.into_place(self.tcx, &self.upvars),
|
||||
var_id: var,
|
||||
binding_mode: mode,
|
||||
});
|
||||
|
@ -154,10 +154,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
make_target_blocks: impl FnOnce(&mut Self) -> Vec<BasicBlock>,
|
||||
) {
|
||||
let place: Place<'tcx>;
|
||||
if let Ok(test_place_builder) =
|
||||
place_builder.try_upvars_resolved(self.tcx, self.typeck_results)
|
||||
{
|
||||
place = test_place_builder.into_place(self.tcx, self.typeck_results);
|
||||
if let Ok(test_place_builder) = place_builder.try_upvars_resolved(self.tcx, &self.upvars) {
|
||||
place = test_place_builder.into_place(self.tcx, &self.upvars);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -32,13 +32,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
) {
|
||||
let tcx = self.tcx;
|
||||
let (min_length, exact_size) = if let Ok(place_resolved) =
|
||||
place.clone().try_upvars_resolved(tcx, self.typeck_results)
|
||||
place.clone().try_upvars_resolved(tcx, &self.upvars)
|
||||
{
|
||||
match place_resolved
|
||||
.into_place(tcx, self.typeck_results)
|
||||
.ty(&self.local_decls, tcx)
|
||||
.ty
|
||||
.kind()
|
||||
match place_resolved.into_place(tcx, &self.upvars).ty(&self.local_decls, tcx).ty.kind()
|
||||
{
|
||||
ty::Array(_, length) => (length.eval_usize(tcx, self.param_env), true),
|
||||
_ => ((prefix.len() + suffix.len()).try_into().unwrap(), false),
|
||||
|
@ -6,6 +6,7 @@ use crate::thir::pattern::pat_from_hir;
|
||||
use rustc_apfloat::ieee::{Double, Single};
|
||||
use rustc_apfloat::Float;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sorted_map::SortedIndexMultiMap;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
@ -415,12 +416,21 @@ struct Builder<'a, 'tcx> {
|
||||
var_indices: FxHashMap<LocalVarId, LocalsForNode>,
|
||||
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
|
||||
canonical_user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
|
||||
upvar_mutbls: Vec<Mutability>,
|
||||
upvars: CaptureMap<'tcx>,
|
||||
unit_temp: Option<Place<'tcx>>,
|
||||
|
||||
var_debug_info: Vec<VarDebugInfo<'tcx>>,
|
||||
}
|
||||
|
||||
type CaptureMap<'tcx> = SortedIndexMultiMap<usize, hir::HirId, Capture<'tcx>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Capture<'tcx> {
|
||||
captured_place: &'tcx ty::CapturedPlace<'tcx>,
|
||||
use_place: Place<'tcx>,
|
||||
mutability: Mutability,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
fn is_bound_var_in_guard(&self, id: LocalVarId) -> bool {
|
||||
self.guard_context.iter().any(|frame| frame.locals.iter().any(|local| local.id == id))
|
||||
@ -865,7 +875,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
in_scope_unsafe: safety,
|
||||
local_decls: IndexVec::from_elem_n(LocalDecl::new(return_ty, return_span), 1),
|
||||
canonical_user_type_annotations: IndexVec::new(),
|
||||
upvar_mutbls: vec![],
|
||||
upvars: CaptureMap::new(),
|
||||
var_indices: Default::default(),
|
||||
unit_temp: None,
|
||||
var_debug_info: vec![],
|
||||
@ -934,7 +944,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// indexed closure and we stored in a map called closure_min_captures in TypeckResults
|
||||
// with the closure's DefId. Here, we run through that vec of UpvarIds for
|
||||
// the given closure and use the necessary information to create upvar
|
||||
// debuginfo and to fill `self.upvar_mutbls`.
|
||||
// debuginfo and to fill `self.upvars`.
|
||||
if hir_typeck_results.closure_min_captures.get(&fn_def_id).is_some() {
|
||||
let mut closure_env_projs = vec![];
|
||||
let mut closure_ty = self.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
|
||||
@ -954,7 +964,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
.closure_min_captures_flattened(fn_def_id)
|
||||
.zip(capture_tys.zip(capture_syms));
|
||||
|
||||
self.upvar_mutbls = captures_with_tys
|
||||
self.upvars = captures_with_tys
|
||||
.enumerate()
|
||||
.map(|(i, (captured_place, (ty, sym)))| {
|
||||
let capture = captured_place.info.capture_kind;
|
||||
@ -974,16 +984,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
let env_place = Place {
|
||||
local: ty::CAPTURE_STRUCT_LOCAL,
|
||||
projection: tcx.intern_place_elems(&projs),
|
||||
};
|
||||
let use_place = env_place;
|
||||
self.var_debug_info.push(VarDebugInfo {
|
||||
name: *sym,
|
||||
source_info: SourceInfo::outermost(tcx_hir.span(var_id)),
|
||||
value: VarDebugInfoContents::Place(Place {
|
||||
local: ty::CAPTURE_STRUCT_LOCAL,
|
||||
projection: tcx.intern_place_elems(&projs),
|
||||
}),
|
||||
value: VarDebugInfoContents::Place(use_place),
|
||||
});
|
||||
|
||||
mutability
|
||||
let capture = Capture { captured_place, use_place, mutability };
|
||||
(var_id, capture)
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user