Remove the Panic block terminator
This commit is contained in:
parent
ecf4d0e3ad
commit
5b34690842
@ -204,12 +204,6 @@ pub enum Terminator<'tcx> {
|
||||
target: BasicBlock,
|
||||
},
|
||||
|
||||
/// block should initiate unwinding; should be one successor
|
||||
/// that does cleanup and branches to DIVERGE_BLOCK
|
||||
Panic {
|
||||
target: BasicBlock,
|
||||
},
|
||||
|
||||
/// jump to branch 0 if this lvalue evaluates to true
|
||||
If {
|
||||
cond: Operand<'tcx>,
|
||||
@ -320,7 +314,6 @@ impl<'tcx> Terminator<'tcx> {
|
||||
use self::Terminator::*;
|
||||
match *self {
|
||||
Goto { target: ref b } => slice::ref_slice(b),
|
||||
Panic { target: ref b } => slice::ref_slice(b),
|
||||
If { targets: ref b, .. } => b.as_slice(),
|
||||
Switch { targets: ref b, .. } => b,
|
||||
SwitchInt { targets: ref b, .. } => b,
|
||||
@ -340,7 +333,6 @@ impl<'tcx> Terminator<'tcx> {
|
||||
use self::Terminator::*;
|
||||
match *self {
|
||||
Goto { target: ref mut b } => slice::mut_ref_slice(b),
|
||||
Panic { target: ref mut b } => slice::mut_ref_slice(b),
|
||||
If { targets: ref mut b, .. } => b.as_mut_slice(),
|
||||
Switch { targets: ref mut b, .. } => b,
|
||||
SwitchInt { targets: ref mut b, .. } => b,
|
||||
@ -401,7 +393,6 @@ impl<'tcx> Terminator<'tcx> {
|
||||
use self::Terminator::*;
|
||||
match *self {
|
||||
Goto { .. } => write!(fmt, "goto"),
|
||||
Panic { .. } => write!(fmt, "panic"),
|
||||
If { cond: ref lv, .. } => write!(fmt, "if({:?})", lv),
|
||||
Switch { discr: ref lv, .. } => write!(fmt, "switch({:?})", lv),
|
||||
SwitchInt { discr: ref lv, .. } => write!(fmt, "switchInt({:?})", lv),
|
||||
@ -424,7 +415,7 @@ impl<'tcx> Terminator<'tcx> {
|
||||
use self::Terminator::*;
|
||||
match *self {
|
||||
Diverge | Return | Resume => vec![],
|
||||
Goto { .. } | Panic { .. } => vec!["".into_cow()],
|
||||
Goto { .. } => vec!["".into_cow()],
|
||||
If { .. } => vec!["true".into_cow(), "false".into_cow()],
|
||||
Call { .. } => vec!["return".into_cow(), "unwind".into_cow()],
|
||||
DivergingCall { .. } => vec!["unwind".into_cow()],
|
||||
|
@ -107,8 +107,7 @@ pub trait Visitor<'tcx> {
|
||||
|
||||
fn super_terminator(&mut self, block: BasicBlock, terminator: &Terminator<'tcx>) {
|
||||
match *terminator {
|
||||
Terminator::Goto { target } |
|
||||
Terminator::Panic { target } => {
|
||||
Terminator::Goto { target } => {
|
||||
self.visit_branch(block, target);
|
||||
}
|
||||
|
||||
@ -405,8 +404,7 @@ pub trait MutVisitor<'tcx> {
|
||||
block: BasicBlock,
|
||||
terminator: &mut Terminator<'tcx>) {
|
||||
match *terminator {
|
||||
Terminator::Goto { target } |
|
||||
Terminator::Panic { target } => {
|
||||
Terminator::Goto { target } => {
|
||||
self.visit_branch(block, target);
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
|
||||
this.cfg.push_assign(block, expr_span, // lt = idx < len
|
||||
<, Rvalue::BinaryOp(BinOp::Lt,
|
||||
idx.clone(),
|
||||
Operand::Consume(len)));
|
||||
Operand::Consume(len.clone())));
|
||||
|
||||
let (success, failure) = (this.cfg.start_new_block(), this.cfg.start_new_block());
|
||||
this.cfg.terminate(block,
|
||||
@ -71,7 +71,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
|
||||
cond: Operand::Consume(lt),
|
||||
targets: (success, failure),
|
||||
});
|
||||
this.panic(failure);
|
||||
this.panic_bound_check(failure, idx.clone(), Operand::Consume(len), expr_span);
|
||||
success.and(slice.index(idx))
|
||||
}
|
||||
ExprKind::SelfRef => {
|
||||
|
@ -89,7 +89,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
|
||||
// not entirely precise
|
||||
if !otherwise.is_empty() {
|
||||
let join_block = self.join_otherwise_blocks(otherwise);
|
||||
self.panic(join_block);
|
||||
self.panic(join_block, "something about matches algorithm not being precise", span);
|
||||
}
|
||||
|
||||
// all the arm blocks will rejoin here
|
||||
|
@ -88,9 +88,12 @@ should go to.
|
||||
|
||||
use build::{BlockAnd, BlockAndExtension, Builder};
|
||||
use rustc::middle::region::CodeExtent;
|
||||
use rustc::middle::ty::Ty;
|
||||
use rustc::middle::lang_items;
|
||||
use rustc::middle::subst::Substs;
|
||||
use rustc::middle::ty::{Ty, Region};
|
||||
use rustc::mir::repr::*;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
use syntax::parse::token::intern_and_get_ident;
|
||||
|
||||
pub struct Scope<'tcx> {
|
||||
extent: CodeExtent,
|
||||
@ -261,13 +264,6 @@ impl<'a,'tcx> Builder<'a,'tcx> {
|
||||
self.scopes.iter().rev().flat_map(|b| b.cached_block).next()
|
||||
}
|
||||
|
||||
/// Create diverge cleanup and branch to it from `block`.
|
||||
pub fn panic(&mut self, block: BasicBlock) {
|
||||
// FIXME: panic terminator should also have conditional cleanup?
|
||||
let cleanup = self.diverge_cleanup().unwrap_or(DIVERGE_BLOCK);
|
||||
self.cfg.terminate(block, Terminator::Panic { target: cleanup });
|
||||
}
|
||||
|
||||
/// Indicates that `lvalue` should be dropped on exit from
|
||||
/// `extent`.
|
||||
pub fn schedule_drop(&mut self,
|
||||
@ -299,4 +295,94 @@ impl<'a,'tcx> Builder<'a,'tcx> {
|
||||
pub fn extent_of_outermost_scope(&self) -> CodeExtent {
|
||||
self.scopes.first().map(|scope| scope.extent).unwrap()
|
||||
}
|
||||
|
||||
pub fn panic_bound_check(&mut self,
|
||||
block: BasicBlock,
|
||||
index: Operand<'tcx>,
|
||||
len: Operand<'tcx>,
|
||||
span: Span) {
|
||||
let cleanup = self.diverge_cleanup();
|
||||
let func = self.lang_function(lang_items::PanicBoundsCheckFnLangItem);
|
||||
let str_ty = self.hir.tcx().mk_static_str();
|
||||
let tup_ty = self.hir.tcx().mk_tup(vec![str_ty, self.hir.tcx().types.u32]);
|
||||
// FIXME: ReStatic might be wrong here?
|
||||
let ref_region = self.hir.tcx().mk_region(Region::ReStatic);
|
||||
let ref_ty = self.hir.tcx().mk_imm_ref(ref_region, tup_ty.clone());
|
||||
let (file_arg, line_arg) = self.span_to_fileline_args(span);
|
||||
let (tuple, tuple_ref) = (self.temp(tup_ty), self.temp(ref_ty));
|
||||
self.cfg.push_assign(block, DUMMY_SP, &tuple, // tuple = (message_arg, file_arg, line_arg);
|
||||
Rvalue::Aggregate(AggregateKind::Tuple, vec![file_arg, line_arg]));
|
||||
// FIXME: ReStatic might be wrong here?
|
||||
self.cfg.push_assign(block, DUMMY_SP, &tuple_ref, // tuple_ref = &tuple;
|
||||
Rvalue::Ref(*ref_region, BorrowKind::Unique, tuple));
|
||||
self.cfg.terminate(block, Terminator::DivergingCall {
|
||||
func: func,
|
||||
args: vec![Operand::Consume(tuple_ref), index, len],
|
||||
cleanup: cleanup,
|
||||
});
|
||||
}
|
||||
|
||||
/// Create diverge cleanup and branch to it from `block`.
|
||||
pub fn panic(&mut self, block: BasicBlock, msg: &'static str, span: Span) {
|
||||
let cleanup = self.diverge_cleanup();
|
||||
let func = self.lang_function(lang_items::PanicFnLangItem);
|
||||
|
||||
let str_ty = self.hir.tcx().mk_static_str();
|
||||
let tup_ty = self.hir.tcx().mk_tup(vec![str_ty, str_ty, self.hir.tcx().types.u32]);
|
||||
// FIXME: ReStatic might be wrong here?
|
||||
let ref_region = self.hir.tcx().mk_region(Region::ReStatic);
|
||||
let ref_ty = self.hir.tcx().mk_imm_ref(ref_region, tup_ty.clone());
|
||||
let message_arg = Operand::Constant(Constant {
|
||||
span: DUMMY_SP,
|
||||
ty: str_ty,
|
||||
literal: self.hir.str_literal(intern_and_get_ident(msg))
|
||||
});
|
||||
let (file_arg, line_arg) = self.span_to_fileline_args(span);
|
||||
let tuple = self.temp(tup_ty);
|
||||
let tuple_ref = self.temp(ref_ty);
|
||||
self.cfg.push_assign(block, DUMMY_SP, &tuple, // tuple = (message_arg, file_arg, line_arg);
|
||||
Rvalue::Aggregate(AggregateKind::Tuple,
|
||||
vec![message_arg, file_arg, line_arg])
|
||||
);
|
||||
// FIXME: ReStatic might be wrong here?
|
||||
self.cfg.push_assign(block, DUMMY_SP, &tuple_ref, // tuple_ref = &tuple;
|
||||
Rvalue::Ref(*ref_region, BorrowKind::Unique, tuple));
|
||||
|
||||
self.cfg.terminate(block, Terminator::DivergingCall {
|
||||
func: func,
|
||||
args: vec![Operand::Consume(tuple_ref)],
|
||||
cleanup: cleanup,
|
||||
});
|
||||
}
|
||||
|
||||
fn lang_function(&mut self, lang_item: lang_items::LangItem) -> Operand<'tcx> {
|
||||
let funcdid = match self.hir.tcx().lang_items.require(lang_item) {
|
||||
Ok(d) => d,
|
||||
Err(m) => {
|
||||
self.hir.tcx().sess.fatal(&*m)
|
||||
}
|
||||
};
|
||||
Operand::Constant(Constant {
|
||||
span: DUMMY_SP,
|
||||
ty: self.hir.tcx().lookup_item_type(funcdid).ty,
|
||||
literal: Literal::Item {
|
||||
def_id: funcdid,
|
||||
kind: ItemKind::Function,
|
||||
substs: self.hir.tcx().mk_substs(Substs::empty())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn span_to_fileline_args(&mut self, span: Span) -> (Operand<'tcx>, Operand<'tcx>) {
|
||||
let span_lines = self.hir.tcx().sess.codemap().lookup_char_pos(span.lo);
|
||||
(Operand::Constant(Constant {
|
||||
span: DUMMY_SP,
|
||||
ty: self.hir.tcx().mk_static_str(),
|
||||
literal: self.hir.str_literal(intern_and_get_ident(&span_lines.file.name))
|
||||
}), Operand::Constant(Constant {
|
||||
span: DUMMY_SP,
|
||||
ty: self.hir.tcx().types.u32,
|
||||
literal: self.hir.usize_literal(span_lines.line)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ use rustc::middle::const_eval::{self, ConstVal};
|
||||
use rustc::middle::infer::InferCtxt;
|
||||
use rustc::middle::ty::{self, Ty};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token;
|
||||
use rustc_front::hir;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@ -61,6 +62,10 @@ impl<'a,'tcx:'a> Cx<'a, 'tcx> {
|
||||
self.tcx.types.bool
|
||||
}
|
||||
|
||||
pub fn str_literal(&mut self, value: token::InternedString) -> Literal<'tcx> {
|
||||
Literal::Value { value: ConstVal::Str(value) }
|
||||
}
|
||||
|
||||
pub fn true_literal(&mut self) -> Literal<'tcx> {
|
||||
Literal::Value { value: ConstVal::Bool(true) }
|
||||
}
|
||||
|
@ -81,8 +81,7 @@ impl<'a, 'tcx> EraseRegions<'a, 'tcx> {
|
||||
Terminator::Goto { .. } |
|
||||
Terminator::Diverge |
|
||||
Terminator::Resume |
|
||||
Terminator::Return |
|
||||
Terminator::Panic { .. } => {
|
||||
Terminator::Return => {
|
||||
/* nothing to do */
|
||||
}
|
||||
Terminator::If { ref mut cond, .. } => {
|
||||
|
@ -40,10 +40,6 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||
build::Br(bcx, self.llblock(target), DebugLoc::None)
|
||||
}
|
||||
|
||||
mir::Terminator::Panic { .. } => {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
mir::Terminator::If { ref cond, targets: (true_bb, false_bb) } => {
|
||||
let cond = self.trans_operand(bcx, cond);
|
||||
let lltrue = self.llblock(true_bb);
|
||||
|
Loading…
x
Reference in New Issue
Block a user