introduce an unreachable terminator

Use it instead of a `panic` for inexhaustive matches and correct the
comment. I think we trust our match-generation algorithm enough to
generate these blocks, and not generating an `unreachable` means that
LLVM won't optimize `match void() {}` to an `unreachable`.
This commit is contained in:
Ariel Ben-Yehuda 2016-06-08 19:26:19 +03:00 committed by Ariel Ben-Yehuda
parent 6405527ded
commit 798be90648
11 changed files with 37 additions and 92 deletions

View file

@ -374,6 +374,9 @@ pub enum TerminatorKind<'tcx> {
/// have been filled in by now. This should occur at most once.
Return,
/// Indicates a terminator that can never be reached.
Unreachable,
/// Drop the Lvalue
Drop {
location: Lvalue<'tcx>,
@ -432,6 +435,7 @@ impl<'tcx> TerminatorKind<'tcx> {
SwitchInt { targets: ref b, .. } => b[..].into_cow(),
Resume => (&[]).into_cow(),
Return => (&[]).into_cow(),
Unreachable => (&[]).into_cow(),
Call { destination: Some((_, t)), cleanup: Some(c), .. } => vec![t, c].into_cow(),
Call { destination: Some((_, ref t)), cleanup: None, .. } =>
slice::ref_slice(t).into_cow(),
@ -461,6 +465,7 @@ impl<'tcx> TerminatorKind<'tcx> {
SwitchInt { targets: ref mut b, .. } => b.iter_mut().collect(),
Resume => Vec::new(),
Return => Vec::new(),
Unreachable => Vec::new(),
Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut c), .. } => vec![t, c],
Call { destination: Some((_, ref mut t)), cleanup: None, .. } => vec![t],
Call { destination: None, cleanup: Some(ref mut c), .. } => vec![c],
@ -539,6 +544,7 @@ impl<'tcx> TerminatorKind<'tcx> {
SwitchInt { discr: ref lv, .. } => write!(fmt, "switchInt({:?})", lv),
Return => write!(fmt, "return"),
Resume => write!(fmt, "resume"),
Unreachable => write!(fmt, "unreachable"),
Drop { ref location, .. } => write!(fmt, "drop({:?})", location),
DropAndReplace { ref location, ref value, .. } =>
write!(fmt, "replace({:?} <- {:?})", location, value),
@ -582,7 +588,7 @@ impl<'tcx> TerminatorKind<'tcx> {
pub fn fmt_successor_labels(&self) -> Vec<Cow<'static, str>> {
use self::TerminatorKind::*;
match *self {
Return | Resume => vec![],
Return | Resume | Unreachable => vec![],
Goto { .. } => vec!["".into()],
If { .. } => vec!["true".into(), "false".into()],
Switch { ref adt_def, .. } => {

View file

@ -386,7 +386,8 @@ macro_rules! make_mir_visitor {
}
TerminatorKind::Resume |
TerminatorKind::Return => {
TerminatorKind::Return |
TerminatorKind::Unreachable => {
}
TerminatorKind::Drop { ref $($mutability)* location,