Translation part of drop panic recovery

With this commit we now finally execute all the leftover drops once some drop panics for some
reason!
This commit is contained in:
Simonas Kazlauskas 2016-01-30 19:32:50 +02:00
parent 98265d3385
commit ebf6341d1d
4 changed files with 68 additions and 9 deletions

View File

@ -95,11 +95,36 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
base::build_return_block(bcx.fcx, bcx, return_ty, DebugLoc::None);
}
mir::Terminator::Drop { ref value, target, unwind: _ } => {
mir::Terminator::Drop { ref value, target, unwind } => {
let lvalue = self.trans_lvalue(bcx, value);
// FIXME: this does not account for possibility of unwinding (and totally should).
glue::drop_ty(bcx, lvalue.llval, lvalue.ty.to_ty(bcx.tcx()), DebugLoc::None);
build::Br(bcx, self.llblock(target), DebugLoc::None);
let ty = lvalue.ty.to_ty(bcx.tcx());
// Double check for necessity to drop
if !glue::type_needs_drop(bcx.tcx(), ty) {
build::Br(bcx, self.llblock(target), DebugLoc::None);
return;
}
let drop_fn = glue::get_drop_glue(bcx.ccx(), ty);
let drop_ty = glue::get_drop_glue_type(bcx.ccx(), ty);
let llvalue = if drop_ty != ty {
build::PointerCast(bcx, lvalue.llval,
type_of::type_of(bcx.ccx(), drop_ty).ptr_to())
} else {
lvalue.llval
};
if let Some(unwind) = unwind {
let uwbcx = self.bcx(unwind);
let unwind = self.make_landing_pad(uwbcx);
build::Invoke(bcx,
drop_fn,
&[llvalue],
self.llblock(target),
unwind.llbb,
None,
DebugLoc::None);
} else {
build::Call(bcx, drop_fn, &[llvalue], None, DebugLoc::None);
build::Br(bcx, self.llblock(target), DebugLoc::None);
}
}
mir::Terminator::Call { ref func, ref args, ref destination, ref cleanup } => {

View File

@ -65,7 +65,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
assert!(lvalue.llextra != ptr::null_mut());
lvalue.llextra
}
_ => bcx.sess().bug("unexpected type in get_base_and_len"),
_ => bcx.sess().bug("unexpected type in lvalue_len"),
}
}

View File

@ -195,8 +195,8 @@ fn arg_value_refs<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>,
mod analyze;
mod block;
mod constant;
mod lvalue;
mod rvalue;
mod operand;
mod statement;
mod did;
mod lvalue;
mod operand;
mod rvalue;
mod statement;

View File

@ -0,0 +1,34 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(rustc_attrs)]
// error-pattern:panic 1
// error-pattern:drop 2
use std::io::{self, Write};
struct Droppable(u32);
impl Drop for Droppable {
fn drop(&mut self) {
if self.0 == 1 {
panic!("panic 1");
} else {
write!(io::stderr(), "drop {}", self.0);
}
}
}
#[rustc_mir]
fn mir() {
let x = Droppable(2);
let y = Droppable(1);
}
fn main() {
mir();
}