targets.hash_stable(hcx, hasher);
}
mir::TerminatorKind::Resume |
+ mir::TerminatorKind::Abort |
mir::TerminatorKind::Return |
mir::TerminatorKind::GeneratorDrop |
mir::TerminatorKind::Unreachable => {}
/// continue. Emitted by build::scope::diverge_cleanup.
Resume,
+ /// Indicates that the landing pad is finished and that the process
+ /// should abort. Used to prevent unwinding for foreign items.
+ Abort,
+
/// Indicates a normal return. The return place should have
/// been filled in by now. This should occur at most once.
Return,
match *self {
Goto { target: ref b } => slice::from_ref(b).into_cow(),
SwitchInt { targets: ref b, .. } => b[..].into_cow(),
- Resume | GeneratorDrop => (&[]).into_cow(),
+ Resume | Abort | GeneratorDrop => (&[]).into_cow(),
Return => (&[]).into_cow(),
Unreachable => (&[]).into_cow(),
Call { destination: Some((_, t)), cleanup: Some(c), .. } => vec![t, c].into_cow(),
match *self {
Goto { target: ref mut b } => vec![b],
SwitchInt { targets: ref mut b, .. } => b.iter_mut().collect(),
- Resume | GeneratorDrop => Vec::new(),
+ Resume | Abort | GeneratorDrop => Vec::new(),
Return => Vec::new(),
Unreachable => Vec::new(),
Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut c), .. } => vec![t, c],
match *self {
TerminatorKind::Goto { .. } |
TerminatorKind::Resume |
+ TerminatorKind::Abort |
TerminatorKind::Return |
TerminatorKind::Unreachable |
TerminatorKind::GeneratorDrop |
Return => write!(fmt, "return"),
GeneratorDrop => write!(fmt, "generator_drop"),
Resume => write!(fmt, "resume"),
+ Abort => write!(fmt, "abort"),
Yield { ref value, .. } => write!(fmt, "_1 = suspend({:?})", value),
Unreachable => write!(fmt, "unreachable"),
Drop { ref location, .. } => write!(fmt, "drop({:?})", location),
pub fn fmt_successor_labels(&self) -> Vec<Cow<'static, str>> {
use self::TerminatorKind::*;
match *self {
- Return | Resume | Unreachable | GeneratorDrop => vec![],
+ Return | Resume | Abort | Unreachable | GeneratorDrop => vec![],
Goto { .. } => vec!["".into()],
SwitchInt { ref values, .. } => {
values.iter()
},
GeneratorDrop => GeneratorDrop,
Resume => Resume,
+ Abort => Abort,
Return => Return,
Unreachable => Unreachable,
FalseEdges { real_target, ref imaginary_targets } =>
},
Goto { .. } |
Resume |
+ Abort |
Return |
GeneratorDrop |
Unreachable |
}
TerminatorKind::Resume |
+ TerminatorKind::Abort |
TerminatorKind::Return |
TerminatorKind::GeneratorDrop |
TerminatorKind::Unreachable => {
});
}
TerminatorKind::Goto { target: _ }
+ | TerminatorKind::Abort
| TerminatorKind::Unreachable
| TerminatorKind::FalseEdges { .. } => {
// no data used, thus irrelevant to borrowck
match term.kind {
TerminatorKind::Goto { .. }
| TerminatorKind::Resume
+ | TerminatorKind::Abort
| TerminatorKind::Return
| TerminatorKind::GeneratorDrop
| TerminatorKind::Unreachable
TerminatorKind::Resume => if !is_cleanup {
span_mirbug!(self, block_data, "resume on non-cleanup block!")
},
+ TerminatorKind::Abort => if !is_cleanup {
+ span_mirbug!(self, block_data, "abort on non-cleanup block!")
+ },
TerminatorKind::Return => if is_cleanup {
span_mirbug!(self, block_data, "return on cleanup block")
},
}
}
}
+ mir::TerminatorKind::Abort |
mir::TerminatorKind::SwitchInt {..} |
mir::TerminatorKind::Drop {..} |
mir::TerminatorKind::DropAndReplace {..} |
match bb_data.terminator().kind {
mir::TerminatorKind::Return |
mir::TerminatorKind::Resume |
+ mir::TerminatorKind::Abort |
mir::TerminatorKind::GeneratorDrop |
mir::TerminatorKind::Unreachable => {}
mir::TerminatorKind::Goto { ref target } |
match term.kind {
TerminatorKind::Goto { target: _ } |
TerminatorKind::Resume |
+ TerminatorKind::Abort |
TerminatorKind::GeneratorDrop |
TerminatorKind::FalseEdges { .. } |
TerminatorKind::Unreachable => { }
GeneratorDrop => unimplemented!(),
DropAndReplace { .. } => unimplemented!(),
Resume => unimplemented!(),
+ Abort => unimplemented!(),
FalseEdges { .. } => bug!("should have been eliminated by `simplify_branches` mir pass"),
Unreachable => return err!(Unreachable),
}
mir::TerminatorKind::Goto { .. } |
mir::TerminatorKind::SwitchInt { .. } |
mir::TerminatorKind::Resume |
+ mir::TerminatorKind::Abort |
mir::TerminatorKind::Return |
mir::TerminatorKind::Unreachable |
mir::TerminatorKind::Assert { .. } => {}
TerminatorKind::DropAndReplace { .. } |
TerminatorKind::GeneratorDrop |
TerminatorKind::Resume |
+ TerminatorKind::Abort |
TerminatorKind::Return |
TerminatorKind::Unreachable |
TerminatorKind::FalseEdges { .. } => {
*kind = TerminatorKind::Goto { target: tgt }
}
}
+ TerminatorKind::Abort => { }
TerminatorKind::Unreachable => { }
TerminatorKind::FalseEdges { ref mut real_target, ref mut imaginary_targets } => {
*real_target = self.update_target(*real_target);
TerminatorKind::SwitchInt {..} |
TerminatorKind::DropAndReplace { .. } |
TerminatorKind::Resume |
+ TerminatorKind::Abort |
TerminatorKind::GeneratorDrop |
TerminatorKind::Yield { .. } |
TerminatorKind::Unreachable |
TerminatorKind::GeneratorDrop |
TerminatorKind::Yield { .. } |
TerminatorKind::Return |
+ TerminatorKind::Abort |
TerminatorKind::Unreachable |
TerminatorKind::Call { .. } |
TerminatorKind::Assert { .. } |
TerminatorKind::Goto { .. } => "TerminatorKind::Goto",
TerminatorKind::SwitchInt { .. } => "TerminatorKind::SwitchInt",
TerminatorKind::Resume => "TerminatorKind::Resume",
+ TerminatorKind::Abort => "TerminatorKind::Abort",
TerminatorKind::Return => "TerminatorKind::Return",
TerminatorKind::Unreachable => "TerminatorKind::Unreachable",
TerminatorKind::Drop { .. } => "TerminatorKind::Drop",
match data.terminator().kind {
TerminatorKind::Goto { .. } |
TerminatorKind::Resume |
+ TerminatorKind::Abort |
TerminatorKind::Return |
TerminatorKind::GeneratorDrop |
TerminatorKind::Unreachable |
}
}
+ mir::TerminatorKind::Abort => {
+ // Call core::intrinsics::abort()
+ let fnname = bcx.ccx.get_intrinsic(&("llvm.trap"));
+ bcx.call(fnname, &[], None);
+ bcx.unreachable();
+ }
+
mir::TerminatorKind::Goto { target } => {
funclet_br(self, bcx, target);
}