Code change:
pub type SuccessorsMut<'a> = iter::Chain<option::IntoIter<&'a mut BasicBlock>, slice::IterMut<'a, BasicBlock>>; <del> impl<'tcx> Terminator<'tcx> { pub fn successors(&self) -> Successors<'_> { self.kind.successors() } pub fn successors_mut(&mut self) -> SuccessorsMut<'_> { self.kind.successors_mut() } pub fn unwind(&self) -> Option<&Option<BasicBlock>> { self.kind.unwind() } pub fn unwind_mut(&mut self) -> Option<&mut Option<BasicBlock>> { self.kind.unwind_mut() } } impl<'tcx> TerminatorKind<'tcx> { pub fn if_( tcx: TyCtxt<'tcx>, cond: Operand<'tcx>, t: BasicBlock, f: BasicBlock, ) -> TerminatorKind<'tcx> { static BOOL_SWITCH_FALSE: &[u128] = &[0]; TerminatorKind::SwitchInt { discr: cond, switch_ty: tcx.types.bool, values: From::from(BOOL_SWITCH_FALSE), targets: vec![f, t], } } pub fn successors(&self) -> Successors<'_> { use self::TerminatorKind::*; match *self { Resume | Abort | GeneratorDrop | Return | Unreachable | Call { destination: None, cleanup: None, .. } | InlineAsm { destination: None, .. } => None.into_iter().chain(&[]), Goto { target: ref t } | Call { destination: None, cleanup: Some(ref t), .. } | Call { destination: Some((_, ref t)), cleanup: None, .. } | Yield { resume: ref t, drop: None, .. } | DropAndReplace { target: ref t, unwind: None, .. } | Drop { target: ref t, unwind: None, .. } | Assert { target: ref t, cleanup: None, .. } | FalseUnwind { real_target: ref t, unwind: None } | InlineAsm { destination: Some(ref t), .. } => Some(t).into_iter().chain(&[]), Call { destination: Some((_, ref t)), cleanup: Some(ref u), .. } | Yield { resume: ref t, drop: Some(ref u), .. } | DropAndReplace { target: ref t, unwind: Some(ref u), .. } | Drop { target: ref t, unwind: Some(ref u), .. } | Assert { target: ref t, cleanup: Some(ref u), .. } | FalseUnwind { real_target: ref t, unwind: Some(ref u) } => { Some(t).into_iter().chain(slice::from_ref(u)) } SwitchInt { ref targets, .. } => None.into_iter().chain(&targets[..]), FalseEdge { ref real_target, ref imaginary_target } => { Some(real_target).into_iter().chain(slice::from_ref(imaginary_target)) } } } pub fn successors_mut(&mut self) -> SuccessorsMut<'_> { use self::TerminatorKind::*; match *self { Resume | Abort | GeneratorDrop | Return | Unreachable | Call { destination: None, cleanup: None, .. } | InlineAsm { destination: None, .. } => None.into_iter().chain(&mut []), Goto { target: ref mut t } | Call { destination: None, cleanup: Some(ref mut t), .. } | Call { destination: Some((_, ref mut t)), cleanup: None, .. } | Yield { resume: ref mut t, drop: None, .. } | DropAndReplace { target: ref mut t, unwind: 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), .. } => Some(t).into_iter().chain(&mut []), Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut u), .. } | Yield { resume: ref mut t, drop: Some(ref mut u), .. } | DropAndReplace { target: ref mut t, unwind: 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) } => { Some(t).into_iter().chain(slice::from_mut(u)) } SwitchInt { ref mut targets, .. } => None.into_iter().chain(&mut targets[..]), FalseEdge { ref mut real_target, ref mut imaginary_target } => { Some(real_target).into_iter().chain(slice::from_mut(imaginary_target)) } } } pub fn unwind(&self) -> Option<&Option<BasicBlock>> { match *self { TerminatorKind::Goto { .. } | TerminatorKind::Resume | TerminatorKind::Abort | TerminatorKind::Return | TerminatorKind::Unreachable | TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::FalseEdge { .. } | TerminatorKind::InlineAsm { .. } => None, TerminatorKind::Call { cleanup: ref unwind, .. } | TerminatorKind::Assert { cleanup: ref unwind, .. } | TerminatorKind::DropAndReplace { ref unwind, .. } | TerminatorKind::Drop { ref unwind, .. } | TerminatorKind::FalseUnwind { ref unwind, .. } => Some(unwind), } } pub fn unwind_mut(&mut self) -> Option<&mut Option<BasicBlock>> { match *self { TerminatorKind::Goto { .. } | TerminatorKind::Resume | TerminatorKind::Abort | TerminatorKind::Return | TerminatorKind::Unreachable | TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::FalseEdge { .. } | TerminatorKind::InlineAsm { .. } => None, TerminatorKind::Call { cleanup: ref mut unwind, .. } | TerminatorKind::Assert { cleanup: ref mut unwind, .. } | TerminatorKind::DropAndReplace { ref mut unwind, .. } | TerminatorKind::Drop { ref mut unwind, .. } | TerminatorKind::FalseUnwind { ref mut unwind, .. } => Some(unwind), } } } </del> impl<'tcx> BasicBlockData<'tcx> { pub fn new(terminator: Option<Terminator<'tcx>>) -> BasicBlockData<'tcx> { BasicBlockData { statements: vec![], terminator, is_cleanup: false }

Related discussion:
text: moved the file to over 3k LOC, but I didn't fix it there and instead just annotated the file so tidy ignores it. We should probably split the mir types into separate submodules by the way they are used in MIR. I think we can start by pulling out e.g. terminators and all their sub-types to a submodule <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim Will be interested in picking this up