Remove the non-assigning form of unpack!

This kind of unpacking can be expressed as an ordinary method on
`BlockAnd<()>`.
This commit is contained in:
Zalathar 2024-07-06 11:45:47 +10:00
parent 20ae37c18d
commit 4fe8dd05ed
6 changed files with 60 additions and 44 deletions

View File

@ -282,7 +282,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
) )
} else { } else {
let scope = (*init_scope, source_info); let scope = (*init_scope, source_info);
unpack!(this.in_scope(scope, *lint_level, |this| { let _: BlockAnd<()> = this.in_scope(scope, *lint_level, |this| {
this.declare_bindings( this.declare_bindings(
visibility_scope, visibility_scope,
remainder_span, remainder_span,
@ -291,7 +291,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
None, None,
); );
block.unit() block.unit()
})); });
debug!("ast_block_stmts: pattern={:?}", pattern); debug!("ast_block_stmts: pattern={:?}", pattern);
this.visit_primary_bindings( this.visit_primary_bindings(

View File

@ -486,7 +486,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block.and(Rvalue::Aggregate(result, operands)) block.and(Rvalue::Aggregate(result, operands))
} }
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => { ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
block = unpack!(this.stmt_expr(block, expr_id, None)); block = this.stmt_expr(block, expr_id, None).into_block();
block.and(Rvalue::Use(Operand::Constant(Box::new(ConstOperand { block.and(Rvalue::Use(Operand::Constant(Box::new(ConstOperand {
span: expr_span, span: expr_span,
user_ty: None, user_ty: None,

View File

@ -82,13 +82,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Lower the condition, and have it branch into `then` and `else` blocks. // Lower the condition, and have it branch into `then` and `else` blocks.
let (then_block, else_block) = let (then_block, else_block) =
this.in_if_then_scope(condition_scope, then_span, |this| { this.in_if_then_scope(condition_scope, then_span, |this| {
let then_blk = unpack!(this.then_else_break( let then_blk = this
block, .then_else_break(
cond, block,
Some(condition_scope), // Temp scope cond,
source_info, Some(condition_scope), // Temp scope
DeclareLetBindings::Yes, // Declare `let` bindings normally source_info,
)); DeclareLetBindings::Yes, // Declare `let` bindings normally
)
.into_block();
// Lower the `then` arm into its block. // Lower the `then` arm into its block.
this.expr_into_dest(destination, then_blk, then) this.expr_into_dest(destination, then_blk, then)
@ -187,7 +189,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
const_: Const::from_bool(this.tcx, constant), const_: Const::from_bool(this.tcx, constant),
}, },
); );
let mut rhs_block = unpack!(this.expr_into_dest(destination, continuation, rhs)); let mut rhs_block =
this.expr_into_dest(destination, continuation, rhs).into_block();
// Instrument the lowered RHS's value for condition coverage. // Instrument the lowered RHS's value for condition coverage.
// (Does nothing if condition coverage is not enabled.) // (Does nothing if condition coverage is not enabled.)
this.visit_coverage_standalone_condition(rhs, destination, &mut rhs_block); this.visit_coverage_standalone_condition(rhs, destination, &mut rhs_block);
@ -230,7 +233,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// introduce a unit temporary as the destination for the loop body. // introduce a unit temporary as the destination for the loop body.
let tmp = this.get_unit_temp(); let tmp = this.get_unit_temp();
// Execute the body, branching back to the test. // Execute the body, branching back to the test.
let body_block_end = unpack!(this.expr_into_dest(tmp, body_block, body)); let body_block_end = this.expr_into_dest(tmp, body_block, body).into_block();
this.cfg.goto(body_block_end, source_info, loop_block); this.cfg.goto(body_block_end, source_info, loop_block);
// Loops are only exited by `break` expressions. // Loops are only exited by `break` expressions.
@ -462,7 +465,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
targets.push(target); targets.push(target);
let tmp = this.get_unit_temp(); let tmp = this.get_unit_temp();
let target = unpack!(this.ast_block(tmp, target, block, source_info)); let target =
this.ast_block(tmp, target, block, source_info).into_block();
this.cfg.terminate( this.cfg.terminate(
target, target,
source_info, source_info,

View File

@ -121,8 +121,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
match expr.kind { match expr.kind {
ExprKind::LogicalOp { op: op @ LogicalOp::And, lhs, rhs } => { ExprKind::LogicalOp { op: op @ LogicalOp::And, lhs, rhs } => {
this.visit_coverage_branch_operation(op, expr_span); this.visit_coverage_branch_operation(op, expr_span);
let lhs_then_block = unpack!(this.then_else_break_inner(block, lhs, args)); let lhs_then_block = this.then_else_break_inner(block, lhs, args).into_block();
let rhs_then_block = unpack!(this.then_else_break_inner(lhs_then_block, rhs, args)); let rhs_then_block =
this.then_else_break_inner(lhs_then_block, rhs, args).into_block();
rhs_then_block.unit() rhs_then_block.unit()
} }
ExprKind::LogicalOp { op: op @ LogicalOp::Or, lhs, rhs } => { ExprKind::LogicalOp { op: op @ LogicalOp::Or, lhs, rhs } => {
@ -139,14 +140,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}, },
) )
}); });
let rhs_success_block = unpack!(this.then_else_break_inner( let rhs_success_block = this
failure_block, .then_else_break_inner(
rhs, failure_block,
ThenElseArgs { rhs,
declare_let_bindings: DeclareLetBindings::LetNotPermitted, ThenElseArgs {
..args declare_let_bindings: DeclareLetBindings::LetNotPermitted,
}, ..args
)); },
)
.into_block();
// Make the LHS and RHS success arms converge to a common block. // Make the LHS and RHS success arms converge to a common block.
// (We can't just make LHS goto RHS, because `rhs_success_block` // (We can't just make LHS goto RHS, because `rhs_success_block`
@ -451,7 +454,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
outer_source_info: SourceInfo, outer_source_info: SourceInfo,
fake_borrow_temps: Vec<(Place<'tcx>, Local, FakeBorrowKind)>, fake_borrow_temps: Vec<(Place<'tcx>, Local, FakeBorrowKind)>,
) -> BlockAnd<()> { ) -> BlockAnd<()> {
let arm_end_blocks: Vec<_> = arm_candidates let arm_end_blocks: Vec<BasicBlock> = arm_candidates
.into_iter() .into_iter()
.map(|(arm, candidate)| { .map(|(arm, candidate)| {
debug!("lowering arm {:?}\ncandidate = {:?}", arm, candidate); debug!("lowering arm {:?}\ncandidate = {:?}", arm, candidate);
@ -502,6 +505,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
this.expr_into_dest(destination, arm_block, arm.body) this.expr_into_dest(destination, arm_block, arm.body)
}) })
.into_block()
}) })
.collect(); .collect();
@ -512,10 +516,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
outer_source_info.span.with_lo(outer_source_info.span.hi() - BytePos::from_usize(1)), outer_source_info.span.with_lo(outer_source_info.span.hi() - BytePos::from_usize(1)),
); );
for arm_block in arm_end_blocks { for arm_block in arm_end_blocks {
let block = &self.cfg.basic_blocks[arm_block.0]; let block = &self.cfg.basic_blocks[arm_block];
let last_location = block.statements.last().map(|s| s.source_info); let last_location = block.statements.last().map(|s| s.source_info);
self.cfg.goto(unpack!(arm_block), last_location.unwrap_or(end_brace), end_block); self.cfg.goto(arm_block, last_location.unwrap_or(end_brace), end_block);
} }
self.source_scope = outer_source_info.scope; self.source_scope = outer_source_info.scope;

View File

@ -403,6 +403,15 @@ enum NeedsTemporary {
#[must_use = "if you don't use one of these results, you're leaving a dangling edge"] #[must_use = "if you don't use one of these results, you're leaving a dangling edge"]
struct BlockAnd<T>(BasicBlock, T); struct BlockAnd<T>(BasicBlock, T);
impl BlockAnd<()> {
/// Unpacks `BlockAnd<()>` into a [`BasicBlock`].
#[must_use]
fn into_block(self) -> BasicBlock {
let Self(block, ()) = self;
block
}
}
trait BlockAndExtension { trait BlockAndExtension {
fn and<T>(self, v: T) -> BlockAnd<T>; fn and<T>(self, v: T) -> BlockAnd<T>;
fn unit(self) -> BlockAnd<()>; fn unit(self) -> BlockAnd<()>;
@ -426,11 +435,6 @@ macro_rules! unpack {
$x = b; $x = b;
v v
}}; }};
($c:expr) => {{
let BlockAnd(b, ()) = $c;
b
}};
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -516,21 +520,22 @@ fn construct_fn<'tcx>(
region::Scope { id: body.id().hir_id.local_id, data: region::ScopeData::Arguments }; region::Scope { id: body.id().hir_id.local_id, data: region::ScopeData::Arguments };
let source_info = builder.source_info(span); let source_info = builder.source_info(span);
let call_site_s = (call_site_scope, source_info); let call_site_s = (call_site_scope, source_info);
unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| { let _: BlockAnd<()> = builder.in_scope(call_site_s, LintLevel::Inherited, |builder| {
let arg_scope_s = (arg_scope, source_info); let arg_scope_s = (arg_scope, source_info);
// Attribute epilogue to function's closing brace // Attribute epilogue to function's closing brace
let fn_end = span_with_body.shrink_to_hi(); let fn_end = span_with_body.shrink_to_hi();
let return_block = let return_block = builder
unpack!(builder.in_breakable_scope(None, Place::return_place(), fn_end, |builder| { .in_breakable_scope(None, Place::return_place(), fn_end, |builder| {
Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| { Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
builder.args_and_body(START_BLOCK, arguments, arg_scope, expr) builder.args_and_body(START_BLOCK, arguments, arg_scope, expr)
})) }))
})); })
.into_block();
let source_info = builder.source_info(fn_end); let source_info = builder.source_info(fn_end);
builder.cfg.terminate(return_block, source_info, TerminatorKind::Return); builder.cfg.terminate(return_block, source_info, TerminatorKind::Return);
builder.build_drop_trees(); builder.build_drop_trees();
return_block.unit() return_block.unit()
})); });
let mut body = builder.finish(); let mut body = builder.finish();

