mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-31 17:12:53 +00:00
Pass one argument instead of fetching two fields of it at every call site
This commit is contained in:
parent
a034446fae
commit
eeb10335ce
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
)
|
||||
}
|
||||
})
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
});
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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> {
|
||||
|
Loading…
Reference in New Issue
Block a user