Reduce extensions to FunctionContext in cleanup.
This commit is contained in:
parent
1804131b6d
commit
f051c60d92
@ -398,7 +398,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
|
||||
|
||||
let llfn = callee.reify(bcx.ccx());
|
||||
let llret;
|
||||
if let Some(landing_pad) = self_scope.as_ref().and_then(|c| c.landing_pad) {
|
||||
if let Some(landing_pad) = self_scope.landing_pad {
|
||||
let normal_bcx = bcx.fcx().build_new_block("normal-return");
|
||||
llret = bcx.invoke(llfn, &llargs[..], normal_bcx.llbb(), landing_pad, None);
|
||||
bcx = normal_bcx;
|
||||
@ -416,7 +416,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
|
||||
if fn_ret.0.is_never() {
|
||||
bcx.unreachable();
|
||||
}
|
||||
fcx.trans_scope(&bcx, self_scope);
|
||||
self_scope.trans(&bcx);
|
||||
fcx.finish(&bcx);
|
||||
|
||||
ccx.instances().borrow_mut().insert(method_instance, lloncefn);
|
||||
|
@ -29,7 +29,7 @@ use rustc::ty::Ty;
|
||||
|
||||
pub struct CleanupScope<'tcx> {
|
||||
// Cleanup to run upon scope exit.
|
||||
cleanup: DropValue<'tcx>,
|
||||
cleanup: Option<DropValue<'tcx>>,
|
||||
|
||||
// Computed on creation if compiling with landing pads (!sess.no_landing_pads)
|
||||
pub landing_pad: Option<BasicBlockRef>,
|
||||
@ -92,21 +92,11 @@ impl PartialEq for UnwindKind {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
||||
pub fn trans_scope(
|
||||
&self,
|
||||
bcx: &BlockAndBuilder<'blk, 'tcx>,
|
||||
custom_scope: Option<CleanupScope<'tcx>>
|
||||
) {
|
||||
if let Some(scope) = custom_scope {
|
||||
scope.cleanup.trans(None, &bcx);
|
||||
}
|
||||
}
|
||||
|
||||
/// Schedules a (deep) drop of `val`, which is a pointer to an instance of
|
||||
/// `ty`
|
||||
pub fn schedule_drop_mem(&self, val: ValueRef, ty: Ty<'tcx>) -> Option<CleanupScope<'tcx>> {
|
||||
if !self.type_needs_drop(ty) { return None; }
|
||||
impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
||||
/// Schedules a (deep) drop of `val`, which is a pointer to an instance of `ty`
|
||||
pub fn schedule_drop_mem(&self, val: ValueRef, ty: Ty<'tcx>) -> CleanupScope<'tcx> {
|
||||
if !self.type_needs_drop(ty) { return CleanupScope::noop(); }
|
||||
let drop = DropValue {
|
||||
val: val,
|
||||
ty: ty,
|
||||
@ -115,7 +105,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
||||
|
||||
debug!("schedule_drop_mem(val={:?}, ty={:?}) skip_dtor={}", Value(val), ty, drop.skip_dtor);
|
||||
|
||||
Some(CleanupScope::new(self, drop))
|
||||
CleanupScope::new(self, drop)
|
||||
}
|
||||
|
||||
/// Issue #23611: Schedules a (deep) drop of the contents of
|
||||
@ -123,11 +113,10 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
||||
/// `ty`. The scheduled code handles extracting the discriminant
|
||||
/// and dropping the contents associated with that variant
|
||||
/// *without* executing any associated drop implementation.
|
||||
pub fn schedule_drop_adt_contents(&self, val: ValueRef, ty: Ty<'tcx>)
|
||||
-> Option<CleanupScope<'tcx>> {
|
||||
pub fn schedule_drop_adt_contents(&self, val: ValueRef, ty: Ty<'tcx>) -> CleanupScope<'tcx> {
|
||||
// `if` below could be "!contents_needs_drop"; skipping drop
|
||||
// is just an optimization, so sound to be conservative.
|
||||
if !self.type_needs_drop(ty) { return None; }
|
||||
if !self.type_needs_drop(ty) { return CleanupScope::noop(); }
|
||||
|
||||
let drop = DropValue {
|
||||
val: val,
|
||||
@ -138,15 +127,14 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
||||
debug!("schedule_drop_adt_contents(val={:?}, ty={:?}) skip_dtor={}",
|
||||
Value(val), ty, drop.skip_dtor);
|
||||
|
||||
Some(CleanupScope::new(self, drop))
|
||||
CleanupScope::new(self, drop)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<'tcx> CleanupScope<'tcx> {
|
||||
fn new<'a>(fcx: &FunctionContext<'a, 'tcx>, drop_val: DropValue<'tcx>) -> CleanupScope<'tcx> {
|
||||
CleanupScope {
|
||||
cleanup: drop_val,
|
||||
cleanup: Some(drop_val),
|
||||
landing_pad: if !fcx.ccx.sess().no_landing_pads() {
|
||||
Some(CleanupScope::get_landing_pad(fcx, &drop_val))
|
||||
} else {
|
||||
@ -155,6 +143,19 @@ impl<'tcx> CleanupScope<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop() -> CleanupScope<'tcx> {
|
||||
CleanupScope {
|
||||
cleanup: None,
|
||||
landing_pad: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trans<'a>(self, bcx: &'a BlockAndBuilder<'a, 'tcx>) {
|
||||
if let Some(cleanup) = self.cleanup {
|
||||
cleanup.trans(None, &bcx);
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a landing pad for the top scope. The landing pad will perform all cleanups necessary
|
||||
/// for an unwind and then `resume` to continue error propagation:
|
||||
///
|
||||
|
@ -32,6 +32,7 @@ use type_of::{type_of, sizing_type_of, align_of};
|
||||
use type_::Type;
|
||||
use value::Value;
|
||||
use Disr;
|
||||
use cleanup::CleanupScope;
|
||||
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
@ -224,7 +225,7 @@ fn trans_custom_dtor<'blk, 'tcx>(mut bcx: BlockAndBuilder<'blk, 'tcx>,
|
||||
let contents_scope = if !shallow_drop {
|
||||
bcx.fcx().schedule_drop_adt_contents(v0, t)
|
||||
} else {
|
||||
None
|
||||
CleanupScope::noop()
|
||||
};
|
||||
|
||||
let (sized_args, unsized_args);
|
||||
@ -252,7 +253,7 @@ fn trans_custom_dtor<'blk, 'tcx>(mut bcx: BlockAndBuilder<'blk, 'tcx>,
|
||||
let callee = Callee::def(bcx.ccx(), dtor_did, vtbl.substs);
|
||||
let fn_ty = callee.direct_fn_type(bcx.ccx(), &[]);
|
||||
let llret;
|
||||
if let Some(landing_pad) = contents_scope.as_ref().and_then(|c| c.landing_pad) {
|
||||
if let Some(landing_pad) = contents_scope.landing_pad {
|
||||
let normal_bcx = bcx.fcx().build_new_block("normal-return");
|
||||
llret = bcx.invoke(callee.reify(bcx.ccx()), args, normal_bcx.llbb(), landing_pad, None);
|
||||
bcx = normal_bcx;
|
||||
@ -260,7 +261,7 @@ fn trans_custom_dtor<'blk, 'tcx>(mut bcx: BlockAndBuilder<'blk, 'tcx>,
|
||||
llret = bcx.call(callee.reify(bcx.ccx()), args, None);
|
||||
}
|
||||
fn_ty.apply_attrs_callsite(llret);
|
||||
bcx.fcx().trans_scope(&bcx, contents_scope);
|
||||
contents_scope.trans(&bcx);
|
||||
bcx
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user