Replace a magic boolean with enum EmitStorageLive
The previous boolean used `true` to indicate that storage-live should _not_ be emitted, so all occurrences of `Yes` and `No` should be the logical opposite of the previous value.
This commit is contained in:
parent
ad575b093b
commit
3b22589cfa
@ -1,4 +1,4 @@
|
|||||||
use crate::build::matches::DeclareLetBindings;
|
use crate::build::matches::{DeclareLetBindings, EmitStorageLive};
|
||||||
use crate::build::ForGuard::OutsideGuard;
|
use crate::build::ForGuard::OutsideGuard;
|
||||||
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
||||||
use rustc_middle::middle::region::Scope;
|
use rustc_middle::middle::region::Scope;
|
||||||
@ -215,7 +215,7 @@ fn ast_block_stmts(
|
|||||||
None,
|
None,
|
||||||
initializer_span,
|
initializer_span,
|
||||||
DeclareLetBindings::No,
|
DeclareLetBindings::No,
|
||||||
true,
|
EmitStorageLive::No,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
matching.and(failure)
|
matching.and(failure)
|
||||||
|
@ -62,6 +62,18 @@ pub(crate) enum DeclareLetBindings {
|
|||||||
LetNotPermitted,
|
LetNotPermitted,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used by [`Builder::bind_matched_candidate_for_arm_body`] to determine
|
||||||
|
/// whether or not to call [`Builder::storage_live_binding`] to emit
|
||||||
|
/// [`StatementKind::StorageLive`].
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub(crate) enum EmitStorageLive {
|
||||||
|
/// Yes, emit `StorageLive` as normal.
|
||||||
|
Yes,
|
||||||
|
/// No, don't emit `StorageLive`. The caller has taken responsibility for
|
||||||
|
/// emitting `StorageLive` as appropriate.
|
||||||
|
No,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
/// Lowers a condition in a way that ensures that variables bound in any let
|
/// Lowers a condition in a way that ensures that variables bound in any let
|
||||||
/// expressions are definitely initialized in the if body.
|
/// expressions are definitely initialized in the if body.
|
||||||
@ -174,7 +186,7 @@ fn then_else_break_inner(
|
|||||||
Some(args.variable_source_info.scope),
|
Some(args.variable_source_info.scope),
|
||||||
args.variable_source_info.span,
|
args.variable_source_info.span,
|
||||||
args.declare_let_bindings,
|
args.declare_let_bindings,
|
||||||
false,
|
EmitStorageLive::Yes,
|
||||||
),
|
),
|
||||||
_ => {
|
_ => {
|
||||||
let mut block = block;
|
let mut block = block;
|
||||||
@ -467,7 +479,7 @@ fn lower_match_arms(
|
|||||||
&fake_borrow_temps,
|
&fake_borrow_temps,
|
||||||
scrutinee_span,
|
scrutinee_span,
|
||||||
Some((arm, match_scope)),
|
Some((arm, match_scope)),
|
||||||
false,
|
EmitStorageLive::Yes,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.fixed_temps_scope = old_dedup_scope;
|
this.fixed_temps_scope = old_dedup_scope;
|
||||||
@ -512,7 +524,7 @@ fn bind_pattern(
|
|||||||
fake_borrow_temps: &[(Place<'tcx>, Local, FakeBorrowKind)],
|
fake_borrow_temps: &[(Place<'tcx>, Local, FakeBorrowKind)],
|
||||||
scrutinee_span: Span,
|
scrutinee_span: Span,
|
||||||
arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>,
|
arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>,
|
||||||
storages_alive: bool,
|
emit_storage_live: EmitStorageLive,
|
||||||
) -> BasicBlock {
|
) -> BasicBlock {
|
||||||
if candidate.subcandidates.is_empty() {
|
if candidate.subcandidates.is_empty() {
|
||||||
// Avoid generating another `BasicBlock` when we only have one
|
// Avoid generating another `BasicBlock` when we only have one
|
||||||
@ -524,7 +536,7 @@ fn bind_pattern(
|
|||||||
scrutinee_span,
|
scrutinee_span,
|
||||||
arm_match_scope,
|
arm_match_scope,
|
||||||
true,
|
true,
|
||||||
storages_alive,
|
emit_storage_live,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// It's helpful to avoid scheduling drops multiple times to save
|
// It's helpful to avoid scheduling drops multiple times to save
|
||||||
@ -561,7 +573,7 @@ fn bind_pattern(
|
|||||||
scrutinee_span,
|
scrutinee_span,
|
||||||
arm_match_scope,
|
arm_match_scope,
|
||||||
schedule_drops,
|
schedule_drops,
|
||||||
storages_alive,
|
emit_storage_live,
|
||||||
);
|
);
|
||||||
if arm.is_none() {
|
if arm.is_none() {
|
||||||
schedule_drops = false;
|
schedule_drops = false;
|
||||||
@ -731,7 +743,7 @@ pub(crate) fn place_into_pattern(
|
|||||||
&[],
|
&[],
|
||||||
irrefutable_pat.span,
|
irrefutable_pat.span,
|
||||||
None,
|
None,
|
||||||
false,
|
EmitStorageLive::Yes,
|
||||||
)
|
)
|
||||||
.unit()
|
.unit()
|
||||||
}
|
}
|
||||||
@ -807,6 +819,8 @@ pub(crate) fn declare_guard_bindings(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Emits a [`StatementKind::StorageLive`] for the given var, and also
|
||||||
|
/// schedules a drop if requested (and possible).
|
||||||
pub(crate) fn storage_live_binding(
|
pub(crate) fn storage_live_binding(
|
||||||
&mut self,
|
&mut self,
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
@ -2034,7 +2048,7 @@ pub(crate) fn lower_let_expr(
|
|||||||
source_scope: Option<SourceScope>,
|
source_scope: Option<SourceScope>,
|
||||||
scope_span: Span,
|
scope_span: Span,
|
||||||
declare_let_bindings: DeclareLetBindings,
|
declare_let_bindings: DeclareLetBindings,
|
||||||
storages_alive: bool,
|
emit_storage_live: EmitStorageLive,
|
||||||
) -> BlockAnd<()> {
|
) -> BlockAnd<()> {
|
||||||
let expr_span = self.thir[expr_id].span;
|
let expr_span = self.thir[expr_id].span;
|
||||||
let scrutinee = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span));
|
let scrutinee = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span));
|
||||||
@ -2074,7 +2088,7 @@ pub(crate) fn lower_let_expr(
|
|||||||
&[],
|
&[],
|
||||||
expr_span,
|
expr_span,
|
||||||
None,
|
None,
|
||||||
storages_alive,
|
emit_storage_live,
|
||||||
);
|
);
|
||||||
|
|
||||||
// If branch coverage is enabled, record this branch.
|
// If branch coverage is enabled, record this branch.
|
||||||
@ -2099,7 +2113,7 @@ fn bind_and_guard_matched_candidate<'pat>(
|
|||||||
scrutinee_span: Span,
|
scrutinee_span: Span,
|
||||||
arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>,
|
arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>,
|
||||||
schedule_drops: bool,
|
schedule_drops: bool,
|
||||||
storages_alive: bool,
|
emit_storage_live: EmitStorageLive,
|
||||||
) -> BasicBlock {
|
) -> BasicBlock {
|
||||||
debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate);
|
debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate);
|
||||||
|
|
||||||
@ -2314,7 +2328,7 @@ fn bind_and_guard_matched_candidate<'pat>(
|
|||||||
post_guard_block,
|
post_guard_block,
|
||||||
true,
|
true,
|
||||||
by_value_bindings,
|
by_value_bindings,
|
||||||
storages_alive,
|
emit_storage_live,
|
||||||
);
|
);
|
||||||
|
|
||||||
post_guard_block
|
post_guard_block
|
||||||
@ -2326,7 +2340,7 @@ fn bind_and_guard_matched_candidate<'pat>(
|
|||||||
block,
|
block,
|
||||||
schedule_drops,
|
schedule_drops,
|
||||||
bindings,
|
bindings,
|
||||||
storages_alive,
|
emit_storage_live,
|
||||||
);
|
);
|
||||||
block
|
block
|
||||||
}
|
}
|
||||||
@ -2417,7 +2431,7 @@ fn bind_matched_candidate_for_arm_body<'b>(
|
|||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
schedule_drops: bool,
|
schedule_drops: bool,
|
||||||
bindings: impl IntoIterator<Item = &'b Binding<'tcx>>,
|
bindings: impl IntoIterator<Item = &'b Binding<'tcx>>,
|
||||||
storages_alive: bool,
|
emit_storage_live: EmitStorageLive,
|
||||||
) where
|
) where
|
||||||
'tcx: 'b,
|
'tcx: 'b,
|
||||||
{
|
{
|
||||||
@ -2427,19 +2441,18 @@ fn bind_matched_candidate_for_arm_body<'b>(
|
|||||||
// Assign each of the bindings. This may trigger moves out of the candidate.
|
// Assign each of the bindings. This may trigger moves out of the candidate.
|
||||||
for binding in bindings {
|
for binding in bindings {
|
||||||
let source_info = self.source_info(binding.span);
|
let source_info = self.source_info(binding.span);
|
||||||
let local = if storages_alive {
|
let local = match emit_storage_live {
|
||||||
// Here storages are already alive, probably because this is a binding
|
// Here storages are already alive, probably because this is a binding
|
||||||
// from let-else.
|
// from let-else.
|
||||||
// We just need to schedule drop for the value.
|
// We just need to schedule drop for the value.
|
||||||
self.var_local_id(binding.var_id, OutsideGuard).into()
|
EmitStorageLive::No => self.var_local_id(binding.var_id, OutsideGuard).into(),
|
||||||
} else {
|
EmitStorageLive::Yes => self.storage_live_binding(
|
||||||
self.storage_live_binding(
|
|
||||||
block,
|
block,
|
||||||
binding.var_id,
|
binding.var_id,
|
||||||
binding.span,
|
binding.span,
|
||||||
OutsideGuard,
|
OutsideGuard,
|
||||||
schedule_drops,
|
schedule_drops,
|
||||||
)
|
),
|
||||||
};
|
};
|
||||||
if schedule_drops {
|
if schedule_drops {
|
||||||
self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard);
|
self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard);
|
||||||
|
Loading…
Reference in New Issue
Block a user