Skip to content

Commit 5b34690

Browse files
committed
Remove the Panic block terminator
1 parent ecf4d0e commit 5b34690

File tree

8 files changed

+107
-32
lines changed

8 files changed

+107
-32
lines changed

src/librustc/mir/repr.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,6 @@ pub enum Terminator<'tcx> {
204204
target: BasicBlock,
205205
},
206206

207-
/// block should initiate unwinding; should be one successor
208-
/// that does cleanup and branches to DIVERGE_BLOCK
209-
Panic {
210-
target: BasicBlock,
211-
},
212-
213207
/// jump to branch 0 if this lvalue evaluates to true
214208
If {
215209
cond: Operand<'tcx>,
@@ -320,7 +314,6 @@ impl<'tcx> Terminator<'tcx> {
320314
use self::Terminator::*;
321315
match *self {
322316
Goto { target: ref b } => slice::ref_slice(b),
323-
Panic { target: ref b } => slice::ref_slice(b),
324317
If { targets: ref b, .. } => b.as_slice(),
325318
Switch { targets: ref b, .. } => b,
326319
SwitchInt { targets: ref b, .. } => b,
@@ -340,7 +333,6 @@ impl<'tcx> Terminator<'tcx> {
340333
use self::Terminator::*;
341334
match *self {
342335
Goto { target: ref mut b } => slice::mut_ref_slice(b),
343-
Panic { target: ref mut b } => slice::mut_ref_slice(b),
344336
If { targets: ref mut b, .. } => b.as_mut_slice(),
345337
Switch { targets: ref mut b, .. } => b,
346338
SwitchInt { targets: ref mut b, .. } => b,
@@ -401,7 +393,6 @@ impl<'tcx> Terminator<'tcx> {
401393
use self::Terminator::*;
402394
match *self {
403395
Goto { .. } => write!(fmt, "goto"),
404-
Panic { .. } => write!(fmt, "panic"),
405396
If { cond: ref lv, .. } => write!(fmt, "if({:?})", lv),
406397
Switch { discr: ref lv, .. } => write!(fmt, "switch({:?})", lv),
407398
SwitchInt { discr: ref lv, .. } => write!(fmt, "switchInt({:?})", lv),
@@ -424,7 +415,7 @@ impl<'tcx> Terminator<'tcx> {
424415
use self::Terminator::*;
425416
match *self {
426417
Diverge | Return | Resume => vec![],
427-
Goto { .. } | Panic { .. } => vec!["".into_cow()],
418+
Goto { .. } => vec!["".into_cow()],
428419
If { .. } => vec!["true".into_cow(), "false".into_cow()],
429420
Call { .. } => vec!["return".into_cow(), "unwind".into_cow()],
430421
DivergingCall { .. } => vec!["unwind".into_cow()],

src/librustc/mir/visit.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ pub trait Visitor<'tcx> {
107107

108108
fn super_terminator(&mut self, block: BasicBlock, terminator: &Terminator<'tcx>) {
109109
match *terminator {
110-
Terminator::Goto { target } |
111-
Terminator::Panic { target } => {
110+
Terminator::Goto { target } => {
112111
self.visit_branch(block, target);
113112
}
114113

@@ -405,8 +404,7 @@ pub trait MutVisitor<'tcx> {
405404
block: BasicBlock,
406405
terminator: &mut Terminator<'tcx>) {
407406
match *terminator {
408-
Terminator::Goto { target } |
409-
Terminator::Panic { target } => {
407+
Terminator::Goto { target } => {
410408
self.visit_branch(block, target);
411409
}
412410

src/librustc_mir/build/expr/as_lvalue.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,15 @@ impl<'a,'tcx> Builder<'a,'tcx> {
6363
this.cfg.push_assign(block, expr_span, // lt = idx < len
6464
&lt, Rvalue::BinaryOp(BinOp::Lt,
6565
idx.clone(),
66-
Operand::Consume(len)));
66+
Operand::Consume(len.clone())));
6767

6868
let (success, failure) = (this.cfg.start_new_block(), this.cfg.start_new_block());
6969
this.cfg.terminate(block,
7070
Terminator::If {
7171
cond: Operand::Consume(lt),
7272
targets: (success, failure),
7373
});
74-
this.panic(failure);
74+
this.panic_bound_check(failure, idx.clone(), Operand::Consume(len), expr_span);
7575
success.and(slice.index(idx))
7676
}
7777
ExprKind::SelfRef => {

src/librustc_mir/build/matches/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
8989
// not entirely precise
9090
if !otherwise.is_empty() {
9191
let join_block = self.join_otherwise_blocks(otherwise);
92-
self.panic(join_block);
92+
self.panic(join_block, "something about matches algorithm not being precise", span);
9393
}
9494

9595
// all the arm blocks will rejoin here

src/librustc_mir/build/scope.rs

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,12 @@ should go to.
8888

8989
use build::{BlockAnd, BlockAndExtension, Builder};
9090
use rustc::middle::region::CodeExtent;
91-
use rustc::middle::ty::Ty;
91+
use rustc::middle::lang_items;
92+
use rustc::middle::subst::Substs;
93+
use rustc::middle::ty::{Ty, Region};
9294
use rustc::mir::repr::*;
93-
use syntax::codemap::Span;
95+
use syntax::codemap::{Span, DUMMY_SP};
96+
use syntax::parse::token::intern_and_get_ident;
9497

9598
pub struct Scope<'tcx> {
9699
extent: CodeExtent,
@@ -261,13 +264,6 @@ impl<'a,'tcx> Builder<'a,'tcx> {
261264
self.scopes.iter().rev().flat_map(|b| b.cached_block).next()
262265
}
263266

264-
/// Create diverge cleanup and branch to it from `block`.
265-
pub fn panic(&mut self, block: BasicBlock) {
266-
// FIXME: panic terminator should also have conditional cleanup?
267-
let cleanup = self.diverge_cleanup().unwrap_or(DIVERGE_BLOCK);
268-
self.cfg.terminate(block, Terminator::Panic { target: cleanup });
269-
}
270-
271267
/// Indicates that `lvalue` should be dropped on exit from
272268
/// `extent`.
273269
pub fn schedule_drop(&mut self,
@@ -299,4 +295,94 @@ impl<'a,'tcx> Builder<'a,'tcx> {
299295
pub fn extent_of_outermost_scope(&self) -> CodeExtent {
300296
self.scopes.first().map(|scope| scope.extent).unwrap()
301297
}
298+
299+
pub fn panic_bound_check(&mut self,
300+
block: BasicBlock,
301+
index: Operand<'tcx>,
302+
len: Operand<'tcx>,
303+
span: Span) {
304+
let cleanup = self.diverge_cleanup();
305+
let func = self.lang_function(lang_items::PanicBoundsCheckFnLangItem);
306+
let str_ty = self.hir.tcx().mk_static_str();
307+
let tup_ty = self.hir.tcx().mk_tup(vec![str_ty, self.hir.tcx().types.u32]);
308+
// FIXME: ReStatic might be wrong here?
309+
let ref_region = self.hir.tcx().mk_region(Region::ReStatic);
310+
let ref_ty = self.hir.tcx().mk_imm_ref(ref_region, tup_ty.clone());
311+
let (file_arg, line_arg) = self.span_to_fileline_args(span);
312+
let (tuple, tuple_ref) = (self.temp(tup_ty), self.temp(ref_ty));
313+
self.cfg.push_assign(block, DUMMY_SP, &tuple, // tuple = (message_arg, file_arg, line_arg);
314+
Rvalue::Aggregate(AggregateKind::Tuple, vec![file_arg, line_arg]));
315+
// FIXME: ReStatic might be wrong here?
316+
self.cfg.push_assign(block, DUMMY_SP, &tuple_ref, // tuple_ref = &tuple;
317+
Rvalue::Ref(*ref_region, BorrowKind::Unique, tuple));
318+
self.cfg.terminate(block, Terminator::DivergingCall {
319+
func: func,
320+
args: vec![Operand::Consume(tuple_ref), index, len],
321+
cleanup: cleanup,
322+
});
323+
}
324+
325+
/// Create diverge cleanup and branch to it from `block`.
326+
pub fn panic(&mut self, block: BasicBlock, msg: &'static str, span: Span) {
327+
let cleanup = self.diverge_cleanup();
328+
let func = self.lang_function(lang_items::PanicFnLangItem);
329+
330+
let str_ty = self.hir.tcx().mk_static_str();
331+
let tup_ty = self.hir.tcx().mk_tup(vec![str_ty, str_ty, self.hir.tcx().types.u32]);
332+
// FIXME: ReStatic might be wrong here?
333+
let ref_region = self.hir.tcx().mk_region(Region::ReStatic);
334+
let ref_ty = self.hir.tcx().mk_imm_ref(ref_region, tup_ty.clone());
335+
let message_arg = Operand::Constant(Constant {
336+
span: DUMMY_SP,
337+
ty: str_ty,
338+
literal: self.hir.str_literal(intern_and_get_ident(msg))
339+
});
340+
let (file_arg, line_arg) = self.span_to_fileline_args(span);
341+
let tuple = self.temp(tup_ty);
342+
let tuple_ref = self.temp(ref_ty);
343+
self.cfg.push_assign(block, DUMMY_SP, &tuple, // tuple = (message_arg, file_arg, line_arg);
344+
Rvalue::Aggregate(AggregateKind::Tuple,
345+
vec![message_arg, file_arg, line_arg])
346+
);
347+
// FIXME: ReStatic might be wrong here?
348+
self.cfg.push_assign(block, DUMMY_SP, &tuple_ref, // tuple_ref = &tuple;
349+
Rvalue::Ref(*ref_region, BorrowKind::Unique, tuple));
350+
351+
self.cfg.terminate(block, Terminator::DivergingCall {
352+
func: func,
353+
args: vec![Operand::Consume(tuple_ref)],
354+
cleanup: cleanup,
355+
});
356+
}
357+
358+
fn lang_function(&mut self, lang_item: lang_items::LangItem) -> Operand<'tcx> {
359+
let funcdid = match self.hir.tcx().lang_items.require(lang_item) {
360+
Ok(d) => d,
361+
Err(m) => {
362+
self.hir.tcx().sess.fatal(&*m)
363+
}
364+
};
365+
Operand::Constant(Constant {
366+
span: DUMMY_SP,
367+
ty: self.hir.tcx().lookup_item_type(funcdid).ty,
368+
literal: Literal::Item {
369+
def_id: funcdid,
370+
kind: ItemKind::Function,
371+
substs: self.hir.tcx().mk_substs(Substs::empty())
372+
}
373+
})
374+
}
375+
376+
fn span_to_fileline_args(&mut self, span: Span) -> (Operand<'tcx>, Operand<'tcx>) {
377+
let span_lines = self.hir.tcx().sess.codemap().lookup_char_pos(span.lo);
378+
(Operand::Constant(Constant {
379+
span: DUMMY_SP,
380+
ty: self.hir.tcx().mk_static_str(),
381+
literal: self.hir.str_literal(intern_and_get_ident(&span_lines.file.name))
382+
}), Operand::Constant(Constant {
383+
span: DUMMY_SP,
384+
ty: self.hir.tcx().types.u32,
385+
literal: self.hir.usize_literal(span_lines.line)
386+
}))
387+
}
302388
}

src/librustc_mir/hair/cx/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc::middle::const_eval::{self, ConstVal};
2222
use rustc::middle::infer::InferCtxt;
2323
use rustc::middle::ty::{self, Ty};
2424
use syntax::codemap::Span;
25+
use syntax::parse::token;
2526
use rustc_front::hir;
2627

2728
#[derive(Copy, Clone)]
@@ -61,6 +62,10 @@ impl<'a,'tcx:'a> Cx<'a, 'tcx> {
6162
self.tcx.types.bool
6263
}
6364

65+
pub fn str_literal(&mut self, value: token::InternedString) -> Literal<'tcx> {
66+
Literal::Value { value: ConstVal::Str(value) }
67+
}
68+
6469
pub fn true_literal(&mut self) -> Literal<'tcx> {
6570
Literal::Value { value: ConstVal::Bool(true) }
6671
}

src/librustc_mir/transform/erase_regions.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ impl<'a, 'tcx> EraseRegions<'a, 'tcx> {
8181
Terminator::Goto { .. } |
8282
Terminator::Diverge |
8383
Terminator::Resume |
84-
Terminator::Return |
85-
Terminator::Panic { .. } => {
84+
Terminator::Return => {
8685
/* nothing to do */
8786
}
8887
Terminator::If { ref mut cond, .. } => {

src/librustc_trans/trans/mir/block.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
4040
build::Br(bcx, self.llblock(target), DebugLoc::None)
4141
}
4242

43-
mir::Terminator::Panic { .. } => {
44-
unimplemented!()
45-
}
46-
4743
mir::Terminator::If { ref cond, targets: (true_bb, false_bb) } => {
4844
let cond = self.trans_operand(bcx, cond);
4945
let lltrue = self.llblock(true_bb);

0 commit comments

Comments
 (0)