Skip to content

Commit

Permalink
Auto merge of #102906 - nbdd0121:mir, r=wesleywiser,tmiasko
Browse files Browse the repository at this point in the history
Refactor unwind in MIR

This makes unwinding from current `Option<BasicBlock>` into
```rust
enum UnwindAction {
	Continue,
	Cleanup(BasicBlock),
	Unreachable,
	Terminate,
}
```

cc `@JakobDegen` `@RalfJung` `@Amanieu`
  • Loading branch information
bors committed Apr 7, 2023
2 parents b6f6104 + ea69dad commit da14081
Show file tree
Hide file tree
Showing 294 changed files with 1,218 additions and 926 deletions.
7 changes: 5 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/find_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
};
use rustc_data_structures::fx::FxIndexSet;
use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor};
use rustc_middle::mir::{Body, Local, Location};
use rustc_middle::mir::{self, Body, Local, Location};
use rustc_middle::ty::{RegionVid, TyCtxt};

pub(crate) fn find<'tcx>(
Expand Down Expand Up @@ -70,7 +70,10 @@ impl<'cx, 'tcx> UseFinder<'cx, 'tcx> {
block_data
.terminator()
.successors()
.filter(|&bb| Some(&Some(bb)) != block_data.terminator().unwind())
.filter(|&bb| {
Some(&mir::UnwindAction::Cleanup(bb))
!= block_data.terminator().unwind()
})
.map(|bb| Location { statement_index: 0, block: bb }),
);
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_borrowck/src/invalidation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
args,
destination,
target: _,
cleanup: _,
unwind: _,
from_hir_call: _,
fn_span: _,
} => {
Expand All @@ -135,7 +135,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
}
self.mutate_place(location, *destination, Deep);
}
TerminatorKind::Assert { cond, expected: _, msg, target: _, cleanup: _ } => {
TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => {
self.consume_operand(location, cond);
use rustc_middle::mir::AssertKind;
if let AssertKind::BoundsCheck { len, index } = msg {
Expand Down Expand Up @@ -173,7 +173,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
options: _,
line_spans: _,
destination: _,
cleanup: _,
unwind: _,
} => {
for op in operands {
match op {
Expand All @@ -198,7 +198,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
}
}
TerminatorKind::Goto { target: _ }
| TerminatorKind::Abort
| TerminatorKind::Terminate
| TerminatorKind::Unreachable
| TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
| TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => {
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
args,
destination,
target: _,
cleanup: _,
unwind: _,
from_hir_call: _,
fn_span: _,
} => {
Expand All @@ -750,7 +750,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
}
self.mutate_place(loc, (*destination, span), Deep, flow_state);
}
TerminatorKind::Assert { cond, expected: _, msg, target: _, cleanup: _ } => {
TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => {
self.consume_operand(loc, (cond, span), flow_state);
use rustc_middle::mir::AssertKind;
if let AssertKind::BoundsCheck { len, index } = msg {
Expand All @@ -770,7 +770,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
options: _,
line_spans: _,
destination: _,
cleanup: _,
unwind: _,
} => {
for op in operands {
match op {
Expand Down Expand Up @@ -801,7 +801,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
}

TerminatorKind::Goto { target: _ }
| TerminatorKind::Abort
| TerminatorKind::Terminate
| TerminatorKind::Unreachable
| TerminatorKind::Resume
| TerminatorKind::Return
Expand Down Expand Up @@ -845,7 +845,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
}
}

TerminatorKind::Abort
TerminatorKind::Terminate
| TerminatorKind::Assert { .. }
| TerminatorKind::Call { .. }
| TerminatorKind::Drop { .. }
Expand Down
61 changes: 32 additions & 29 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1300,7 +1300,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
match &term.kind {
TerminatorKind::Goto { .. }
| TerminatorKind::Resume
| TerminatorKind::Abort
| TerminatorKind::Terminate
| TerminatorKind::Return
| TerminatorKind::GeneratorDrop
| TerminatorKind::Unreachable
Expand Down Expand Up @@ -1584,7 +1584,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
span_mirbug!(self, block_data, "resume on non-cleanup block!")
}
}
TerminatorKind::Abort => {
TerminatorKind::Terminate => {
if !is_cleanup {
span_mirbug!(self, block_data, "abort on non-cleanup block!")
}
Expand All @@ -1610,49 +1610,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
TerminatorKind::Unreachable => {}
TerminatorKind::Drop { target, unwind, .. }
| TerminatorKind::Assert { target, cleanup: unwind, .. } => {
| TerminatorKind::Assert { target, unwind, .. } => {
self.assert_iscleanup(body, block_data, target, is_cleanup);
if let Some(unwind) = unwind {
if is_cleanup {
span_mirbug!(self, block_data, "unwind on cleanup block")
}
self.assert_iscleanup(body, block_data, unwind, true);
}
self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);
}
TerminatorKind::Call { ref target, cleanup, .. } => {
TerminatorKind::Call { ref target, unwind, .. } => {
if let &Some(target) = target {
self.assert_iscleanup(body, block_data, target, is_cleanup);
}
if let Some(cleanup) = cleanup {
if is_cleanup {
span_mirbug!(self, block_data, "cleanup on cleanup block")
}
self.assert_iscleanup(body, block_data, cleanup, true);
}
self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);
}
TerminatorKind::FalseEdge { real_target, imaginary_target } => {
self.assert_iscleanup(body, block_data, real_target, is_cleanup);
self.assert_iscleanup(body, block_data, imaginary_target, is_cleanup);
}
TerminatorKind::FalseUnwind { real_target, unwind } => {
self.assert_iscleanup(body, block_data, real_target, is_cleanup);
if let Some(unwind) = unwind {
if is_cleanup {
span_mirbug!(self, block_data, "cleanup in cleanup block via false unwind");
}
self.assert_iscleanup(body, block_data, unwind, true);
}
self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);
}
TerminatorKind::InlineAsm { destination, cleanup, .. } => {
TerminatorKind::InlineAsm { destination, unwind, .. } => {
if let Some(target) = destination {
self.assert_iscleanup(body, block_data, target, is_cleanup);
}
if let Some(cleanup) = cleanup {
if is_cleanup {
span_mirbug!(self, block_data, "cleanup on cleanup block")
}
self.assert_iscleanup(body, block_data, cleanup, true);
}
self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);
}
}
}
Expand All @@ -1669,6 +1649,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
}

fn assert_iscleanup_unwind(
&mut self,
body: &Body<'tcx>,
ctxt: &dyn fmt::Debug,
unwind: UnwindAction,
is_cleanup: bool,
) {
match unwind {
UnwindAction::Cleanup(unwind) => {
if is_cleanup {
span_mirbug!(self, ctxt, "unwind on cleanup block")
}
self.assert_iscleanup(body, ctxt, unwind, true);
}
UnwindAction::Continue => {
if is_cleanup {
span_mirbug!(self, ctxt, "unwind on cleanup block")
}
}
UnwindAction::Unreachable | UnwindAction::Terminate => (),
}
}

fn check_local(&mut self, body: &Body<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) {
match body.local_kind(local) {
LocalKind::ReturnPointer | LocalKind::Arg => {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
TerminatorKind::Return => {
crate::abi::codegen_return(fx);
}
TerminatorKind::Assert { cond, expected, msg, target, cleanup: _ } => {
TerminatorKind::Assert { cond, expected, msg, target, unwind: _ } => {
if !fx.tcx.sess.overflow_checks() && msg.is_optional_overflow_check() {
let target = fx.get_block(*target);
fx.bcx.ins().jump(target, &[]);
Expand Down Expand Up @@ -450,7 +450,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
destination,
target,
fn_span,
cleanup: _,
unwind: _,
from_hir_call: _,
} => {
fx.tcx.prof.generic_activity("codegen call").run(|| {
Expand All @@ -470,7 +470,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
options,
destination,
line_spans: _,
cleanup: _,
unwind: _,
} => {
if options.contains(InlineAsmOptions::MAY_UNWIND) {
fx.tcx.sess.span_fatal(
Expand All @@ -488,7 +488,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
*destination,
);
}
TerminatorKind::Abort => {
TerminatorKind::Terminate => {
codegen_panic_cannot_unwind(fx, source_info);
}
TerminatorKind::Resume => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
TerminatorKind::Goto { .. }
| TerminatorKind::SwitchInt { .. }
| TerminatorKind::Resume
| TerminatorKind::Abort
| TerminatorKind::Terminate
| TerminatorKind::Return
| TerminatorKind::Unreachable
| TerminatorKind::Drop { .. }
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_codegen_ssa/src/mir/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,19 +284,19 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi
match data.terminator().kind {
TerminatorKind::Goto { .. }
| TerminatorKind::Resume
| TerminatorKind::Abort
| TerminatorKind::Terminate
| TerminatorKind::Return
| TerminatorKind::GeneratorDrop
| TerminatorKind::Unreachable
| TerminatorKind::SwitchInt { .. }
| TerminatorKind::Yield { .. }
| TerminatorKind::FalseEdge { .. }
| TerminatorKind::FalseUnwind { .. } => { /* nothing to do */ }
TerminatorKind::Call { cleanup: unwind, .. }
| TerminatorKind::InlineAsm { cleanup: unwind, .. }
| TerminatorKind::Assert { cleanup: unwind, .. }
TerminatorKind::Call { unwind, .. }
| TerminatorKind::InlineAsm { unwind, .. }
| TerminatorKind::Assert { unwind, .. }
| TerminatorKind::Drop { unwind, .. } => {
if let Some(unwind) = unwind {
if let mir::UnwindAction::Cleanup(unwind) = unwind {
debug!(
"cleanup_kinds: {:?}/{:?} registering {:?} as funclet",
bb, data, unwind
Expand Down
Loading

0 comments on commit da14081

Please sign in to comment.