Skip to content

Commit ebf6341

Browse files
committed
Translation part of drop panic recovery
With this commit we now finally execute all the leftover drops once some drop panics for some reason!
1 parent 98265d3 commit ebf6341

File tree

4 files changed

+66
-7
lines changed

4 files changed

+66
-7
lines changed

src/librustc_trans/trans/mir/block.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,36 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
9595
base::build_return_block(bcx.fcx, bcx, return_ty, DebugLoc::None);
9696
}
9797

98-
mir::Terminator::Drop { ref value, target, unwind: _ } => {
98+
mir::Terminator::Drop { ref value, target, unwind } => {
9999
let lvalue = self.trans_lvalue(bcx, value);
100-
// FIXME: this does not account for possibility of unwinding (and totally should).
101-
glue::drop_ty(bcx, lvalue.llval, lvalue.ty.to_ty(bcx.tcx()), DebugLoc::None);
102-
build::Br(bcx, self.llblock(target), DebugLoc::None);
100+
let ty = lvalue.ty.to_ty(bcx.tcx());
101+
// Double check for necessity to drop
102+
if !glue::type_needs_drop(bcx.tcx(), ty) {
103+
build::Br(bcx, self.llblock(target), DebugLoc::None);
104+
return;
105+
}
106+
let drop_fn = glue::get_drop_glue(bcx.ccx(), ty);
107+
let drop_ty = glue::get_drop_glue_type(bcx.ccx(), ty);
108+
let llvalue = if drop_ty != ty {
109+
build::PointerCast(bcx, lvalue.llval,
110+
type_of::type_of(bcx.ccx(), drop_ty).ptr_to())
111+
} else {
112+
lvalue.llval
113+
};
114+
if let Some(unwind) = unwind {
115+
let uwbcx = self.bcx(unwind);
116+
let unwind = self.make_landing_pad(uwbcx);
117+
build::Invoke(bcx,
118+
drop_fn,
119+
&[llvalue],
120+
self.llblock(target),
121+
unwind.llbb,
122+
None,
123+
DebugLoc::None);
124+
} else {
125+
build::Call(bcx, drop_fn, &[llvalue], None, DebugLoc::None);
126+
build::Br(bcx, self.llblock(target), DebugLoc::None);
127+
}
103128
}
104129

105130
mir::Terminator::Call { ref func, ref args, ref destination, ref cleanup } => {

src/librustc_trans/trans/mir/lvalue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
6565
assert!(lvalue.llextra != ptr::null_mut());
6666
lvalue.llextra
6767
}
68-
_ => bcx.sess().bug("unexpected type in get_base_and_len"),
68+
_ => bcx.sess().bug("unexpected type in lvalue_len"),
6969
}
7070
}
7171

src/librustc_trans/trans/mir/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ fn arg_value_refs<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>,
195195
mod analyze;
196196
mod block;
197197
mod constant;
198+
mod did;
198199
mod lvalue;
199-
mod rvalue;
200200
mod operand;
201+
mod rvalue;
201202
mod statement;
202-
mod did;

src/test/run-fail/mir_drop_panics.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
#![feature(rustc_attrs)]
11+
// error-pattern:panic 1
12+
// error-pattern:drop 2
13+
use std::io::{self, Write};
14+
15+
struct Droppable(u32);
16+
impl Drop for Droppable {
17+
fn drop(&mut self) {
18+
if self.0 == 1 {
19+
panic!("panic 1");
20+
} else {
21+
write!(io::stderr(), "drop {}", self.0);
22+
}
23+
}
24+
}
25+
26+
#[rustc_mir]
27+
fn mir() {
28+
let x = Droppable(2);
29+
let y = Droppable(1);
30+
}
31+
32+
fn main() {
33+
mir();
34+
}

0 commit comments

Comments
 (0)