From 8cf95cd54b29c210801cae2941abcbbb85051b92 Mon Sep 17 00:00:00 2001 From: Horacio Lisdero Scaffino Date: Sat, 8 Apr 2023 15:15:53 +0200 Subject: [PATCH] Fix major regression in the MIR related to the introduction of the UnwindAction enum. This is the relevant PR that introduced the changes to rustc https://github.com/rust-lang/rust/pull/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 --- README.md | 2 +- src/naming/basic_block.rs | 2 +- src/translator.rs | 4 ++-- src/translator/mir_function.rs | 4 ++-- src/translator/mir_function/basic_block.rs | 12 ++++++------ src/translator/mir_function/terminator.rs | 21 +++++++++++---------- src/translator/mir_visitor.rs | 10 +++++----- 7 files changed, 28 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index edf8307..330e513 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/naming/basic_block.rs b/src/naming/basic_block.rs index 89c9cc2..fec1ac6 100644 --- a/src/naming/basic_block.rs +++ b/src/naming/basic_block.rs @@ -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)) } diff --git a/src/translator.rs b/src/translator.rs index 67e239d..4c0370a 100644 --- a/src/translator.rs +++ b/src/translator.rs @@ -178,7 +178,7 @@ impl<'tcx> Translator<'tcx> { args: &[rustc_middle::mir::Operand<'tcx>], destination: rustc_middle::mir::Place<'tcx>, target: Option, - cleanup: Option, + 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( diff --git a/src/translator/mir_function.rs b/src/translator/mir_function.rs index afc4bb0..175bac1 100644 --- a/src/translator/mir_function.rs +++ b/src/translator/mir_function.rs @@ -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, + 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()); } diff --git a/src/translator/mir_function/basic_block.rs b/src/translator/mir_function/basic_block.rs index 980c670..7673590 100644 --- a/src/translator/mir_function/basic_block.rs +++ b/src/translator/mir_function/basic_block.rs @@ -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), ); } diff --git a/src/translator/mir_function/terminator.rs b/src/translator/mir_function/terminator.rs index 2193ed4..064676e 100644 --- a/src/translator/mir_function/terminator.rs +++ b/src/translator/mir_function/terminator.rs @@ -49,8 +49,8 @@ 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 /// @@ -58,23 +58,24 @@ impl<'tcx> MirFunction<'tcx> { pub fn drop( &mut self, target: rustc_middle::mir::BasicBlock, - unwind: Option, + 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 /// @@ -82,13 +83,13 @@ impl<'tcx> MirFunction<'tcx> { pub fn assert( &mut self, target: rustc_middle::mir::BasicBlock, - cleanup: Option, + 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); diff --git a/src/translator/mir_visitor.rs b/src/translator/mir_visitor.rs index 7a7934b..cdf7a4e 100644 --- a/src/translator/mir_visitor.rs +++ b/src/translator/mir_visitor.rs @@ -81,7 +81,7 @@ impl<'tcx> Visitor<'tcx> for Translator<'tcx> { // 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")