View File

@ -510,12 +510,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let target = self.cfg.start_new_block(); let target = self.cfg.start_new_block();
let source_info = self.source_info(span); let source_info = self.source_info(span);
self.cfg.terminate( self.cfg.terminate(
unpack!(normal_block), normal_block.into_block(),
source_info, source_info,
TerminatorKind::Goto { target }, TerminatorKind::Goto { target },
); );
self.cfg.terminate( self.cfg.terminate(
unpack!(exit_block), exit_block.into_block(),
source_info, source_info,
TerminatorKind::Goto { target }, TerminatorKind::Goto { target },
); );
@ -552,14 +552,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let scope = IfThenScope { region_scope, else_drops: DropTree::new() }; let scope = IfThenScope { region_scope, else_drops: DropTree::new() };
let previous_scope = mem::replace(&mut self.scopes.if_then_scope, Some(scope)); let previous_scope = mem::replace(&mut self.scopes.if_then_scope, Some(scope));
let then_block = unpack!(f(self)); let then_block = f(self).into_block();
let if_then_scope = mem::replace(&mut self.scopes.if_then_scope, previous_scope).unwrap(); let if_then_scope = mem::replace(&mut self.scopes.if_then_scope, previous_scope).unwrap();
assert!(if_then_scope.region_scope == region_scope); assert!(if_then_scope.region_scope == region_scope);
let else_block = self let else_block =
.build_exit_tree(if_then_scope.else_drops, region_scope, span, None) self.build_exit_tree(if_then_scope.else_drops, region_scope, span, None).map_or_else(
.map_or_else(|| self.cfg.start_new_block(), |else_block_and| unpack!(else_block_and)); || self.cfg.start_new_block(),
|else_block_and| else_block_and.into_block(),
);
(then_block, else_block) (then_block, else_block)
} }
@ -753,7 +755,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let unwind_to = if needs_cleanup { self.diverge_cleanup() } else { DropIdx::MAX }; let unwind_to = if needs_cleanup { self.diverge_cleanup() } else { DropIdx::MAX };
let scope = self.scopes.scopes.last().expect("leave_top_scope called with no scopes"); let scope = self.scopes.scopes.last().expect("leave_top_scope called with no scopes");
unpack!(build_scope_drops( build_scope_drops(
&mut self.cfg, &mut self.cfg,
&mut self.scopes.unwind_drops, &mut self.scopes.unwind_drops,
scope, scope,
@ -761,7 +763,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
unwind_to, unwind_to,
is_coroutine && needs_cleanup, is_coroutine && needs_cleanup,
self.arg_count, self.arg_count,
)) )
.into_block()
} }
/// Possibly creates a new source scope if `current_root` and `parent_root` /// Possibly creates a new source scope if `current_root` and `parent_root`