Pass one argument instead of fetching two fields of it at every call site

This commit is contained in:
Oli Scherer 2022-06-23 16:08:02 +00:00
parent a034446fae
commit eeb10335ce
7 changed files with 60 additions and 100 deletions

View File

@ -71,7 +71,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<PlaceElem<'tcx>>,
}
@ -202,10 +202,9 @@ 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>(
fn to_upvars_resolved_place_builder<'tcx>(
from_builder: PlaceBuilder<'tcx>,
tcx: TyCtxt<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
cx: &Builder<'_, 'tcx>,
) -> Result<PlaceBuilder<'tcx>, PlaceBuilder<'tcx>> {
match from_builder.base {
PlaceBase::Local(_) => Ok(from_builder),
@ -220,13 +219,13 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>(
let Some((capture_index, capture)) =
find_capture_matching_projections(
typeck_results,
cx.typeck_results,
var_hir_id,
closure_def_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",
@ -243,8 +242,8 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>(
};
// 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.expect_local());
let closure_ty = typeck_results.node_type(closure_hir_id);
let closure_hir_id = cx.tcx.hir().local_def_id_to_hir_id(closure_def_id.expect_local());
let closure_ty = cx.typeck_results.node_type(closure_hir_id);
let substs = match closure_ty.kind() {
ty::Closure(_, substs) => ty::UpvarSubsts::Closure(substs),
@ -316,24 +315,16 @@ fn strip_prefix<'tcx>(
}
impl<'tcx> PlaceBuilder<'tcx> {
pub(crate) fn into_place<'a>(
self,
tcx: TyCtxt<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
) -> Place<'tcx> {
pub(crate) 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, typeck_results).into_place(tcx, typeck_results)
self.expect_upvars_resolved(cx).into_place(cx)
}
}
fn expect_upvars_resolved<'a>(
self,
tcx: TyCtxt<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
) -> PlaceBuilder<'tcx> {
to_upvars_resolved_place_builder(self, tcx, typeck_results).unwrap()
fn expect_upvars_resolved(self, cx: &Builder<'_, 'tcx>) -> PlaceBuilder<'tcx> {
to_upvars_resolved_place_builder(self, cx).unwrap()
}
/// Attempts to resolve the `PlaceBuilder`.
@ -347,12 +338,11 @@ 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(crate) fn try_upvars_resolved(
self,
tcx: TyCtxt<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
cx: &Builder<'_, 'tcx>,
) -> Result<PlaceBuilder<'tcx>, PlaceBuilder<'tcx>> {
to_upvars_resolved_place_builder(self, tcx, typeck_results)
to_upvars_resolved_place_builder(self, cx)
}
pub(crate) fn base(&self) -> PlaceBase {
@ -412,7 +402,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))
}
/// This is used when constructing a compound `Place`, so that we can avoid creating
@ -436,7 +426,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))
}
/// This is used when constructing a compound `Place`, so that we can avoid creating
@ -531,7 +521,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);
this.cfg.push(
block,
Statement {
@ -683,7 +673,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);
self.add_fake_borrows_of_base(
&base_place,
block,
@ -711,12 +701,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.typeck_results)),
);
self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice.into_place(self)));
// lt = idx < len
self.cfg.push_assign(
block,

View File

@ -321,11 +321,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let place_builder =
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)
{
let mir_place =
place_builder_resolved.into_place(this.tcx, this.typeck_results);
if let Ok(place_builder_resolved) = place_builder.try_upvars_resolved(this) {
let mir_place = place_builder_resolved.into_place(this);
this.cfg.push_fake_read(
block,
this.source_info(this.tcx.hir().span(*hir_id)),
@ -616,8 +613,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// by the parent itself. The mutability of the current capture
// 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);
let enclosing_upvars_resolved = arg_place_builder.clone().into_place(this);
match enclosing_upvars_resolved.as_ref() {
PlaceRef {
@ -654,7 +650,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);
this.cfg.push_assign(
block,

View File

@ -365,9 +365,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),
)
}
})

