diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index e759fd6618276..b913e5a7826e9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -4085,7 +4085,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diag<'_>) { let tcx = self.infcx.tcx; - if let Some(Terminator { kind: TerminatorKind::Call { call_source, fn_span, .. }, .. }) = + if let Terminator { kind: TerminatorKind::Call { call_source, fn_span, .. }, .. } = &self.body[loan.reserve_location.block].terminator && let Some((method_did, method_args)) = mir::find_self_call( tcx, diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs index ab4a710ba70e5..5ff2b5cfaa025 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs @@ -57,7 +57,7 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { if is_statement { visitor.visit_statement(&block_data.statements[p.statement_index], p); } else { - visitor.visit_terminator(block_data.terminator.as_ref().unwrap(), p); + visitor.visit_terminator(block_data.terminator(), p); } match visitor.def_use_result { diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 311f1f5b9162c..b6a612a2ea68c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -561,7 +561,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { ); if !is_terminator { continue; - } else if let Some(Terminator { + } else if let Terminator { kind: TerminatorKind::Call { func, @@ -569,7 +569,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { .. }, .. - }) = &bbd.terminator + } = &bbd.terminator { if let Some(source) = BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx) @@ -1082,9 +1082,8 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { debug!("move_spans: target_temp = {:?}", target_temp); - if let Some(Terminator { - kind: TerminatorKind::Call { fn_span, call_source, .. }, .. - }) = &self.body[location.block].terminator + if let Terminator { kind: TerminatorKind::Call { fn_span, call_source, .. }, .. } = + &self.body[location.block].terminator { let Some((method_did, method_args)) = find_self_call(self.infcx.tcx, self.body, target_temp, location.block) diff --git a/compiler/rustc_borrowck/src/region_infer/region_context.rs b/compiler/rustc_borrowck/src/region_infer/region_context.rs index 6f29c42eed249..f2e4f3c12c116 100644 --- a/compiler/rustc_borrowck/src/region_infer/region_context.rs +++ b/compiler/rustc_borrowck/src/region_infer/region_context.rs @@ -823,7 +823,7 @@ impl<'tcx> RegionInferenceContextInner<'tcx> { for location in locations { if from_location.is_predecessor_of(location, body) { let bb = &body[location.block]; - if let Some(terminator) = &bb.terminator + if let terminator = &bb.terminator // terminator of a loop should be TerminatorKind::FalseUnwind && let TerminatorKind::FalseUnwind { .. } = terminator.kind { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 52b584f12213a..b787e99f62eea 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1336,7 +1336,7 @@ pub struct BasicBlockData<'tcx> { /// exception is that certain passes, such as `simplify_cfg`, swap /// out the terminator temporarily with `None` while they continue /// to recurse over the set of basic blocks. - pub terminator: Option>, + pub terminator: Terminator<'tcx>, /// If true, this block lies on an unwind path. This is used /// during codegen where distinct kinds of basic blocks may be @@ -1346,13 +1346,13 @@ pub struct BasicBlockData<'tcx> { } impl<'tcx> BasicBlockData<'tcx> { - pub fn new(terminator: Option>, is_cleanup: bool) -> BasicBlockData<'tcx> { + pub fn new(terminator: Terminator<'tcx>, is_cleanup: bool) -> BasicBlockData<'tcx> { BasicBlockData::new_stmts(Vec::new(), terminator, is_cleanup) } pub fn new_stmts( statements: Vec>, - terminator: Option>, + terminator: Terminator<'tcx>, is_cleanup: bool, ) -> BasicBlockData<'tcx> { BasicBlockData { @@ -1369,12 +1369,12 @@ impl<'tcx> BasicBlockData<'tcx> { /// provides a convenient way to reach the terminator. #[inline] pub fn terminator(&self) -> &Terminator<'tcx> { - self.terminator.as_ref().expect("invalid terminator state") + &self.terminator } #[inline] pub fn terminator_mut(&mut self) -> &mut Terminator<'tcx> { - self.terminator.as_mut().expect("invalid terminator state") + &mut self.terminator } /// Does the block have no statements and an unreachable terminator? @@ -1696,7 +1696,7 @@ pub fn find_self_call<'tcx>( block: BasicBlock, ) -> Option<(DefId, GenericArgs<'tcx>)> { debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator); - if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) = + if let Terminator { kind: TerminatorKind::Call { func, args, .. }, .. } = &body[block].terminator && let Operand::Constant(ConstOperand { const_, .. }) = func && let ty::FnDef(def_id, fn_args) = *const_.ty().kind() diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index c93fb42bfe7eb..aca148ef4fb0c 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -836,7 +836,7 @@ impl<'a, 'tcx> MirWriter<'a, 'tcx> { // Terminator at the bottom. (self.extra_data)(PassWhere::BeforeLocation(current_location), w)?; - if data.terminator.is_some() { + if true { let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind); if self.options.include_extra_comments { writeln!( diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 0151a8272811d..0affc826b7086 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -426,6 +426,27 @@ pub struct Terminator<'tcx> { pub kind: TerminatorKind<'tcx>, } +impl<'tcx> Terminator<'tcx> { + #[inline] + pub fn none() -> Terminator<'tcx> { + Terminator { + source_info: SourceInfo::outermost(DUMMY_SP), + kind: TerminatorKind::Goto { target: BasicBlock::MAX, loop_hint_attrs: ThinVec::new() }, + } + } + + pub fn take(&mut self) -> Option> { + if self.is_none() { None } else { Some(std::mem::replace(self, Self::none())) } + } + + pub fn is_none(&self) -> bool { + matches!(self.kind, TerminatorKind::Goto { target: BasicBlock::MAX, .. }) + } + pub fn is_some(&self) -> bool { + !self.is_none() + } +} + impl<'tcx> Terminator<'tcx> { #[inline] pub fn successors(&self) -> Successors<'_> { diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index a3c0a5b83ffad..ff8a8b6adcc3a 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -54,9 +54,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { let data = &self.body[idx]; - if let Some(ref term) = data.terminator { - self.worklist.extend(term.successors()); - } + self.worklist.extend(data.terminator.successors()); return Some((idx, data)); } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 2fc07d1c43cd3..3e03f8b0a7dbd 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -316,9 +316,7 @@ macro_rules! make_mir_visitor { for debuginfo in after_last_stmt_debuginfos as & $($mutability)? [_] { self.visit_statement_debuginfo(debuginfo, location); } - if let Some(terminator) = terminator { - self.visit_terminator(terminator, location); - } + self.visit_terminator(terminator, location); } fn super_source_scope_data( @@ -998,9 +996,7 @@ macro_rules! make_mir_visitor { let basic_block = & $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block]; if basic_block.statements.len() == location.statement_index { - if let Some(ref $($mutability)? terminator) = basic_block.terminator { - self.visit_terminator(terminator, location) - } + self.visit_terminator( & $($mutability)? basic_block.terminator, location) } else { let statement = & $($mutability)? basic_block.statements[location.statement_index]; diff --git a/compiler/rustc_mir_build/src/builder/cfg.rs b/compiler/rustc_mir_build/src/builder/cfg.rs index 75377f761f401..0d7b712138079 100644 --- a/compiler/rustc_mir_build/src/builder/cfg.rs +++ b/compiler/rustc_mir_build/src/builder/cfg.rs @@ -21,7 +21,7 @@ impl<'tcx> CFG<'tcx> { // it as #[inline(never)] to keep rustc's stack use in check. #[inline(never)] pub(crate) fn start_new_block(&mut self) -> BasicBlock { - self.basic_blocks.push(BasicBlockData::new(None, false)) + self.basic_blocks.push(BasicBlockData::new(Terminator::none(), false)) } pub(crate) fn start_new_cleanup_block(&mut self) -> BasicBlock { @@ -117,8 +117,8 @@ impl<'tcx> CFG<'tcx> { block, self.block_data(block) ); - self.block_data_mut(block).terminator = Some(Terminator { source_info, kind }); - self.block_data_mut(block).terminator.as_mut().unwrap() + self.block_data_mut(block).terminator = Terminator { source_info, kind }; + self.block_data_mut(block).terminator_mut() } /// In the `origin` block, push a `goto -> target` terminator. diff --git a/compiler/rustc_mir_build/src/builder/custom/mod.rs b/compiler/rustc_mir_build/src/builder/custom/mod.rs index f6c8658544b43..7d3a46bab91c9 100644 --- a/compiler/rustc_mir_build/src/builder/custom/mod.rs +++ b/compiler/rustc_mir_build/src/builder/custom/mod.rs @@ -64,7 +64,7 @@ pub(super) fn build_custom_mir<'tcx>( }; body.local_decls.push(LocalDecl::new(return_ty, return_ty_span)); - body.basic_blocks_mut().push(BasicBlockData::new(None, false)); + body.basic_blocks_mut().push(BasicBlockData::new(Terminator::none(), false)); body.source_scopes.push(SourceScopeData { span, parent_scope: None, diff --git a/compiler/rustc_mir_build/src/builder/custom/parse.rs b/compiler/rustc_mir_build/src/builder/custom/parse.rs index b227923292779..18031611f75e1 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse.rs @@ -200,7 +200,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { StmtKind::Let { pattern, initializer: Some(initializer), .. } => { let (var, ..) = self.parse_var(pattern)?; let data = BasicBlockData::new( - None, + Terminator::none(), parse_by_kind!(self, *initializer, _, "basic block declaration", @variant(mir_basic_block, Normal) => false, @variant(mir_basic_block, Cleanup) => true, @@ -303,7 +303,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { ExprKind::Block { block } => &self.thir[*block], ); - let mut data = BasicBlockData::new(None, is_cleanup); + let mut data = BasicBlockData::new(Terminator::none(), is_cleanup); for stmt_id in &*block.stmts { let stmt = self.statement_as_expr(*stmt_id)?; let span = self.thir[stmt].span; @@ -315,10 +315,10 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { let Some(trailing) = block.expr else { return Err(self.expr_error(expr_id, "terminator")) }; let span = self.thir[trailing].span; let terminator = self.parse_terminator(trailing)?; - data.terminator = Some(Terminator { + data.terminator = Terminator { source_info: SourceInfo { span, scope: self.source_scope }, kind: terminator, - }); + }; Ok(data) } diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs index 39bcee22f7bd0..27f24ed19237d 100644 --- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs +++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs @@ -66,7 +66,7 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls { // This will filter to functions with `extern "C-unwind"` ABIs, for // example. for block in body.basic_blocks.as_mut() { - let Some(terminator) = &mut block.terminator else { continue }; + let terminator = &mut block.terminator; //else { continue }; let span = terminator.source_info.span; // If we see an `UnwindResume` terminator inside a function then: diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index 17e99f506e0f2..5bf932a42e43a 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -88,7 +88,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards { let cur_len = body.basic_blocks.len(); let mut new_block = |source_info: SourceInfo, is_cleanup: bool, target: BasicBlock| { let block = BasicBlockData::new( - Some(Terminator { source_info, kind: TerminatorKind::goto(target) }), + Terminator { source_info, kind: TerminatorKind::goto(target) }, is_cleanup, ); let idx = cur_len + new_blocks.len(); diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs index 41c63d4857df8..1be185bd5b6bd 100644 --- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs +++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs @@ -94,7 +94,7 @@ fn add_move_for_packed_drop<'tcx>( let storage_dead_block = patch.new_block(BasicBlockData::new_stmts( vec![Statement::new(source_info, StatementKind::StorageDead(temp))], - Some(Terminator { source_info, kind: TerminatorKind::goto(target) }), + Terminator { source_info, kind: TerminatorKind::goto(target) }, is_cleanup, )); diff --git a/compiler/rustc_mir_transform/src/check_enums.rs b/compiler/rustc_mir_transform/src/check_enums.rs index 260028c570461..08373b03f710a 100644 --- a/compiler/rustc_mir_transform/src/check_enums.rs +++ b/compiler/rustc_mir_transform/src/check_enums.rs @@ -60,10 +60,8 @@ impl<'tcx> crate::MirPass<'tcx> for CheckEnums { source_info.span, "cannot build enum discriminant from zero-sized type", ); - basic_blocks[block].terminator = Some(Terminator { - source_info, - kind: TerminatorKind::goto(new_block), - }); + basic_blocks[block].terminator = + Terminator { source_info, kind: TerminatorKind::goto(new_block) }; } EnumCheckType::Direct { source_op, discr, op_size, valid_discrs } => { insert_direct_enum_check( @@ -246,7 +244,7 @@ fn split_block( // Drain every statement after this one and move the current terminator to a new basic block. let new_block = BasicBlockData::new_stmts( block_data.statements.split_off(location.statement_index), - block_data.terminator.take(), + block_data.terminator.take().unwrap(), block_data.is_cleanup, ); @@ -348,7 +346,7 @@ fn insert_direct_enum_check<'tcx>( new_block: BasicBlock, ) { // Insert a new target block that is branched to in case of an invalid discriminant. - let invalid_discr_block_data = BasicBlockData::new(None, false); + let invalid_discr_block_data = BasicBlockData::new(Terminator::none(), false); let invalid_discr_block = basic_blocks.push(invalid_discr_block_data); let block_data = &mut basic_blocks[current_block]; let discr_place = insert_discr_cast_to_u128( @@ -382,7 +380,7 @@ fn insert_direct_enum_check<'tcx>( .push(Statement::new(source_info, StatementKind::Assign(Box::new((discr_masked, rvalue))))); // Branch based on the discriminant value. - block_data.terminator = Some(Terminator { + block_data.terminator = Terminator { source_info, kind: TerminatorKind::SwitchInt { discr: Operand::Copy(discr_masked), @@ -393,10 +391,10 @@ fn insert_direct_enum_check<'tcx>( invalid_discr_block, ), }, - }); + }; // Abort in case of an invalid enum discriminant. - basic_blocks[invalid_discr_block].terminator = Some(Terminator { + basic_blocks[invalid_discr_block].terminator = Terminator { source_info, kind: TerminatorKind::Assert { cond: Operand::Constant(Box::new(ConstOperand { @@ -412,7 +410,7 @@ fn insert_direct_enum_check<'tcx>( // make a failing UB check turn into much worse UB when we start unwinding. unwind: UnwindAction::Unreachable, }, - }); + }; } fn insert_uninhabited_enum_check<'tcx>( @@ -439,7 +437,7 @@ fn insert_uninhabited_enum_check<'tcx>( ))), )); - block_data.terminator = Some(Terminator { + block_data.terminator = Terminator { source_info, kind: TerminatorKind::Assert { cond: Operand::Copy(is_ok), @@ -457,7 +455,7 @@ fn insert_uninhabited_enum_check<'tcx>( // make a failing UB check turn into much worse UB when we start unwinding. unwind: UnwindAction::Unreachable, }, - }); + }; } fn insert_niche_check<'tcx>( @@ -522,7 +520,7 @@ fn insert_niche_check<'tcx>( ))), )); - block_data.terminator = Some(Terminator { + block_data.terminator = Terminator { source_info, kind: TerminatorKind::Assert { cond: Operand::Copy(is_ok), @@ -534,5 +532,5 @@ fn insert_niche_check<'tcx>( // make a failing UB check turn into much worse UB when we start unwinding. unwind: UnwindAction::Unreachable, }, - }); + }; } diff --git a/compiler/rustc_mir_transform/src/check_pointers.rs b/compiler/rustc_mir_transform/src/check_pointers.rs index 25336280926fe..5a67e841a240a 100644 --- a/compiler/rustc_mir_transform/src/check_pointers.rs +++ b/compiler/rustc_mir_transform/src/check_pointers.rs @@ -103,7 +103,7 @@ pub(crate) fn check_pointers<'tcx, F>( &mut block_data.statements, source_info, ); - block_data.terminator = Some(Terminator { + block_data.terminator = Terminator { source_info, kind: TerminatorKind::Assert { cond: pointer_check.cond, @@ -116,7 +116,7 @@ pub(crate) fn check_pointers<'tcx, F>( // worse UB when we start unwinding. unwind: UnwindAction::Unreachable, }, - }); + }; } } } @@ -237,7 +237,7 @@ fn split_block( // Drain every statement after this one and move the current terminator to a new basic block. let new_block = BasicBlockData::new_stmts( block_data.statements.split_off(location.statement_index), - block_data.terminator.take(), + block_data.terminator.take().unwrap(), // fixme I don't know whether this unwrap is correct block_data.is_cleanup, ); diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index c6bd539eb6eee..35dc4fc5a42a1 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -377,7 +377,7 @@ pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>( body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info); // call coroutine_drop() - let call_bb = body.basic_blocks_mut().push(BasicBlockData::new(None, false)); + let call_bb = body.basic_blocks_mut().push(BasicBlockData::new(Terminator::none(), false)); // return Poll::Ready() let ret_bb = insert_poll_ready_block(tcx, &mut body); @@ -389,7 +389,7 @@ pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>( replace: false, drop: None, }; - body.basic_blocks_mut()[call_bb].terminator = Some(Terminator { source_info, kind }); + body.basic_blocks_mut()[call_bb].terminator = Terminator { source_info, kind }; make_coroutine_state_argument_pinned(tcx, &mut body); diff --git a/compiler/rustc_mir_transform/src/coroutine/mod.rs b/compiler/rustc_mir_transform/src/coroutine/mod.rs index 9bf85b56a4c66..b8ea00de28bc1 100644 --- a/compiler/rustc_mir_transform/src/coroutine/mod.rs +++ b/compiler/rustc_mir_transform/src/coroutine/mod.rs @@ -252,7 +252,7 @@ impl<'tcx> TransformVisitor<'tcx> { body.basic_blocks_mut().push(BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind: TerminatorKind::Return }), + Terminator { source_info, kind: TerminatorKind::Return }, false, )); @@ -722,7 +722,7 @@ fn insert_switch<'tcx>( // Add the switch as entry block, and put the former entry block at the end. let former_entry = std::mem::replace( &mut body.basic_blocks_mut()[START_BLOCK], - BasicBlockData::new_stmts(vec![assign], None, false), + BasicBlockData::new_stmts(vec![assign], Terminator::none(), false), ); let former_entry = body.basic_blocks_mut().push(former_entry); @@ -737,12 +737,12 @@ fn insert_switch<'tcx>( let switch = TerminatorKind::SwitchInt { discr: Operand::Move(discr), targets: switch_targets }; body.basic_blocks_mut()[START_BLOCK].terminator = - Some(Terminator { source_info: SourceInfo::outermost(body.span), kind: switch }); + Terminator { source_info: SourceInfo::outermost(body.span), kind: switch }; } fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock { let source_info = SourceInfo::outermost(body.span); - body.basic_blocks_mut().push(BasicBlockData::new(Some(Terminator { source_info, kind }), false)) + body.basic_blocks_mut().push(BasicBlockData::new(Terminator { source_info, kind }, false)) } fn return_poll_ready_assign<'tcx>(tcx: TyCtxt<'tcx>, source_info: SourceInfo) -> Statement<'tcx> { @@ -761,7 +761,7 @@ fn insert_poll_ready_block<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> Ba let source_info = SourceInfo::outermost(body.span); body.basic_blocks_mut().push(BasicBlockData::new_stmts( [return_poll_ready_assign(tcx, source_info)].to_vec(), - Some(Terminator { source_info, kind: TerminatorKind::Return }), + Terminator { source_info, kind: TerminatorKind::Return }, false, )) } @@ -813,7 +813,7 @@ fn insert_poll_pending_block<'tcx>( let source_info = SourceInfo::outermost(body.span); body.basic_blocks_mut().push(BasicBlockData::new_stmts( [return_poll_pending(tcx, source_info, return_type)].to_vec(), - Some(Terminator { source_info, kind: TerminatorKind::Return }), + Terminator { source_info, kind: TerminatorKind::Return }, false, )) } @@ -847,7 +847,7 @@ fn generate_poison_block_and_redirect_unwinds_there<'tcx>( let source_info = SourceInfo::outermost(body.span); let poison_block = body.basic_blocks_mut().push(BasicBlockData::new_stmts( vec![transform.set_discr(VariantIdx::new(CoroutineArgs::POISONED), source_info)], - Some(Terminator { source_info, kind: TerminatorKind::UnwindResume }), + Terminator { source_info, kind: TerminatorKind::UnwindResume }, true, )); @@ -1049,7 +1049,7 @@ fn create_cases<'tcx>( // Then jump to the real target let block = body.basic_blocks_mut().push(BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind: TerminatorKind::goto(target) }), + Terminator { source_info, kind: TerminatorKind::goto(target) }, false, )); diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index 9fcd2a3028f84..f223972304ea6 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -69,7 +69,7 @@ impl<'tcx> MockBlocks<'tcx> { }; let next_hi = next_lo + BytePos(1); self.blocks.push(BasicBlockData::new( - Some(Terminator { + (Terminator { source_info: SourceInfo::outermost(Span::with_root_ctxt(next_lo, next_hi)), kind, }), diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index 6a34f0167354b..cc4f3e2b3911b 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -167,14 +167,14 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch { // Create `bbEq` in example above let eq_switch = BasicBlockData::new( - Some(Terminator { + Terminator { source_info: bbs[parent].terminator().source_info, kind: TerminatorKind::SwitchInt { // switch on the first discriminant, so we can mark the second one as dead discr: parent_op, targets: eq_targets, }, - }), + }, bbs[parent].is_cleanup, ); diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 7d05589b6169a..ce5da4fa6084a 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -1619,7 +1619,7 @@ where #[instrument(level = "trace", skip(self), ret)] fn new_block(&mut self, unwind: Unwind, k: TerminatorKind<'tcx>) -> BasicBlock { self.elaborator.patch().new_block(BasicBlockData::new( - Some(Terminator { source_info: self.source_info, kind: k }), + Terminator { source_info: self.source_info, kind: k }, unwind.is_cleanup(), )) } @@ -1633,7 +1633,7 @@ where ) -> BasicBlock { self.elaborator.patch().new_block(BasicBlockData::new_stmts( statements, - Some(Terminator { source_info: self.source_info, kind: k }), + Terminator { source_info: self.source_info, kind: k }, unwind.is_cleanup(), )) } diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index c6530ec375f9b..1fc0aa5ddbada 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -46,7 +46,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { if block.is_cleanup { continue; } - let Some(terminator) = &block.terminator else { continue }; + let terminator = &block.terminator; // else { continue }; if let TerminatorKind::InlineAsm { options, .. } = &terminator.kind { if options.contains(InlineAsmOptions::MAY_UNWIND) { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 501d2c38df170..a180d7bea2afe 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -610,7 +610,7 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( check_inline::is_inline_valid_on_fn(tcx, callsite.callee.def_id())?; check_codegen_attributes(inliner, callsite, callee_attrs)?; - let terminator = caller_body[callsite.block].terminator.as_ref().unwrap(); + let terminator = caller_body[callsite.block].terminator(); let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() }; let destination_ty = destination.ty(&caller_body.local_decls, tcx).ty; for arg in args { @@ -868,10 +868,7 @@ fn inline_call<'tcx, I: Inliner<'tcx>>( // Prepare a new block for code that should execute when call returns. We don't use // target block directly since it might have other predecessors. let data = BasicBlockData::new( - Some(Terminator { - source_info: terminator.source_info, - kind: TerminatorKind::goto(block), - }), + Terminator { source_info: terminator.source_info, kind: TerminatorKind::goto(block) }, caller_body[block].is_cleanup, ); Some(caller_body.basic_blocks_mut().push(data)) @@ -995,10 +992,10 @@ fn inline_call<'tcx, I: Inliner<'tcx>>( } caller_body.basic_blocks_mut().append(callee_body.basic_blocks_mut()); - caller_body[callsite.block].terminator = Some(Terminator { + caller_body[callsite.block].terminator = Terminator { source_info: callsite.source_info, kind: TerminatorKind::goto(integrator.map_block(START_BLOCK)), - }); + }; // Copy required constants from the callee_body into the caller_body. Although we are only // pushing constants that still need evaluation to `required_consts`, here they may have been evaluated diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 11ce25f2f5d7d..af451715cc156 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -54,7 +54,7 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify { ctx.simplify_repeat_once(rvalue); } - let terminator = block.terminator.as_mut().unwrap(); + let terminator = &mut block.terminator; ctx.simplify_primitive_clone(terminator, &mut block.statements); ctx.simplify_size_or_align_of_val(terminator, &mut block.statements); ctx.simplify_raw_eq(terminator, &mut block.statements); diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index d73d9a82f1a22..48b7d8f7016e7 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -247,7 +247,7 @@ fn remap_mir_for_const_eval_select<'tcx>( context: hir::Constness, ) -> Body<'tcx> { for bb in body.basic_blocks.as_mut().iter_mut() { - let terminator = bb.terminator.as_mut().expect("invalid terminator"); + let terminator = &mut bb.terminator; //.as_mut().expect("invalid terminator"); match terminator.kind { TerminatorKind::Call { func: Operand::Constant(ConstOperand { ref const_, .. }), diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 7e91890a08cc2..a23aea5a4e015 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -61,7 +61,7 @@ impl<'a, 'mir, 'tcx> DropsReachable<'a, 'mir, 'tcx> { let make_new_path_set = || Rc::new(RefCell::new(MixedBitSet::new_empty(move_set_size))); let data = &self.body.basic_blocks[block]; - let Some(terminator) = &data.terminator else { return }; + let terminator = &data.terminator; // Given that we observe these dropped locals here at `block` so far, we will try to update // the successor blocks. An occupied entry at `block` in `self.visited` signals that we // have visited `block` before. @@ -129,7 +129,7 @@ impl<'a, 'mir, 'tcx> DropsReachable<'a, 'mir, 'tcx> { vacant_entry.insert(Rc::new(RefCell::new(dropped_local_here.borrow().clone()))), ), }; - if let Some(terminator) = &target.terminator + if let terminator = &target.terminator && let TerminatorKind::Drop { place: dropped_place, target: _, diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 369ef0a6849bc..af1c807ea2d86 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -12,7 +12,7 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let local_decls = &body.local_decls; for block in body.basic_blocks.as_mut() { - let terminator = block.terminator.as_mut().unwrap(); + let terminator = &mut block.terminator; //.as_mut().unwrap(); if let TerminatorKind::Call { func, args, destination, target, .. } = &mut terminator.kind && let ty::FnDef(def_id, generic_args) = *func.ty(local_decls, tcx).kind() diff --git a/compiler/rustc_mir_transform/src/move_elimination.rs b/compiler/rustc_mir_transform/src/move_elimination.rs index 95a7f8cf237b5..3717dcc864c5b 100644 --- a/compiler/rustc_mir_transform/src/move_elimination.rs +++ b/compiler/rustc_mir_transform/src/move_elimination.rs @@ -742,7 +742,7 @@ fn get_or_split_edge<'tcx>( } let source_info = body.basic_blocks[pred].terminator().source_info; let split_bb = patcher.new_block(BasicBlockData::new( - Some(Terminator { source_info, kind: TerminatorKind::goto(succ) }), + Terminator { source_info, kind: TerminatorKind::goto(succ) }, body.basic_blocks[succ].is_cleanup, )); patcher.mutate_terminator(body, pred, |kind| { diff --git a/compiler/rustc_mir_transform/src/patch.rs b/compiler/rustc_mir_transform/src/patch.rs index 739fa5e37ab13..f1476108557a8 100644 --- a/compiler/rustc_mir_transform/src/patch.rs +++ b/compiler/rustc_mir_transform/src/patch.rs @@ -89,10 +89,10 @@ impl<'tcx> MirPatch<'tcx> { } let bb = self.new_block(BasicBlockData::new( - Some(Terminator { + Terminator { source_info: SourceInfo::outermost(self.body_span), kind: TerminatorKind::UnwindResume, - }), + }, true, )); self.resume_block = Some(bb); @@ -105,10 +105,10 @@ impl<'tcx> MirPatch<'tcx> { } let bb = self.new_block(BasicBlockData::new( - Some(Terminator { + Terminator { source_info: SourceInfo::outermost(self.body_span), kind: TerminatorKind::Unreachable, - }), + }, true, )); self.unreachable_cleanup_block = Some(bb); @@ -121,10 +121,10 @@ impl<'tcx> MirPatch<'tcx> { } let bb = self.new_block(BasicBlockData::new( - Some(Terminator { + Terminator { source_info: SourceInfo::outermost(self.body_span), kind: TerminatorKind::Unreachable, - }), + }, false, )); self.unreachable_no_cleanup_block = Some(bb); @@ -139,10 +139,10 @@ impl<'tcx> MirPatch<'tcx> { } let bb = self.new_block(BasicBlockData::new( - Some(Terminator { + Terminator { source_info: SourceInfo::outermost(self.body_span), kind: TerminatorKind::UnwindTerminate(reason), - }), + }, true, )); self.terminate_block = Some((bb, reason)); diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 7ad164956cbfd..5be8a1b8523c8 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -752,10 +752,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { fn new_block(&mut self) -> BasicBlock { let span = self.promoted.span; self.promoted.basic_blocks_mut().push(BasicBlockData::new( - Some(Terminator { - source_info: SourceInfo::outermost(span), - kind: TerminatorKind::Return, - }), + Terminator { source_info: SourceInfo::outermost(span), kind: TerminatorKind::Return }, false, )) } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 170a13ac173ea..cbe795097b1f4 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -279,7 +279,7 @@ pub fn build_drop_shim<'tcx>( let return_block = BasicBlock::new(1); let mut blocks = IndexVec::with_capacity(2); let block = |blocks: &mut IndexVec<_, _>, kind| -> BasicBlock { - blocks.push(BasicBlockData::new(Some(Terminator { source_info, kind }), false)) + blocks.push(BasicBlockData::new(Terminator { source_info, kind }, false)) }; if ty.is_some() { block(&mut blocks, TerminatorKind::goto(return_block)); @@ -325,7 +325,7 @@ pub fn build_drop_shim<'tcx>( ), ))), )); - start.terminator = Some(Terminator { + start.terminator = Terminator { source_info, kind: TerminatorKind::Call { func: Operand::function_handle( @@ -341,7 +341,7 @@ pub fn build_drop_shim<'tcx>( call_source: CallSource::Misc, fn_span: span, }, - }); + }; } else { let patch = { let mut elaborator = DropShimElaborator { @@ -493,7 +493,7 @@ fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Rvalue::ThreadLocalRef(def_id), ))), )], - Some(Terminator { source_info, kind: TerminatorKind::Return }), + Terminator { source_info, kind: TerminatorKind::Return }, false, )]); @@ -579,7 +579,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { let source_info = self.source_info(); self.blocks.push(BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind }), + Terminator { source_info, kind }, is_cleanup, )) } @@ -761,14 +761,13 @@ impl<'tcx> CloneShimBuilder<'tcx> { let rvalue = Rvalue::Discriminant(src); let statement = self.make_statement(StatementKind::Assign(Box::new((temp, rvalue)))); match &mut self.blocks[switch] { - BasicBlockData { statements, terminator: Some(Terminator { kind, .. }), .. } => { + BasicBlockData { statements, terminator: Terminator { kind, .. }, .. } => { statements.push(statement); *kind = TerminatorKind::SwitchInt { discr: Operand::Move(temp), targets: SwitchTargets::new(cases.into_iter(), unreachable), }; - } - BasicBlockData { terminator: None, .. } => unreachable!(), + } // BasicBlockData { terminator: None, .. } => unreachable!(), } } } @@ -933,7 +932,7 @@ fn build_call_shim<'tcx>( let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| { blocks.push(BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind }), + Terminator { source_info, kind }, is_cleanup, )) }; @@ -1060,7 +1059,7 @@ pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { let start_block = BasicBlockData::new_stmts( vec![statement], - Some(Terminator { source_info, kind: TerminatorKind::Return }), + Terminator { source_info, kind: TerminatorKind::Return }, false, ); @@ -1143,7 +1142,7 @@ fn build_fn_ptr_as_ptr_shim<'tcx>( let start_block = BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind: TerminatorKind::Return }), + Terminator { source_info, kind: TerminatorKind::Return }, false, ); let source = MirSource::from_shim(ty::ShimKind::FnPtrAsPtr(def_id, self_ty)); @@ -1178,7 +1177,7 @@ fn build_fn_ptr_from_ptr_shim<'tcx>( let start_block = BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind: TerminatorKind::Return }), + Terminator { source_info, kind: TerminatorKind::Return }, false, ); let source = MirSource::from_shim(ty::ShimKind::FnPtrFromPtr(def_id, self_ty)); @@ -1276,7 +1275,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>( let statements = vec![stmt]; let start_block = BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind: TerminatorKind::Return }), + Terminator { source_info, kind: TerminatorKind::Return }, false, ); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index 510da5cbce89b..70de1cc6a2d63 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -85,7 +85,7 @@ pub(super) fn build_async_drop_shim<'tcx>( let return_block = BasicBlock::new(1); let mut blocks = IndexVec::with_capacity(2); let block = |blocks: &mut IndexVec<_, _>, kind| -> BasicBlock { - blocks.push(BasicBlockData::new(Some(Terminator { source_info, kind }), false)) + blocks.push(BasicBlockData::new(Terminator { source_info, kind }, false)) }; block( &mut blocks, @@ -386,7 +386,7 @@ fn build_adrop_for_adrop_shim<'tcx>( // call Pin::new_unchecked(&mut impl_cor) blocks.push(BasicBlockData::new_stmts( statements, - Some(Terminator { + Terminator { source_info, kind: TerminatorKind::Call { func: Operand::function_handle(tcx, pin_fn, &[cor_ref.into()], span), @@ -397,7 +397,7 @@ fn build_adrop_for_adrop_shim<'tcx>( call_source: CallSource::Misc, fn_span: span, }, - }), + }, false, )); // When dropping async drop coroutine, we continue its execution: @@ -405,7 +405,7 @@ fn build_adrop_for_adrop_shim<'tcx>( let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, span); let resume_ctx = Place::from(Local::new(2)); blocks.push(BasicBlockData::new( - Some(Terminator { + Terminator { source_info, kind: TerminatorKind::Call { func: Operand::function_handle(tcx, poll_fn, &[impl_ty.into()], span), @@ -420,13 +420,11 @@ fn build_adrop_for_adrop_shim<'tcx>( call_source: CallSource::Misc, fn_span: span, }, - }), - false, - )); - blocks.push(BasicBlockData::new( - Some(Terminator { source_info, kind: TerminatorKind::Return }), + }, false, )); + blocks + .push(BasicBlockData::new(Terminator { source_info, kind: TerminatorKind::Return }, false)); let source = MirSource::from_shim(shim); let mut body = new_body(source, blocks, locals, sig.inputs().len(), span); diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index c0281871f2a73..6c679e7ec40a5 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -120,10 +120,8 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { pred_count[START_BLOCK] = 1; for (_, data) in traversal::preorder(body) { - if let Some(ref term) = data.terminator { - for tgt in term.successors() { - pred_count[tgt] += 1; - } + for tgt in data.terminator.successors() { + pred_count[tgt] += 1; } } @@ -194,7 +192,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { self.basic_blocks[bb].after_last_stmt_debuginfos = parent_bb_last_debuginfos; } - self.basic_blocks[bb].terminator = Some(terminator); + self.basic_blocks[bb].terminator = terminator; } if !changed { @@ -216,7 +214,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { BasicBlockData { ref statements, terminator: - ref mut terminator @ Some(Terminator { kind: TerminatorKind::Goto { .. }, .. }), + ref mut terminator @ Terminator { kind: TerminatorKind::Goto { .. }, .. }, .. } if statements.is_empty() => terminator.take(), // if `terminator` is None, this means we are in a loop. In that @@ -273,7 +271,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { self.pred_count[*target] += 1; self.pred_count[current] -= 1; } - self.basic_blocks[current].terminator = Some(terminator); + self.basic_blocks[current].terminator = terminator; } } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index eb5befb52c3e4..b394239cc0697 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -634,7 +634,7 @@ pub fn is_default_equivalent_call( { return true; } else if block_data.statements.is_empty() - && let Some(term) = &block_data.terminator + && let term = &block_data.terminator { match &term.kind { TerminatorKind::Call { diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs index 2ea5e368fcfa9..7559ef06d467c 100644 --- a/src/tools/clippy/clippy_utils/src/mir/mod.rs +++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs @@ -300,7 +300,7 @@ fn is_local_assignment(mir: &Body<'_>, local: Local, location: Location) -> bool /// Returns the basic block that is terminated with this function call. pub fn function_call_basic_block(body: &Body<'_>, fun: &Expr<'_>) -> Option { body.basic_blocks.iter_enumerated().find_map(|(block, data)| { - if let Some(terminator) = data.terminator.as_ref() + if let terminator = &data.terminator && let TerminatorKind::Call { fn_span, .. } = terminator.kind && fn_span.lo() == fun.span.lo() { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 5e097c56ec6ef..098d02fd2bc76 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -1510,7 +1510,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { } fn set_terminator(&mut self, source: BasicBlockId, terminator: TerminatorKind, span: MirSpan) { - self.result.basic_blocks[source].terminator = Some(Terminator { span, kind: terminator }); + self.result.basic_blocks[source].terminator = (Terminator{ span, kind: terminator }); } fn set_goto(&mut self, source: BasicBlockId, target: BasicBlockId, span: MirSpan) {