diff options
| author | Gary Guo <gary@garyguo.net> | 2022-10-08 23:47:59 +0100 |
|---|---|---|
| committer | Gary Guo <gary@garyguo.net> | 2023-04-06 09:34:16 +0100 |
| commit | daeb844e0ccddb9e058128974b290f2022e88be7 (patch) | |
| tree | 2d0be78154d1f2748841b79cded649158b2a012a | |
| parent | 7f6edd3f15f75f0df70027edee2a520820d14217 (diff) | |
| download | rust-daeb844e0ccddb9e058128974b290f2022e88be7.tar.gz rust-daeb844e0ccddb9e058128974b290f2022e88be7.zip | |
Refactor unwind from Option to a new enum
39 files changed, 328 insertions, 250 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs index fd1fda2ee4b..e2d04324f3b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs @@ -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>( @@ -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 }), ); } diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index a71c4163286..f69b35549b4 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -125,7 +125,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { args, destination, target: _, - cleanup: _, + unwind: _, from_hir_call: _, fn_span: _, } => { @@ -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 { @@ -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 { diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 1d4d1406239..4787b0ea4e9 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -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: _, } => { @@ -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 { @@ -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 { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 2fc4e32ecb2..10332c6d9b5 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1610,20 +1610,20 @@ 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 let UnwindAction::Cleanup(unwind) = unwind { if is_cleanup { span_mirbug!(self, block_data, "unwind on cleanup block") } self.assert_iscleanup(body, block_data, unwind, true); } } - 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 let UnwindAction::Cleanup(cleanup) = unwind { if is_cleanup { span_mirbug!(self, block_data, "cleanup on cleanup block") } @@ -1636,18 +1636,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } TerminatorKind::FalseUnwind { real_target, unwind } => { self.assert_iscleanup(body, block_data, real_target, is_cleanup); - if let Some(unwind) = unwind { + if let UnwindAction::Cleanup(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); } } - 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 let UnwindAction::Cleanup(cleanup) = unwind { if is_cleanup { span_mirbug!(self, block_data, "cleanup on cleanup block") } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 2630f02e6eb..94413318492 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -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, &[]); @@ -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(|| { @@ -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( diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index dcf533dc39c..7d1c80ba88f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -292,11 +292,11 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi | 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 diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index c086d1b7f5a..a6891a8ff2f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -156,7 +156,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { fn_ptr: Bx::Value, llargs: &[Bx::Value], destination: Option<(ReturnDest<'tcx, Bx::Value>, mir::BasicBlock)>, - cleanup: Option<mir::BasicBlock>, + unwind: mir::UnwindAction, copied_constant_arguments: &[PlaceRef<'tcx, <Bx as BackendTypes>::Value>], mergeable_succ: bool, ) -> MergingSucc { @@ -164,6 +164,10 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { // do an invoke, otherwise do a call. let fn_ty = bx.fn_decl_backend_type(&fn_abi); + let cleanup = match unwind { + mir::UnwindAction::Cleanup(cleanup) => Some(cleanup), + mir::UnwindAction::Continue => None, + }; let unwind_block = if let Some(cleanup) = cleanup.filter(|_| fn_abi.can_unwind) { Some(self.llbb_with_cleanup(fx, cleanup)) } else if fx.mir[self.bb].is_cleanup @@ -244,11 +248,11 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { options: InlineAsmOptions, line_spans: &[Span], destination: Option<mir::BasicBlock>, - cleanup: Option<mir::BasicBlock>, + unwind: mir::UnwindAction, instance: Instance<'_>, mergeable_succ: bool, ) -> MergingSucc { - if let Some(cleanup) = cleanup { + if let mir::UnwindAction::Cleanup(cleanup) = unwind { let ret_llbb = if let Some(target) = destination { fx.llbb(target) } else { @@ -431,7 +435,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx: &mut Bx, location: mir::Place<'tcx>, target: mir::BasicBlock, - unwind: Option<mir::BasicBlock>, + unwind: mir::UnwindAction, mergeable_succ: bool, ) -> MergingSucc { let ty = location.ty(self.mir, bx.tcx()).ty; @@ -552,7 +556,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { expected: bool, msg: &mir::AssertMessage<'tcx>, target: mir::BasicBlock, - cleanup: Option<mir::BasicBlock>, + unwind: mir::UnwindAction, mergeable_succ: bool, ) -> MergingSucc { let span = terminator.source_info.span; @@ -618,7 +622,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (fn_abi, llfn) = common::build_langcall(bx, Some(span), lang_item); // Codegen the actual panic invoke/call. - let merging_succ = helper.do_call(self, bx, fn_abi, llfn, &args, None, cleanup, &[], false); + let merging_succ = helper.do_call(self, bx, fn_abi, llfn, &args, None, unwind, &[], false); assert_eq!(merging_succ, MergingSucc::False); MergingSucc::False } @@ -636,7 +640,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (fn_abi, llfn) = common::build_langcall(bx, Some(span), LangItem::PanicCannotUnwind); // Codegen the actual panic invoke/call. - let merging_succ = helper.do_call(self, bx, fn_abi, llfn, &[], None, None, &[], false); + let merging_succ = helper.do_call(self, bx, fn_abi, llfn, &[], None, mir::UnwindAction::Continue, &[], false); assert_eq!(merging_succ, MergingSucc::False); } @@ -649,7 +653,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { instance: Option<Instance<'tcx>>, source_info: mir::SourceInfo, target: Option<mir::BasicBlock>, - cleanup: Option<mir::BasicBlock>, + unwind: mir::UnwindAction, mergeable_succ: bool, ) -> Option<MergingSucc> { // Emit a panic or a no-op for `assert_*` intrinsics. @@ -696,7 +700,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llfn, &[msg.0, msg.1], target.as_ref().map(|bb| (ReturnDest::Nothing, *bb)), - cleanup, + unwind, &[], mergeable_succ, ) @@ -719,7 +723,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { args: &[mir::Operand<'tcx>], destination: mir::Place<'tcx>, target: Option<mir::BasicBlock>, - cleanup: Option<mir::BasicBlock>, + unwind: mir::UnwindAction, fn_span: Span, mergeable_succ: bool, ) -> MergingSucc { @@ -783,7 +787,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { instance, source_info, target, - cleanup, + unwind, mergeable_succ, ) { return merging_succ; @@ -1064,7 +1068,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_ptr, &llargs, target.as_ref().map(|&target| (ret_dest, target)), - cleanup, + unwind, &copied_constant_arguments, false, ); @@ -1084,7 +1088,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_ptr, &llargs, target.as_ref().map(|&target| (ret_dest, target)), - cleanup, + unwind, &copied_constant_arguments, mergeable_succ, ) @@ -1100,7 +1104,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { options: ast::InlineAsmOptions, line_spans: &[Span], destination: Option<mir::BasicBlock>, - cleanup: Option<mir::BasicBlock>, + unwind: mir::UnwindAction, instance: Instance<'_>, mergeable_succ: bool, ) -> MergingSucc { @@ -1164,7 +1168,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { options, line_spans, destination, - cleanup, + unwind, instance, mergeable_succ, ) @@ -1274,7 +1278,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_drop_terminator(helper, bx, place, target, unwind, mergeable_succ()) } - mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, cleanup } => self + mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, unwind } => self .codegen_assert_terminator( helper, bx, @@ -1283,7 +1287,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { expected, msg, target, - cleanup, + unwind, mergeable_succ(), ), @@ -1292,7 +1296,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ref args, destination, target, - cleanup, + unwind, from_hir_call: _, fn_span, } => self.codegen_call_terminator( @@ -1303,7 +1307,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { args, destination, target, - cleanup, + unwind, fn_span, mergeable_succ(), ), @@ -1320,7 +1324,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { options, line_spans, destination, - cleanup, + unwind, } => self.codegen_asm_terminator( helper, bx, @@ -1330,7 +1334,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { options, line_spans, destination, - cleanup, + unwind, self.instance, mergeable_succ(), ), diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index c87ea18af4f..5fd99a9a84a 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -526,7 +526,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, fn assert_panic( ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &AssertMessage<'tcx>, - _unwind: Option<mir::BasicBlock>, + _unwind: mir::UnwindAction, ) -> InterpResult<'tcx> { use rustc_middle::mir::AssertKind::*; // Convert `AssertKind<Operand>` to `AssertKind<Scalar>`. diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index aca68dc454b..ca4da29ebbd 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -215,7 +215,7 @@ pub trait Machine<'mir, 'tcx>: Sized { fn assert_panic( ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &mir::AssertMessage<'tcx>, - unwind: Option<mir::BasicBlock>, + unwind: mir::UnwindAction, ) -> InterpResult<'tcx>; /// Called to evaluate `Abort` MIR terminator. diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 2d9fee9852c..2546423d4cc 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -60,7 +60,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ref args, destination, target, - ref cleanup, + ref unwind, from_hir_call: _, fn_span: _, } => { @@ -106,9 +106,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { with_caller_location, &destination, target, - match (cleanup, fn_abi.can_unwind) { - (Some(cleanup), true) => StackPopUnwind::Cleanup(*cleanup), - (None, true) => StackPopUnwind::Skip, + match (unwind, fn_abi.can_unwind) { + (mir::UnwindAction::Cleanup(cleanup), true) => { + StackPopUnwind::Cleanup(*cleanup) + } + (mir::UnwindAction::Continue, true) => StackPopUnwind::Skip, (_, false) => StackPopUnwind::NotAllowed, }, )?; @@ -137,14 +139,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.drop_in_place(&place, instance, target, unwind)?; } - Assert { ref cond, expected, ref msg, target, cleanup } => { + Assert { ref cond, expected, ref msg, target, unwind } => { let ignored = M::ignore_optional_overflow_checks(self) && msg.is_optional_overflow_check(); let cond_val = self.read_scalar(&self.eval_operand(cond, None)?)?.to_bool()?; if ignored || expected == cond_val { self.go_to_block(target); } else { - M::assert_panic(self, msg, cleanup)?; + M::assert_panic(self, msg, unwind)?; } } @@ -676,7 +678,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { place: &PlaceTy<'tcx, M::Provenance>, instance: ty::Instance<'tcx>, target: mir::BasicBlock, - unwind: Option<mir::BasicBlock>, + unwind: mir::UnwindAction, ) -> InterpResult<'tcx> { trace!("drop_in_place: {:?},\n {:?}, {:?}", *place, place.layout.ty, instance); // We take the address of the object. This may well be unaligned, which is fine @@ -718,8 +720,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &ret.into(), Some(target), match unwind { - Some(cleanup) => StackPopUnwind::Cleanup(cleanup), - None => StackPopUnwind::Skip, + mir::UnwindAction::Cleanup(cleanup) => StackPopUnwind::Cleanup(cleanup), + mir::UnwindAction::Continue => StackPopUnwind::Skip, }, ) } diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 6774e5a5837..7919aed097a 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -807,7 +807,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { kind: TerminatorKind::Call { func, args, - cleanup: None, + unwind: UnwindAction::Continue, destination: Place::from(new_temp), target: Some(new_target), from_hir_call, diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index e798c9d236e..be840ef6f7f 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -10,7 +10,7 @@ use rustc_middle::mir::{ traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location, MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator, - TerminatorKind, UnOp, VarDebugInfo, VarDebugInfoContents, START_BLOCK, + TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents, START_BLOCK, }; use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; use rustc_mir_dataflow::impls::MaybeStorageLive; @@ -902,11 +902,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } TerminatorKind::Drop { target, unwind, .. } => { self.check_edge(location, *target, EdgeKind::Normal); - if let Some(unwind) = unwind { + if let UnwindAction::Cleanup(unwind) = unwind { self.check_edge(location, *unwind, EdgeKind::Unwind); } } - TerminatorKind::Call { func, args, destination, target, cleanup, .. } => { + TerminatorKind::Call { func, args, destination, target, unwind, .. } => { let func_ty = func.ty(&self.body.local_decls, self.tcx); match func_ty.kind() { ty::FnPtr(..) | ty::FnDef(..) => {} @@ -918,7 +918,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if let Some(target) = target { self.check_edge(location, *target, EdgeKind::Normal); } - if let Some(cleanup) = cleanup { + if let UnwindAction::Cleanup(cleanup) = unwind { self.check_edge(location, *cleanup, EdgeKind::Unwind); } @@ -946,7 +946,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } } - TerminatorKind::Assert { cond, target, cleanup, .. } => { + TerminatorKind::Assert { cond, target, unwind, .. } => { let cond_ty = cond.ty(&self.body.local_decls, self.tcx); if cond_ty != self.tcx.types.bool { self.fail( @@ -958,7 +958,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } self.check_edge(location, *target, EdgeKind::Normal); - if let Some(cleanup) = cleanup { + if let UnwindAction::Cleanup(cleanup) = unwind { self.check_edge(location, *cleanup, EdgeKind::Unwind); } } @@ -992,15 +992,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } self.check_edge(location, *real_target, EdgeKind::Normal); - if let Some(unwind) = unwind { + if let UnwindAction::Cleanup(unwind) = unwind { self.check_edge(location, *unwind, EdgeKind::Unwind); } } - TerminatorKind::InlineAsm { destination, cleanup, .. } => { + TerminatorKind::InlineAsm { destination, unwind, .. } => { if let Some(destination) = destination { self.check_edge(location, *destination, EdgeKind::Normal); } - if let Some(cleanup) = cleanup { + if let UnwindAction::Cleanup(cleanup) = unwind { self.check_edge(location, *cleanup, EdgeKind::Unwind); } } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index cc35e6106e2..c2a12bb3b66 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -515,14 +515,14 @@ pub struct CopyNonOverlapping<'tcx> { /// /// A note on unwinding: Panics may occur during the execution of some terminators. Depending on the /// `-C panic` flag, this may either cause the program to abort or the call stack to unwind. Such -/// terminators have a `cleanup: Option<BasicBlock>` field on them. If stack unwinding occurs, then -/// once the current function is reached, execution continues at the given basic block, if any. If -/// `cleanup` is `None` then no cleanup is performed, and the stack continues unwinding. This is -/// equivalent to the execution of a `Resume` terminator. +/// terminators have a `unwind: UnwindAction` field on them. If stack unwinding occurs, then +/// once the current function is reached, an action will be taken based on the `unwind` field. +/// If the action is `Cleanup`, then the execution continues at the given basic block. If the +/// action is `Continue` then no cleanup is performed, and the stack continues unwinding. /// -/// The basic block pointed to by a `cleanup` field must have its `cleanup` flag set. `cleanup` -/// basic blocks have a couple restrictions: -/// 1. All `cleanup` fields in them must be `None`. +/// The basic block pointed to by a `Cleanup` unwind action must have its `cleanup` flag set. +/// `cleanup` basic blocks have a couple restrictions: +/// 1. All `unwind` fields in them must be `UnwindAction::Continue`. /// 2. `Return` terminators are not allowed in them. `Abort` and `Unwind` terminators are. /// 3. All other basic blocks (in the current body) that are reachable from `cleanup` basic blocks /// must also be `cleanup`. This is a part of the type system and checked statically, so it is @@ -604,7 +604,7 @@ pub enum TerminatorKind<'tcx> { /// > The drop glue is executed if, among all statements executed within this `Body`, an assignment to /// > the place or one of its "parents" occurred more recently than a move out of it. This does not /// > consider indirect assignments. - Drop { place: Place<'tcx>, target: BasicBlock, unwind: Option<BasicBlock> }, + Drop { place: Place<'tcx>, target: BasicBlock, unwind: UnwindAction }, /// Roughly speaking, evaluates the `func` operand and the arguments, and starts execution of /// the referred to function. The operand types must match the argument types of the function. @@ -628,8 +628,8 @@ pub enum TerminatorKind<'tcx> { destination: Place<'tcx>, /// Where to go after this call returns. If none, the call necessarily diverges. target: Option<BasicBlock>, - /// Cleanups to be done if the call unwinds. - cleanup: Option<BasicBlock>, + /// Action to be taken if the call unwinds. + unwind: UnwindAction, /// `true` if this is from a call in HIR rather than from an overloaded /// operator. True for overloaded function call. from_hir_call: bool, @@ -654,7 +654,7 @@ pub enum TerminatorKind<'tcx> { expected: bool, msg: AssertMessage<'tcx>, target: BasicBlock, - cleanup: Option<BasicBlock>, + unwind: UnwindAction, }, /// Marks a suspend point. @@ -720,9 +720,10 @@ pub enum TerminatorKind<'tcx> { /// in practice, but in order to avoid fragility we want to always /// consider it in borrowck. We don't want to accept programs which /// pass borrowck only when `panic=abort` or some assertions are disabled - /// due to release vs. debug mode builds. This needs to be an `Option` because + /// due to release vs. debug mode builds. + /// This field does not necessary have to be `UnwindAction::Cleanup` because /// of the `remove_noop_landing_pads` and `abort_unwinding_calls` passes. - unwind: Option<BasicBlock>, + unwind: UnwindAction, }, /// Block ends with an inline assembly block. This is a terminator since @@ -745,12 +746,22 @@ pub enum TerminatorKind<'tcx> { /// diverging (InlineAsmOptions::NORETURN). destination: Option<BasicBlock>, - /// Cleanup to be done if the inline assembly unwinds. This is present + /// Action to be taken if the inline assembly unwinds. This is present /// if and only if InlineAsmOptions::MAY_UNWIND is set. - cleanup: Option<BasicBlock>, + unwind: UnwindAction, }, } +/// Action to be taken when a stack unwind happens. +#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] +pub enum UnwindAction { + // No action is to be taken. Continue unwinding. + Continue, + // Cleanups to be done. + Cleanup(BasicBlock), +} + /// Information about an assertion failure. #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)] pub enum AssertKind<O> { diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index cd970270727..19aa01c12bd 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -1,6 +1,6 @@ use smallvec::SmallVec; -use super::{BasicBlock, InlineAsmOperand, Operand, SourceInfo, TerminatorKind}; +use super::{BasicBlock, InlineAsmOperand, Operand, SourceInfo, TerminatorKind, UnwindAction}; use rustc_ast::InlineAsmTemplatePiece; pub use rustc_ast::Mutability; use rustc_macros::HashStable; @@ -118,11 +118,11 @@ impl<'tcx> Terminator<'tcx> { self.kind.successors_mut() } - pub fn unwind(&self) -> Option<&Option<BasicBlock>> { + pub fn unwind(&self) -> Option<&UnwindAction> { self.kind.unwind() } - pub fn unwind_mut(&mut self) -> Option<&mut Option<BasicBlock>> { + pub fn unwind_mut(&mut self) -> Option<&mut UnwindAction> { self.kind.unwind_mut() } } @@ -135,34 +135,34 @@ impl<'tcx> TerminatorKind<'tcx> { pub fn successors(&self) -> Successors<'_> { use self::TerminatorKind::*; match *self { + Call { target: Some(t), unwind: UnwindAction::Cleanup(ref u), .. } + | Yield { resume: t, drop: Some(ref u), .. } + | Drop { target: t, unwind: UnwindAction::Cleanup(ref u), .. } + | Assert { target: t, unwind: UnwindAction::Cleanup(ref u), .. } + | FalseUnwind { real_target: t, unwind: UnwindAction::Cleanup(ref u) } + | InlineAsm { destination: Some(t), unwind: UnwindAction::Cleanup(ref u), .. } => { + Some(t).into_iter().chain(slice::from_ref(u).into_iter().copied()) + } + Goto { target: t } + | Call { target: None, unwind: UnwindAction::Cleanup(t), .. } + | Call { target: Some(t), unwind: _, .. } + | Yield { resume: t, drop: None, .. } + | Drop { target: t, unwind: _, .. } + | Assert { target: t, unwind: _, .. } + | FalseUnwind { real_target: t, unwind: _ } + | InlineAsm { destination: None, unwind: UnwindAction::Cleanup(t), .. } + | InlineAsm { destination: Some(t), unwind: _, .. } => { + Some(t).into_iter().chain((&[]).into_iter().copied()) + } Resume | Abort | GeneratorDrop | Return | Unreachable - | Call { target: None, cleanup: None, .. } - | InlineAsm { destination: None, cleanup: None, .. } => { + | Call { target: None, unwind: _, .. } + | InlineAsm { destination: None, unwind: _, .. } => { None.into_iter().chain((&[]).into_iter().copied()) } - Goto { target: t } - | Call { target: None, cleanup: Some(t), .. } - | Call { target: Some(t), cleanup: None, .. } - | Yield { resume: t, drop: None, .. } - | Drop { target: t, unwind: None, .. } - | Assert { target: t, cleanup: None, .. } - | FalseUnwind { real_target: t, unwind: None } - | InlineAsm { destination: Some(t), cleanup: None, .. } - | InlineAsm { destination: None, cleanup: Some(t), .. } => { - Some(t).into_iter().chain((&[]).into_iter().copied()) - } - Call { target: Some(t), cleanup: Some(ref u), .. } - | Yield { resume: t, drop: Some(ref u), .. } - | Drop { target: t, unwind: Some(ref u), .. } - | Assert { target: t, cleanup: Some(ref u), .. } - | FalseUnwind { real_target: t, unwind: Some(ref u) } - | InlineAsm { destination: Some(t), cleanup: Some(ref u), .. } => { - Some(t).into_iter().chain(slice::from_ref(u).into_iter().copied()) - } SwitchInt { ref targets, .. } => { None.into_iter().chain(targets.targets.iter().copied()) } @@ -175,32 +175,34 @@ impl<'tcx> TerminatorKind<'tcx> { pub fn successors_mut(&mut self) -> SuccessorsMut<'_> { use self::TerminatorKind::*; match *self { + Call { target: Some(ref mut t), unwind: UnwindAction::Cleanup(ref mut u), .. } + | Yield { resume: ref mut t, drop: Some(ref mut u), .. } + | Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. } + | Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. } + | FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) } + | InlineAsm { + destination: Some(ref mut t), + unwind: UnwindAction::Cleanup(ref mut u), + .. + } => Some(t).into_iter().chain(slice::from_mut(u)), + Goto { target: ref mut t } + | Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. } + | Call { target: Some(ref mut t), unwind: _, .. } + | Yield { resume: ref mut t, drop: None, .. } + | Drop { target: ref mut t, unwind: _, .. } + | Assert { target: ref mut t, unwind: _, .. } + | FalseUnwind { real_target: ref mut t, unwind: _ } + | InlineAsm { destination: None, unwind: UnwindAction::Cleanup(ref mut t), .. } + | InlineAsm { destination: Some(ref mut t), unwind: _, .. } => { + Some(t).into_iter().chain(&mut []) + } Resume | Abort | GeneratorDrop | Return | Unreachable - | Call { target: None, cleanup: None, .. } - | InlineAsm { destination: None, cleanup: None, .. } => None.into_iter().chain(&mut []), - Goto { target: ref mut t } - | Call { target: None, cleanup: Some(ref mut t), .. } - | Call { target: Some(ref mut t), cleanup: None, .. } - | Yield { resume: ref mut t, drop: None, .. } - | Drop { target: ref mut t, unwind: None, .. } - | Assert { target: ref mut t, cleanup: None, .. } - | FalseUnwind { real_target: ref mut t, unwind: None } - | InlineAsm { destination: Some(ref mut t), cleanup: None, .. } - | InlineAsm { destination: None, cleanup: Some(ref mut t), .. } => { - Some(t).into_iter().chain(&mut []) - } - Call { target: Some(ref mut t), cleanup: Some(ref mut u), .. } - | Yield { resume: ref mut t, drop: Some(ref mut u), .. } - | Drop { target: ref mut t, unwind: Some(ref mut u), .. } - | Assert { target: ref mut t, cleanup: Some(ref mut u), .. } - | FalseUnwind { real_target: ref mut t, unwind: Some(ref mut u) } - | InlineAsm { destination: Some(ref mut t), cleanup: Some(ref mut u), .. } => { - Some(t).into_iter().chain(slice::from_mut(u)) - } + | Call { target: None, unwind: _, .. } + | InlineAsm { destination: None, unwind: _, .. } => None.into_iter().chain(&mut []), SwitchInt { ref mut targets, .. } => None.into_iter().chain(&mut targets.targets), FalseEdge { ref mut real_target, ref mut imaginary_target } => { Some(real_target).into_iter().chain(slice::from_mut(imaginary_target)) @@ -208,7 +210,7 @@ impl<'tcx> TerminatorKind<'tcx> { } } - pub fn unwind(&self) -> Option<&Option<BasicBlock>> { + pub fn unwind(&self) -> Option<&UnwindAction> { match *self { TerminatorKind::Goto { .. } | TerminatorKind::Resume @@ -219,15 +221,15 @@ impl<'tcx> TerminatorKind<'tcx> { | TerminatorKind::Yield { .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::FalseEdge { .. } => None, - TerminatorKind::Call { cleanup: ref unwind, .. } - | TerminatorKind::Assert { cleanup: ref unwind, .. } + TerminatorKind::Call { ref unwind, .. } + | TerminatorKind::Assert { ref unwind, .. } | TerminatorKind::Drop { ref unwind, .. } | TerminatorKind::FalseUnwind { ref unwind, .. } - | TerminatorKind::InlineAsm { cleanup: ref unwind, .. } => Some(unwind), + | TerminatorKind::InlineAsm { ref unwind, .. } => Some(unwind), } } - pub fn unwind_mut(&mut self) -> Option<&mut Option<BasicBlock>> { + pub fn unwind_mut(&mut self) -> Option<&mut UnwindAction> { match *self { TerminatorKind::Goto { .. } | TerminatorKind::Resume @@ -238,11 +240,11 @@ impl<'tcx> TerminatorKind<'tcx> { | TerminatorKind::Yield { .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::FalseEdge { .. } => None, - TerminatorKind::Call { cleanup: ref mut unwind, .. } - | TerminatorKind::Assert { cleanup: ref mut unwind, .. } + TerminatorKind::Call { ref mut unwind, .. } + | TerminatorKind::Assert { ref mut unwind, .. } | TerminatorKind::Drop { ref mut unwind, .. } | TerminatorKind::FalseUnwind { ref mut unwind, .. } - | TerminatorKind::InlineAsm { cleanup: ref mut unwind, .. } => Some(unwind), + | TerminatorKind::InlineAsm { ref mut unwind, .. } => Some(unwind), } } @@ -386,31 +388,33 @@ impl<'tcx> TerminatorKind<'tcx> { .map(|&u| Cow::Owned(u.to_string())) .chain(iter::once("otherwise".into())) .collect(), - Call { target: Some(_), cleanup: Some(_), .. } => { + Call { target: Some(_), unwind: UnwindAction::Cleanup(_), .. } => { vec!["return".into(), "unwind".into()] } - Call { target: Some(_), cleanup: None, .. } => vec!["return".into()], - Call { target: None, cleanup: Some(_), .. } => vec!["unwind".into()], - Call { target: None, cleanup: None, .. } => vec![], + Call { target: Some(_), unwind: UnwindAction::Continue, .. } => vec!["return".into()], + Call { target: None, unwind: UnwindAction::Cleanup(_), .. } => vec!["unwind".into()], + Call { target: None, unwind: UnwindAction::Continue, .. } => vec![], Yield { drop: Some(_), .. } => vec!["resume".into(), "drop".into()], Yield { drop: None, .. } => vec!["resume".into()], - Drop { unwind: None, .. } => { - vec!["return".into()] - } - Drop { unwind: Some(_), .. } => { - vec!["return".into(), "unwind".into()] - } - Assert { cleanup: None, .. } => vec!["".into()], + Drop { unwind: UnwindAction::Continue, .. } => vec!["return".into()], + Drop { unwind: UnwindAction::Cleanup(_), .. } => vec!["return".into(), "unwind".into()], + Assert { unwind: UnwindAction::Continue, .. } => vec!["".into()], Assert { .. } => vec!["success".into(), "unwind".into()], FalseEdge { .. } => vec!["real".into(), "imaginary".into()], - FalseUnwind { unwind: Some(_), .. } => vec!["real".into(), "cleanup".into()], - FalseUnwind { unwind: None, .. } => vec!["real".into()], - InlineAsm { destination: Some(_), cleanup: Some(_), .. } => { + FalseUnwind { unwind: UnwindAction::Cleanup(_), .. } => { + vec!["real".into(), "cleanup".into()] + } + FalseUnwind { unwind: UnwindAction::Continue, .. } => vec!["real".into()], + InlineAsm { destination: Some(_), unwind: UnwindAction::Cleanup(_), .. } => { vec!["return".into(), "unwind".into()] } - InlineAsm { destination: Some(_), cleanup: None, .. } => vec!["return".into()], - InlineAsm { destination: None, cleanup: Some(_), .. } => vec!["unwind".into()], - InlineAsm { destination: None, cleanup: None, .. } => vec![], + InlineAsm { destination: Some(_), unwind: UnwindAction::Continue, .. } => { + vec!["return".into()] + } + InlineAsm { destination: None, unwind: UnwindAction::Cleanup(_), .. } => { + vec!["unwind".into()] + } + InlineAsm { destination: None, unwind: UnwindAction::Continue, .. } => vec![], } } } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 7aa446ae966..243c62f4a9c 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -509,7 +509,7 @@ macro_rules! make_mir_visitor { args, destination, target: _, - cleanup: _, + unwind: _, from_hir_call: _, fn_span: _ } => { @@ -529,7 +529,7 @@ macro_rules! make_mir_visitor { expected: _, msg, target: _, - cleanup: _, + unwind: _, } => { self.visit_operand(cond, location); self.visit_assert_message(msg, location); @@ -555,7 +555,7 @@ macro_rules! make_mir_visitor { options: _, line_spans: _, destination: _, - cleanup: _, + unwind: _, } => { for op in operands { match op { diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index baa12ec11c3..8631749a524 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -171,7 +171,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { args: vec![Operand::Move(size), Operand::Move(align)], destination: storage, target: Some(success), - cleanup: None, + unwind: UnwindAction::Continue, from_hir_call: false, fn_span: expr_span, }, @@ -702,7 +702,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.cfg.terminate( block, outer_source_info, - TerminatorKind::Drop { place: to_drop, target: success, unwind: None }, + TerminatorKind::Drop { + place: to_drop, + target: success, + unwind: UnwindAction::Continue, + }, ); this.diverge_from(block); block = success; diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 8efaba1f602..bafe7ede3d9 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -228,7 +228,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.cfg.terminate( loop_block, source_info, - TerminatorKind::FalseUnwind { real_target: body_block, unwind: None }, + TerminatorKind::FalseUnwind { + real_target: body_block, + unwind: UnwindAction::Continue, + }, ); this.diverge_from(loop_block); @@ -264,7 +267,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TerminatorKind::Call { func: fun, args, - cleanup: None, + unwind: UnwindAction::Continue, destination, // The presence or absence of a return edge affects control-flow sensitive // MIR checks and ultimately whether code is accepted or not. We can only @@ -466,7 +469,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } else { Some(destination_block) }, - cleanup: None, + unwind: UnwindAction::Continue, }, ); if options.contains(InlineAsmOptions::MAY_UNWIND) { diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 2de89f67dfd..8a03ea7e2cc 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -263,7 +263,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { args: vec![Operand::Move(ref_string)], destination: ref_str, target: Some(eq_block), - cleanup: None, + unwind: UnwindAction::Continue, from_hir_call: false, fn_span: source_info.span } @@ -466,7 +466,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { args: vec![val, expect], destination: eq_result, target: Some(eq_block), - cleanup: None, + unwind: UnwindAction::Continue, from_hir_call: false, fn_span: source_info.span, }, diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 25af221bf36..f67659ac6bf 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -369,7 +369,7 @@ impl DropTree { let terminator = TerminatorKind::Drop { target: blocks[drop_data.1].unwrap(), // The caller will handle this if needed. - unwind: None, + unwind: UnwindAction::Continue, place: drop_data.0.local.into(), }; cfg.terminate(block, drop_data.0.source_info, terminator); @@ -1141,7 +1141,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.terminate( block, source_info, - TerminatorKind::Drop { place, target: assign, unwind: Some(assign_unwind) }, + TerminatorKind::Drop { + place, + target: assign, + unwind: UnwindAction::Cleanup(assign_unwind), + }, ); self.diverge_from(block); @@ -1165,7 +1169,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.terminate( block, source_info, - TerminatorKind::Assert { cond, expected, msg, target: success_block, cleanup: None }, + TerminatorKind::Assert { + cond, + expected, + msg, + target: success_block, + unwind: UnwindAction::Continue, + }, ); self.diverge_from(block); @@ -1244,7 +1254,11 @@ fn build_scope_drops<'tcx>( cfg.terminate( block, source_info, - TerminatorKind::Drop { place: local.into(), target: next, unwind: None }, + TerminatorKind::Drop { + place: local.into(), + target: next, + unwind: UnwindAction::Continue, + }, ); block = next; } @@ -1432,10 +1446,10 @@ impl<'tcx> DropTreeBuilder<'tcx> for Unwind { } } TerminatorKind::FalseUnwind { unwind, .. } - | TerminatorKind::Call { cleanup: unwind, .. } - | TerminatorKind::Assert { cleanup: unwind, .. } - | TerminatorKind::InlineAsm { cleanup: unwind, .. } => { - *unwind = Some(to); + | TerminatorKind::Call { unwind, .. } + | TerminatorKind::Assert { unwind, .. } + | TerminatorKind::InlineAsm { unwind, .. } => { + *unwind = UnwindAction::Cleanup(to); } TerminatorKind::Goto { .. } | TerminatorKind::SwitchInt { .. } diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index 8937b78fe34..910db7f676d 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -3,7 +3,7 @@ use rustc_data_structures::graph::iterate::{ NodeStatus, TriColorDepthFirstSearch, TriColorVisitor, }; use rustc_hir::def::DefKind; -use rustc_middle::mir::{BasicBlock, BasicBlocks, Body, Operand, TerminatorKind}; +use rustc_middle::mir::{self, BasicBlock, BasicBlocks, Body, Operand, TerminatorKind}; use rustc_middle::ty::subst::{GenericArg, InternalSubsts}; use rustc_middle::ty::{self, Instance, TyCtxt}; use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION; @@ -149,7 +149,9 @@ impl<'mir, 'tcx> TriColorVisitor<BasicBlocks<'tcx>> for Search<'mir, 'tcx> { fn ignore_edge(&mut self, bb: BasicBlock, target: BasicBlock) -> bool { let terminator = self.body[bb].terminator(); - if terminator.unwind() == Some(&Some(target)) && terminator.successors().count() > 1 { + if terminator.unwind() == Some(&mir::UnwindAction::Cleanup(target)) + && terminator.successors().count() > 1 + { return true; } // Don't traverse successors of recursive calls or false CFG edges. diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 7ef3d41ac48..70ed0c22640 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -77,10 +77,10 @@ impl Unwind { } } - fn into_option(self) -> Option<BasicBlock> { + fn into_action(self) -> UnwindAction { match self { - Unwind::To(bb) => Some(bb), - Unwind::InCleanup => None, + Unwind::To(bb) => UnwindAction::Cleanup(bb), + Unwind::InCleanup => UnwindAction::Continue, } } @@ -236,7 +236,7 @@ where TerminatorKind::Drop { place: self.place, target: self.succ, - unwind: self.unwind.into_option(), + unwind: self.unwind.into_action(), }, ); } @@ -640,7 +640,7 @@ where args: vec![Operand::Move(Place::from(ref_place))], destination: unit_temp, target: Some(succ), - cleanup: unwind.into_option(), + unwind: unwind.into_action(), from_hir_call: true, fn_span: self.source_info.span, }, @@ -717,7 +717,7 @@ where TerminatorKind::Drop { place: tcx.mk_place_deref(ptr), target: loop_block, - unwind: unwind.into_option(), + unwind: unwind.into_action(), }, ); @@ -946,7 +946,7 @@ where args, destination: unit_temp, target: Some(target), - cleanup: None, + unwind: UnwindAction::Continue, from_hir_call: false, fn_span: self.source_info.span, }; // FIXME(#43234) @@ -959,7 +959,7 @@ where fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock { let block = - TerminatorKind::Drop { place: self.place, target, unwind: unwind.into_option() }; + TerminatorKind::Drop { place: self.place, target, unwind: unwind.into_action() }; self.new_block(unwind, block) } diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index a40c38aa4c3..a078c6b550e 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -1,4 +1,4 @@ -use rustc_middle::mir::{self, BasicBlock, Location, SwitchTargets}; +use rustc_middle::mir::{self, BasicBlock, Location, SwitchTargets, UnwindAction}; use rustc_middle::ty::TyCtxt; use std::ops::RangeInclusive; @@ -478,10 +478,10 @@ impl Direction for Forward { Goto { target } => propagate(target, exit_state), - Assert { target, cleanup: unwind, expected: _, msg: _, cond: _ } + Assert { target, unwind, expected: _, msg: _, cond: _ } | Drop { target, unwind, place: _ } | FalseUnwind { real_target: target, unwind } => { - if let Some(unwind) = unwind { + if let UnwindAction::Cleanup(unwind) = unwind { propagate(unwind, exit_state); } @@ -503,7 +503,7 @@ impl Direction for Forward { } Call { - cleanup, + unwind, destination, target, func: _, @@ -511,7 +511,7 @@ impl Direction for Forward { from_hir_call: _, fn_span: _, } => { - if let Some(unwind) = cleanup { + if let UnwindAction::Cleanup(unwind) = unwind { propagate(unwind, exit_state); } @@ -533,9 +533,9 @@ impl Direction for Forward { options: _, line_spans: _, destination, - cleanup, + unwind, } => { - if let Some(unwind) = cleanup { + if let UnwindAction::Cleanup(unwind) = unwind { propagate(unwind, exit_state); } diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index 17102454a88..60679b17d6c 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -39,7 +39,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> { args: vec![], destination: dummy_place.clone(), target: Some(mir::START_BLOCK), - cleanup: None, + unwind: mir::UnwindAction::Continue, from_hir_call: false, fn_span: DUMMY_SP, }, @@ -53,7 +53,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> { args: vec![], destination: dummy_place.clone(), target: Some(mir::START_BLOCK), - cleanup: None, + unwind: mir::UnwindAction::Continue, from_hir_call: false, fn_span: DUMMY_SP, }, diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index d9ceac1154f..9f9a5c94b56 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -398,7 +398,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { ref args, destination, target, - cleanup: _, + unwind: _, from_hir_call: _, fn_span: _, } => { @@ -417,7 +417,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { options: _, line_spans: _, destination: _, - cleanup: _, + unwind: _, } => { for op in operands { match *op { diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs index 893018e0d8e..8fddbe4ad9f 100644 --- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs +++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs @@ -125,13 +125,13 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls { for bb in calls_to_terminate { let cleanup = body.basic_blocks_mut()[bb].terminator_mut().unwind_mut().unwrap(); - *cleanup = Some(abort_bb); + *cleanup = UnwindAction::Cleanup(abort_bb); } } for id in cleanups_to_remove { let cleanup = body.basic_blocks_mut()[id].terminator_mut().unwind_mut().unwrap(); - *cleanup = None; + *cleanup = UnwindAction::Continue; } // We may have invalidated some `cleanup` blocks so clean those up now. diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index 30966d22e2f..ea7ccb512e0 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -50,10 +50,10 @@ impl AddCallGuards { for block in body.basic_blocks_mut() { match block.terminator { Some(Terminator { - kind: TerminatorKind::Call { target: Some(ref mut destination), cleanup, .. }, + kind: TerminatorKind::Call { target: Some(ref mut destination), unwind, .. }, source_info, }) if pred_count[*destination] > 1 - && (cleanup.is_some() || self == &AllCallEdges) => + && (matches!(unwind, UnwindAction::Cleanup(_)) || self == &AllCallEdges) => { // It's a critical edge, break it let call_guard = BasicBlockData { diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index ac55948e61b..b9af74a2061 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -228,7 +228,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> fn assert_panic( _ecx: &mut InterpCx<'mir, 'tcx, Self>, _msg: &rustc_middle::mir::AssertMessage<'tcx>, - _unwind: Option<rustc_middle::mir::BasicBlock>, + _unwind: rustc_middle::mir::UnwindAction, ) -> InterpResult<'tcx> { bug!("panics terminators are not evaluated in ConstProp") } diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index 59b506e7345..0f6c06e370b 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -140,7 +140,7 @@ impl<'tcx> MockBlocks<'tcx> { args: vec![], destination: self.dummy_place.clone(), target: Some(TEMP_BLOCK), - cleanup: None, + unwind: UnwindAction::Continue, from_hir_call: false, fn_span: DUMMY_SP, }, diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index a028d6356d5..9217c2dc81c 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -120,7 +120,7 @@ fn remove_dead_unwinds<'tcx>( .into_results_cursor(body); for (bb, bb_data) in body.basic_blocks.iter_enumerated() { let place = match bb_data.terminator().kind { - TerminatorKind::Drop { ref place, unwind: Some(_), .. } => { + TerminatorKind::Drop { ref place, unwind: UnwindAction::Cleanup(_), .. } => { und.derefer(place.as_ref(), body).unwrap_or(*place) } _ => continue, @@ -417,7 +417,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { if data.is_cleanup { Unwind::InCleanup } else { - Unwind::To(Option::unwrap_or(unwind, resume_block)) + match unwind { + UnwindAction::Cleanup(cleanup) => Unwind::To(cleanup), + UnwindAction::Continue => Unwind::To(resume_block), + } }, bb, ), @@ -474,7 +477,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { continue; } if let TerminatorKind::Call { - destination, target: Some(tgt), cleanup: Some(_), .. + destination, + target: Some(tgt), + unwind: UnwindAction::Cleanup(_), + .. } = data.terminator().kind { assert!(!self.patch.is_patched(bb)); @@ -543,8 +549,12 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { // There may be a critical edge after this call, // so mark the return as initialized *before* the // call. - if let TerminatorKind::Call { destination, target: Some(_), cleanup: None, .. } = - data.terminator().kind + if let TerminatorKind::Call { + destination, + target: Some(_), + unwind: UnwindAction::Continue, + .. + } = data.terminator().kind { assert!(!self.patch.is_patched(bb)); diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 66d32b954e4..8601c1b2d71 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -34,7 +34,7 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> { args, destination: _, target: _, - cleanup: _, + unwind: _, from_hir_call: _, fn_span: _, } = &terminator.kind diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index af6422c7246..a83e6a5b680 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1060,7 +1060,10 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let unwind = if block_data.is_cleanup { Unwind::InCleanup } else { - Unwind::To(unwind.unwrap_or_else(|| elaborator.patch.resume_block())) + Unwind::To(match *unwind { + UnwindAction::Cleanup(tgt) => tgt, + UnwindAction::Continue => elaborator.patch.resume_block(), + }) }; elaborate_drop( &mut elaborator, @@ -1147,7 +1150,7 @@ fn insert_panic_block<'tcx>( expected: true, msg: message, target: assert_block, - cleanup: None, + unwind: UnwindAction::Continue, }; let source_info = SourceInfo::outermost(body.span); @@ -1248,8 +1251,8 @@ fn create_generator_resume_function<'tcx>( } else if !block.is_cleanup { // Any terminators that *can* unwind but don't have an unwind target set are also // pointed at our poisoning block (unless they're part of the cleanup path). - if let Some(unwind @ None) = block.terminator_mut().unwind_mut() { - *unwind = Some(poison_block); + if let Some(unwind @ UnwindAction::Continue) = block.terminator_mut().unwind_mut() { + *unwind = UnwindAction::Cleanup(poison_block); } } } @@ -1294,8 +1297,11 @@ fn create_generator_resume_function<'tcx>( fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock { let return_block = insert_term_block(body, TerminatorKind::Return); - let term = - TerminatorKind::Drop { place: Place::from(SELF_ARG), target: return_block, unwind: None }; + let term = TerminatorKind::Drop { + place: Place::from(SELF_ARG), + target: return_block, + unwind: UnwindAction::Continue, + }; let source_info = SourceInfo::outermost(body.span); // Create a block to destroy an unresumed generators. This can only destroy upvars. @@ -1670,7 +1676,7 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> { args, destination, target: Some(_), - cleanup: _, + unwind: _, from_hir_call: _, fn_span: _, } => { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 15b31d38394..c46cb5e98df 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -453,7 +453,7 @@ impl<'tcx> Inliner<'tcx> { // If the place doesn't actually need dropping, treat it like a regular goto. let ty = callsite.callee.subst_mir(self.tcx, &place.ty(callee_body, tcx).ty); - if ty.needs_drop(tcx, self.param_env) && let Some(unwind) = unwind { + if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind { work_list.push(unwind); } } else if callee_attrs.instruction_set != self.codegen_fn_attrs.instruction_set @@ -500,7 +500,7 @@ impl<'tcx> Inliner<'tcx> { ) { let terminator = caller_body[callsite.block].terminator.take().unwrap(); match terminator.kind { - TerminatorKind::Call { args, destination, cleanup, .. } => { + TerminatorKind::Call { args, destination, unwind, .. } => { // If the call is something like `a[*i] = f(i)`, where // `i : &mut usize`, then just duplicating the `a[*i]` // Place could result in two different locations if `f` @@ -571,7 +571,7 @@ impl<'tcx> Inliner<'tcx> { destination: destination_local, callsite_scope: caller_body.source_scopes[callsite.source_info.scope].clone(), callsite, - cleanup_block: cleanup, + cleanup_block: unwind, in_cleanup_block: false, tcx: self.tcx, expn_data, @@ -813,14 +813,14 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { let ty = self.instance.subst_mir(tcx, &place.ty(self.callee_body, tcx).ty); if ty.needs_drop(tcx, self.param_env) { self.cost += CALL_PENALTY; - if unwind.is_some() { + if let UnwindAction::Cleanup(_) = unwind { self.cost += LANDINGPAD_PENALTY; } } else { self.cost += INSTR_COST; } } - TerminatorKind::Call { func: Operand::Constant(ref f), cleanup, .. } => { + TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => { let fn_ty = self.instance.subst_mir(tcx, &f.literal.ty()); self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) { // Don't give intrinsics the extra penalty for calls @@ -828,20 +828,20 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { } else { CALL_PENALTY }; - if cleanup.is_some() { + if let UnwindAction::Cleanup(_) = unwind { self.cost += LANDINGPAD_PENALTY; } } - TerminatorKind::Assert { cleanup, .. } => { + TerminatorKind::Assert { unwind, .. } => { self.cost += CALL_PENALTY; - if cleanup.is_some() { + if let UnwindAction::Cleanup(_) = unwind { self.cost += LANDINGPAD_PENALTY; } } TerminatorKind::Resume => self.cost += RESUME_PENALTY, - TerminatorKind::InlineAsm { cleanup, .. } => { + TerminatorKind::InlineAsm { unwind, .. } => { self.cost += INSTR_COST; - if cleanup.is_some() { + if let UnwindAction::Cleanup(_) = unwind { self.cost += LANDINGPAD_PENALTY; } } @@ -979,7 +979,7 @@ struct Integrator<'a, 'tcx> { destination: Local, callsite_scope: SourceScopeData<'tcx>, callsite: &'a CallSite<'tcx>, - cleanup_block: Option<BasicBlock>, + cleanup_block: UnwindAction, in_cleanup_block: bool, tcx: TyCtxt<'tcx>, expn_data: LocalExpnId, @@ -1014,18 +1014,20 @@ impl Integrator<'_, '_> { new } - fn map_unwind(&self, unwind: Option<BasicBlock>) -> Option<BasicBlock> { + fn map_unwind(&self, unwind: UnwindAction) -> UnwindAction { if self.in_cleanup_block { - if unwind.is_some() { - bug!("cleanup on cleanup block"); + match unwind { + UnwindAction::Cleanup(_) => { + bug!("cleanup on cleanup block"); + } + UnwindAction::Continue => return unwind, } - return unwind; } match unwind { - Some(target) => Some(self.map_block(target)), + UnwindAction::Cleanup(target) => UnwindAction::Cleanup(self.map_block(target)), // Add an unwind edge to the original call's cleanup block - None => self.cleanup_block, + UnwindAction::Continue => self.cleanup_block, } } } @@ -1116,15 +1118,15 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> { *target = self.map_block(*target); *unwind = self.map_unwind(*unwind); } - TerminatorKind::Call { ref mut target, ref mut cleanup, .. } => { + TerminatorKind::Call { ref mut target, ref mut unwind, .. } => { if let Some(ref mut tgt) = *target { *tgt = self.map_block(*tgt); } - *cleanup = self.map_unwind(*cleanup); + *unwind = self.map_unwind(*unwind); } - TerminatorKind::Assert { ref mut target, ref mut cleanup, .. } => { + TerminatorKind::Assert { ref mut target, ref mut unwind, .. } => { *target = self.map_block(*target); - *cleanup = self.map_unwind(*cleanup); + *unwind = self.map_unwind(*unwind); } TerminatorKind::Return => { terminator.kind = if let Some(tgt) = self.callsite.target { @@ -1133,11 +1135,12 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> { TerminatorKind::Unreachable } } - TerminatorKind::Resume => { - if let Some(tgt) = self.cleanup_block { - terminator.kind = TerminatorKind::Goto { target: tgt } + TerminatorKind::Resume => match self.cleanup_block { + UnwindAction::Cleanup(tgt) => { + terminator.kind = TerminatorKind::Goto { target: tgt }; } - } + UnwindAction::Continue => (), + }, TerminatorKind::Abort => {} TerminatorKind::Unreachable => {} TerminatorKind::FalseEdge { ref mut real_target, ref mut imaginary_target } => { @@ -1149,11 +1152,11 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> { { bug!("False unwinds should have been removed before inlining") } - TerminatorKind::InlineAsm { ref mut destination, ref mut cleanup, .. } => { + TerminatorKind::InlineAsm { ref mut destination, ref mut unwind, .. } => { if let Some(ref mut tgt) = *destination { *tgt = self.map_block(*tgt); } - *cleanup = self.map_unwind(*cleanup); + *unwind = self.map_unwind(*unwind); } } } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index b52de4b72c9..2e418c1dafc 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -159,7 +159,7 @@ fn remap_mir_for_const_eval_select<'tcx>( ref mut args, destination, target, - cleanup, + unwind, fn_span, .. } if let ty::FnDef(def_id, _) = *literal.ty().kind() @@ -196,7 +196,7 @@ fn remap_mir_for_const_eval_select<'tcx>( }; method(place) }).collect(); - terminator.kind = TerminatorKind::Call { func, args: arguments, destination, target, cleanup, from_hir_call: false, fn_span }; + terminator.kind = TerminatorKind::Call { func, args: arguments, destination, target, unwind, from_hir_call: false, fn_span }; } _ => {} } diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs index 101fae2f08c..75a415d88ee 100644 --- a/compiler/rustc_mir_transform/src/lower_slice_len.rs +++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs @@ -54,7 +54,7 @@ fn lower_slice_len_call<'tcx>( args, destination, target: Some(bb), - cleanup: None, + unwind: UnwindAction::Continue, from_hir_call: true, .. } => { diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs index e962819b691..b4d68f4a322 100644 --- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs @@ -103,11 +103,11 @@ impl RemoveNoopLandingPads { for bb in postorder { debug!(" processing {:?}", bb); if let Some(unwind) = body[bb].terminator_mut().unwind_mut() { - if let Some(unwind_bb) = *unwind { + if let UnwindAction::Cleanup(unwind_bb) = *unwind { if nop_landing_pads.contains(unwind_bb) { debug!(" removing noop landing pad"); landing_pads_removed += 1; - *unwind = None; + *unwind = UnwindAction::Continue; } } } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 9e406eba0fc..f5a65e12705 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -499,7 +499,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { args: vec![Operand::Move(ref_loc)], destination: dest, target: Some(next), - cleanup: Some(cleanup), + unwind: UnwindAction::Cleanup(cleanup), from_hir_call: true, fn_span: self.span, }, @@ -540,7 +540,11 @@ impl<'tcx> CloneShimBuilder<'tcx> { self.make_clone_call(dest_field, src_field, ity, next_block, unwind); self.block( vec![], - TerminatorKind::Drop { place: dest_field, target: unwind, unwind: None }, + TerminatorKind::Drop { + place: dest_field, + target: unwind, + unwind: UnwindAction::Continue, + }, true, ); unwind = next_unwind; @@ -776,10 +780,10 @@ fn build_call_shim<'tcx>( args, destination: Place::return_place(), target: Some(BasicBlock::new(1)), - cleanup: if let Some(Adjustment::RefMut) = rcvr_adjustment { - Some(BasicBlock::new(3)) + unwind: if let Some(Adjustment::RefMut) = rcvr_adjustment { + UnwindAction::Cleanup(BasicBlock::new(3)) } else { - None + UnwindAction::Continue }, from_hir_call: true, fn_span: span, @@ -792,7 +796,11 @@ fn build_call_shim<'tcx>( block( &mut blocks, vec![], - TerminatorKind::Drop { place: rcvr_place(), target: BasicBlock::new(2), unwind: None }, + TerminatorKind::Drop { + place: rcvr_place(), + target: BasicBlock::new(2), + unwind: UnwindAction::Continue, + }, false, ); } @@ -803,7 +811,11 @@ fn build_call_shim<'tcx>( block( &mut blocks, vec![], - TerminatorKind::Drop { place: rcvr_place(), target: BasicBlock::new(4), unwind: None }, + TerminatorKind::Drop { + place: rcvr_place(), + target: BasicBlock::new(4), + unwind: UnwindAction::Continue, + }, true, ); diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index d66640ba0b7..ff195cd7288 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -318,7 +318,7 @@ fn check_terminator<'tcx>( from_hir_call: _, destination: _, target: _, - cleanup: _, + unwind: _, fn_span: _, } => { let fn_ty = func.ty(body, tcx); @@ -361,7 +361,7 @@ fn check_terminator<'tcx>( expected: _, msg: _, target: _, - cleanup: _, + unwind: _, } => check_operand(tcx, cond, span, body), TerminatorKind::InlineAsm { .. } => Err((span, "cannot use inline assembly in const fn".into())), diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index cc1964de332..621b90f0e57 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -868,7 +868,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { fn assert_panic( ecx: &mut MiriInterpCx<'mir, 'tcx>, msg: &mir::AssertMessage<'tcx>, - unwind: Option<mir::BasicBlock>, + unwind: mir::UnwindAction, ) -> InterpResult<'tcx> { ecx.assert_panic(msg, unwind) } diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs index acc97c4b8a0..c31194b4b93 100644 --- a/src/tools/miri/src/shims/panic.rs +++ b/src/tools/miri/src/shims/panic.rs @@ -189,7 +189,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn assert_panic( &mut self, msg: &mir::AssertMessage<'tcx>, - unwind: Option<mir::BasicBlock>, + unwind: mir::UnwindAction, ) -> InterpResult<'tcx> { use rustc_middle::mir::AssertKind::*; let this = self.eval_context_mut(); |