View File

@ -220,10 +220,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let cause_matched_place = FakeReadCause::ForMatchedPlace(None);
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)
{
let scrutinee_place = scrutinee_builder.into_place(self.tcx, self.typeck_results);
if let Ok(scrutinee_builder) = scrutinee_place_builder.clone().try_upvars_resolved(self) {
let scrutinee_place = scrutinee_builder.into_place(self);
self.cfg.push_fake_read(block, source_info, cause_matched_place, scrutinee_place);
}
@ -348,12 +346,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)
{
scrutinee_place =
scrutinee_builder.into_place(this.tcx, this.typeck_results);
scrutinee_place = scrutinee_builder.into_place(this);
opt_scrutinee_place = Some((Some(&scrutinee_place), scrutinee_span));
}
let scope = this.declare_bindings(
@ -602,12 +598,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
while let Some(next) = {
for binding in &candidate_ref.bindings {
let local = self.var_local_id(binding.var_id, OutsideGuard);
let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. },
)))) = self.local_decls[local].local_info else {
bug!("Let binding to non-user variable.")
};
// `try_upvars_resolved` may fail if it is unable to resolve the given
// `PlaceBuilder` inside a closure. In this case, we don't want to include
// a scrutinee place. `scrutinee_place_builder` will fail for destructured
@ -622,10 +612,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// let (v1, v2) = foo;
// };
// ```
if let Ok(match_pair_resolved) =
initializer.clone().try_upvars_resolved(self.tcx, self.typeck_results)
{
let place = match_pair_resolved.into_place(self.tcx, self.typeck_results);
if let Ok(match_pair_resolved) = initializer.clone().try_upvars_resolved(self) {
let place = match_pair_resolved.into_place(self);
let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. },
)))) = self.local_decls[local].local_info else {
bug!("Let binding to non-user variable.")
};
*match_place = Some(place);
}
}
@ -1605,9 +1600,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)
{
let resolved_place = match_place_resolved.into_place(self.tcx, self.typeck_results);
let resolved_place = match_place_resolved.into_place(self);
fb.insert(resolved_place);
}
@ -1799,10 +1794,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) {
expr_place = expr_builder.into_place(self);
opt_expr_place = Some((Some(&expr_place), expr_span));
}
let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap();

View File

@ -156,12 +156,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ascription: thir::Ascription { ref annotation, variance },
} => {
// 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)
{
if let Ok(place_resolved) = match_pair.place.clone().try_upvars_resolved(self) {
candidate.ascriptions.push(Ascription {
annotation: annotation.clone(),
source: place_resolved.into_place(self.tcx, self.typeck_results),
source: place_resolved.into_place(self),
variance,
});
}
@ -185,12 +183,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ref subpattern,
is_primary: _,
} => {
if let Ok(place_resolved) =
match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
{
if let Ok(place_resolved) = match_pair.place.clone().try_upvars_resolved(self) {
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),
var_id: var,
binding_mode: mode,
});

View File

@ -155,10 +155,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) {
place = test_place_builder.into_place(self);
} else {
return;
}

View File

@ -31,21 +31,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
suffix: &'pat [Pat<'tcx>],
) {
let tcx = self.tcx;
let (min_length, exact_size) = if let Ok(place_resolved) =
place.clone().try_upvars_resolved(tcx, self.typeck_results)
{
match place_resolved
.into_place(tcx, self.typeck_results)
.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),
}
} else {
((prefix.len() + suffix.len()).try_into().unwrap(), false)
};
let (min_length, exact_size) =
if let Ok(place_resolved) = place.clone().try_upvars_resolved(self) {
match place_resolved.into_place(self).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),
}
} else {
((prefix.len() + suffix.len()).try_into().unwrap(), false)
};
match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| {
let elem =
@ -100,7 +94,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
pub(crate) fn new(
pub(in crate::build) fn new(
place: PlaceBuilder<'tcx>,
pattern: &'pat Pat<'tcx>,
) -> MatchPair<'pat, 'tcx> {