Skip to content

Commit

Permalink
Fix major regression in the MIR related to the introduction of the Un…
Browse files Browse the repository at this point in the history
…windAction enum.

This is the relevant PR that introduced the changes to rustc
rust-lang/rust#102906

Now there a new enum called `UnwindAction`, which may contain in some cases a basic block for the cleanup that we need to handle.

This change requires some renaming to keep some consistency when using the words "unwind" and "cleanup"

All tests are passing again.

Updated the README
  • Loading branch information
hlisdero committed Apr 8, 2023
1 parent e2ca279 commit 8cf95cd
Showing 7 changed files with 28 additions and 27 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ This proves extremely useful to get feedback on the types, compiler errors, etc.

As time goes on and the compiler internals change, the code will inevitably need changes to work again.

**The current state of the repository compiled without warnings and with all tests passing with** `rustc 1.70.0-nightly (700938c07 2023-04-04)`
**The current state of the repository compiled without warnings and with all tests passing with** `rustc 1.70.0-nightly (23ee2af2f 2023-04-07)`

### Installation

2 changes: 1 addition & 1 deletion src/naming/basic_block.rs
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ pub fn drop_transition_label(function_name: &str, index: usize) -> String {

/// Label of the transition that represents the (optional) unwind path of a drop terminator.
#[inline]
pub fn drop_unwind_transition_label(function_name: &str, index: usize) -> String {
pub fn drop_cleanup_transition_label(function_name: &str, index: usize) -> String {
format!("{}_DROP_UNWIND_{index}", sanitize(function_name))
}

4 changes: 2 additions & 2 deletions src/translator.rs
Original file line number Diff line number Diff line change
@@ -178,7 +178,7 @@ impl<'tcx> Translator<'tcx> {
args: &[rustc_middle::mir::Operand<'tcx>],
destination: rustc_middle::mir::Place<'tcx>,
target: Option<rustc_middle::mir::BasicBlock>,
cleanup: Option<rustc_middle::mir::BasicBlock>,
unwind: rustc_middle::mir::UnwindAction,
) {
let current_function = self.call_stack.peek_mut();
let function_def_id =
@@ -208,7 +208,7 @@ impl<'tcx> Translator<'tcx> {
};

let place_refs_for_function_call =
current_function.get_place_refs_for_function_call(return_block, cleanup, &mut self.net);
current_function.get_place_refs_for_function_call(return_block, unwind, &mut self.net);

let function_call = FunctionCall::new(function_def_id, self.tcx);
self.start_function_call(
4 changes: 2 additions & 2 deletions src/translator/mir_function.rs
Original file line number Diff line number Diff line change
@@ -209,7 +209,7 @@ impl<'tcx> MirFunction<'tcx> {
pub fn get_place_refs_for_function_call(
&mut self,
block_number: rustc_middle::mir::BasicBlock,
cleanup_block_number: Option<rustc_middle::mir::BasicBlock>,
unwind: rustc_middle::mir::UnwindAction,
net: &mut PetriNet,
) -> FunctionPlaces {
let active_block = self.get_active_block();
@@ -219,7 +219,7 @@ impl<'tcx> MirFunction<'tcx> {
let end_place = return_block.start_place.clone();

let mut cleanup_place = None;
if let Some(cleanup_block_number) = cleanup_block_number {
if let rustc_middle::mir::UnwindAction::Cleanup(cleanup_block_number) = unwind {
let cleanup_block = self.get_or_add_basic_block(cleanup_block_number, net);
cleanup_place = Some(cleanup_block.start_place.clone());
}
12 changes: 6 additions & 6 deletions src/translator/mir_function/basic_block.rs
Original file line number Diff line number Diff line change
@@ -11,8 +11,8 @@ use crate::data_structures::petri_net_interface::{
};
use crate::data_structures::petri_net_interface::{PetriNet, PlaceRef, TransitionRef};
use crate::naming::basic_block::{
assert_cleanup_transition_label, assert_transition_label, drop_transition_label,
drop_unwind_transition_label, end_place_label, goto_transition_label, start_place_label,
assert_cleanup_transition_label, assert_transition_label, drop_cleanup_transition_label,
drop_transition_label, end_place_label, goto_transition_label, start_place_label,
switch_int_transition_label, unreachable_transition_label, unwind_transition_label,
};

@@ -113,12 +113,12 @@ impl BasicBlock {
transition
}

/// Connects the end place of this block to the start place of the `unwind` basic block.
pub fn drop_unwind(&self, unwind: &Self, net: &mut PetriNet) {
/// Connects the end place of this block to the start place of the `cleanup` basic block.
pub fn drop_cleanup(&self, cleanup: &Self, net: &mut PetriNet) {
self.connect_end_to_next_place(
&unwind.start_place,
&cleanup.start_place,
net,
&drop_unwind_transition_label(&self.function_name, self.index),
&drop_cleanup_transition_label(&self.function_name, self.index),
);
}

21 changes: 11 additions & 10 deletions src/translator/mir_function/terminator.rs
Original file line number Diff line number Diff line change
@@ -49,46 +49,47 @@ impl<'tcx> MirFunction<'tcx> {
/// of the drop terminator.
/// Returns the transition that represents dropping the variable.
///
/// Optionally, if an unwind block is present, connects the active basic block to the next basic
/// block identified as the argument `unwind` of the drop terminator.
/// Optionally, if the unwind action contains a cleanup block, connects the active basic block to the next basic
/// block contained in the argument `unwind` of the drop terminator.
///
/// # Panics
///
/// If there is no active basic block set, then the function panics.
pub fn drop(
&mut self,
target: rustc_middle::mir::BasicBlock,
unwind: Option<rustc_middle::mir::BasicBlock>,
unwind: rustc_middle::mir::UnwindAction,
net: &mut PetriNet,
) -> TransitionRef {
let (active_block, target_block) = self.get_pair_active_block_target_block(target, net);
let transition_drop = active_block.drop(target_block, net);

if let Some(unwind) = unwind {
let (active_block, unwind_block) = self.get_pair_active_block_target_block(unwind, net);
active_block.drop_unwind(unwind_block, net);
if let rustc_middle::mir::UnwindAction::Cleanup(cleanup) = unwind {
let (active_block, cleanup_block) =
self.get_pair_active_block_target_block(cleanup, net);
active_block.drop_cleanup(cleanup_block, net);
};
transition_drop
}

/// Connects the active basic block to the next basic block identified as the argument `target`
/// of the assert terminator.
/// Optionally, if a cleanup block is present, connects the active basic block to the next basic
/// block identified as the argument `cleanup` of the assert terminator.
/// Optionally, if the unwind action contains a cleanup block, connects the active basic block to the next basic
/// block contained in the argument `unwind` of the assert terminator.
///
/// # Panics
///
/// If there is no active basic block set, then the function panics.
pub fn assert(
&mut self,
target: rustc_middle::mir::BasicBlock,
cleanup: Option<rustc_middle::mir::BasicBlock>,
unwind: rustc_middle::mir::UnwindAction,
net: &mut PetriNet,
) {
let (active_block, target_block) = self.get_pair_active_block_target_block(target, net);
active_block.assert(target_block, net);

if let Some(cleanup) = cleanup {
if let rustc_middle::mir::UnwindAction::Cleanup(cleanup) = unwind {
let (active_block, cleanup_block) =
self.get_pair_active_block_target_block(cleanup, net);
active_block.assert_cleanup(cleanup_block, net);
10 changes: 5 additions & 5 deletions src/translator/mir_visitor.rs
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@ impl<'tcx> Visitor<'tcx> for Translator<'tcx> {
// <rustc_middle::mir::terminator::SwitchTargets>
function.switch_int(targets.all_targets().to_vec(), &mut self.net);
}
TerminatorKind::Resume | TerminatorKind::Abort => {
TerminatorKind::Resume | TerminatorKind::Terminate => {
function.unwind(&self.program_panic, &mut self.net);
}
TerminatorKind::Return => {
@@ -108,20 +108,20 @@ impl<'tcx> Visitor<'tcx> for Translator<'tcx> {
ref args,
destination,
target,
cleanup,
unwind,
from_hir_call: _,
fn_span: _,
} => {
self.call_function(func, args, destination, target, cleanup);
self.call_function(func, args, destination, target, unwind);
}
TerminatorKind::Assert {
cond: _,
expected: _,
msg: _,
target,
cleanup,
unwind,
} => {
function.assert(target, cleanup, &mut self.net);
function.assert(target, unwind, &mut self.net);
}
TerminatorKind::Yield { .. } => {
unimplemented!("TerminatorKind::Yield not implemented yet")

0 comments on commit 8cf95cd

Please sign in to comment.