1
Fork 0

address review comments

This commit is contained in:
Ariel Ben-Yehuda 2017-05-12 15:00:36 +03:00
parent 24c1a07c72
commit c6d0b5bdd8
4 changed files with 138 additions and 127 deletions

View file

@ -585,7 +585,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
})
}
pub fn const_usize(&self, val: usize) -> ConstInt {
pub fn const_usize(&self, val: u16) -> ConstInt {
match self.sess.target.uint_type {
ast::UintTy::U16 => ConstInt::Usize(ConstUsize::Us16(val as u16)),
ast::UintTy::U32 => ConstInt::Usize(ConstUsize::Us32(val as u32)),

View file

@ -22,7 +22,7 @@ use rustc::util::nodemap::FxHashMap;
use rustc_data_structures::indexed_set::IdxSetBuf;
use rustc_data_structures::indexed_vec::Idx;
use rustc_mir::util::patch::MirPatch;
use rustc_mir::util::elaborate_drops::{DropFlagState, elaborate_drop};
use rustc_mir::util::elaborate_drops::{DropFlagState, Unwind, elaborate_drop};
use rustc_mir::util::elaborate_drops::{DropElaborator, DropStyle, DropFlagMode};
use syntax::ast;
use syntax_pos::Span;
@ -399,14 +399,13 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
ctxt: self
},
terminator.source_info,
data.is_cleanup,
location,
path,
target,
if data.is_cleanup {
None
Unwind::InCleanup
} else {
Some(Option::unwrap_or(unwind, resume_block))
Unwind::To(Option::unwrap_or(unwind, resume_block))
},
bb)
}
@ -455,6 +454,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let bb = loc.block;
let data = &self.mir[bb];
let terminator = data.terminator();
assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported");
let assign = Statement {
kind: StatementKind::Assign(location.clone(), Rvalue::Use(value.clone())),
@ -477,7 +477,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
kind: TerminatorKind::Goto { target: target },
..*terminator
}),
is_cleanup: data.is_cleanup,
is_cleanup: false,
});
match self.move_data().rev_lookup.find(location) {
@ -491,11 +491,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
ctxt: self
},
terminator.source_info,
data.is_cleanup,
location,
path,
target,
Some(unwind),
Unwind::To(unwind),
bb);
on_all_children_bits(self.tcx, self.mir, self.move_data(), path, |child| {
self.set_drop_flag(Location { block: target, statement_index: 0 },

View file

@ -198,11 +198,10 @@ fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
elaborate_drops::elaborate_drop(
&mut elaborator,
source_info,
false,
&dropee,
(),
return_block,
Some(resume_block),
elaborate_drops::Unwind::To(resume_block),
START_BLOCK
);
elaborator.patch

View file

@ -50,6 +50,35 @@ pub enum DropFlagMode {
Deep
}
#[derive(Copy, Clone, Debug)]
pub enum Unwind {
To(BasicBlock),
InCleanup
}
impl Unwind {
fn is_cleanup(self) -> bool {
match self {
Unwind::To(..) => false,
Unwind::InCleanup => true
}
}
fn into_option(self) -> Option<BasicBlock> {
match self {
Unwind::To(bb) => Some(bb),
Unwind::InCleanup => None,
}
}
fn map<F>(self, f: F) -> Self where F: FnOnce(BasicBlock) -> BasicBlock {
match self {
Unwind::To(bb) => Unwind::To(f(bb)),
Unwind::InCleanup => Unwind::InCleanup
}
}
}
pub trait DropElaborator<'a, 'tcx: 'a> : fmt::Debug {
type Path : Copy + fmt::Debug;
@ -75,28 +104,25 @@ struct DropCtxt<'l, 'b: 'l, 'tcx: 'b, D>
elaborator: &'l mut D,
source_info: SourceInfo,
is_cleanup: bool,
lvalue: &'l Lvalue<'tcx>,
path: D::Path,
succ: BasicBlock,
unwind: Option<BasicBlock>,
unwind: Unwind,
}
pub fn elaborate_drop<'b, 'tcx, D>(
elaborator: &mut D,
source_info: SourceInfo,
is_cleanup: bool,
lvalue: &Lvalue<'tcx>,
path: D::Path,
succ: BasicBlock,
unwind: Option<BasicBlock>,
unwind: Unwind,
bb: BasicBlock)
where D: DropElaborator<'b, 'tcx>
{
assert_eq!(unwind.is_none(), is_cleanup);
DropCtxt {
elaborator, source_info, is_cleanup, lvalue, path, succ, unwind
elaborator, source_info, lvalue, path, succ, unwind
}.elaborate_drop(bb)
}
@ -145,14 +171,13 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
self.elaborator.patch().patch_terminator(bb, TerminatorKind::Drop {
location: self.lvalue.clone(),
target: self.succ,
unwind: self.unwind
unwind: self.unwind.into_option(),
});
}
DropStyle::Conditional => {
let is_cleanup = self.is_cleanup; // FIXME(#6393)
let unwind = self.unwind; // FIXME(#6393)
let succ = self.succ;
let drop_bb = self.complete_drop(
is_cleanup, Some(DropFlagMode::Deep), succ);
let drop_bb = self.complete_drop(Some(DropFlagMode::Deep), succ, unwind);
self.elaborator.patch().patch_terminator(bb, TerminatorKind::Goto {
target: drop_bb
});
@ -189,11 +214,10 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
}
fn drop_subpath(&mut self,
is_cleanup: bool,
lvalue: &Lvalue<'tcx>,
path: Option<D::Path>,
succ: BasicBlock,
unwind: Option<BasicBlock>)
unwind: Unwind)
-> BasicBlock
{
if let Some(path) = path {
@ -202,7 +226,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
DropCtxt {
elaborator: self.elaborator,
source_info: self.source_info,
path, lvalue, succ, unwind, is_cleanup
path, lvalue, succ, unwind,
}.elaborated_drop_block()
} else {
debug!("drop_subpath: for rest field {:?}", lvalue);
@ -210,11 +234,11 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
DropCtxt {
elaborator: self.elaborator,
source_info: self.source_info,
lvalue, succ, unwind, is_cleanup,
lvalue, succ, unwind,
// Using `self.path` here to condition the drop on
// our own drop flag.
path: self.path
}.complete_drop(is_cleanup, None, succ)
}.complete_drop(None, succ, unwind)
}
}
@ -222,24 +246,15 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
/// the list of steps in it in reverse order.
///
/// `unwind_ladder` is such a list of steps in reverse order,
/// which is called instead of the next step if the drop unwinds
/// (the first field is never reached). If it is `None`, all
/// unwind targets are left blank.
fn drop_halfladder<'a>(&mut self,
unwind_ladder: Option<&[BasicBlock]>,
succ: BasicBlock,
fields: &[(Lvalue<'tcx>, Option<D::Path>)],
is_cleanup: bool)
-> Vec<BasicBlock>
/// which is called if the matching step of the drop glue panics.
fn drop_halfladder(&mut self,
unwind_ladder: &[Unwind],
succ: BasicBlock,
fields: &[(Lvalue<'tcx>, Option<D::Path>)])
-> Vec<BasicBlock>
{
let mut unwind_succ = if is_cleanup {
None
} else {
self.unwind
};
let goto = TerminatorKind::Goto { target: succ };
let mut succ = self.new_block(is_cleanup, goto);
let mut succ = self.new_block(unwind_ladder[0], goto);
// Always clear the "master" drop flag at the bottom of the
// ladder. This is needed because the "master" drop flag
@ -248,9 +263,8 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
let succ_loc = Location { block: succ, statement_index: 0 };
self.elaborator.clear_drop_flag(succ_loc, self.path, DropFlagMode::Shallow);
fields.iter().rev().enumerate().map(|(i, &(ref lv, path))| {
succ = self.drop_subpath(is_cleanup, lv, path, succ, unwind_succ);
unwind_succ = unwind_ladder.as_ref().map(|p| p[i]);
fields.iter().rev().zip(unwind_ladder).map(|(&(ref lv, path), &unwind_succ)| {
succ = self.drop_subpath(lv, path, succ, unwind_succ);
succ
}).collect()
}
@ -271,7 +285,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
/// ELAB(drop location.2 [target=`self.unwind`])
fn drop_ladder<'a>(&mut self,
fields: Vec<(Lvalue<'tcx>, Option<D::Path>)>)
-> (BasicBlock, Option<BasicBlock>)
-> (BasicBlock, Unwind)
{
debug!("drop_ladder({:?}, {:?})", self, fields);
@ -282,21 +296,21 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
debug!("drop_ladder - fields needing drop: {:?}", fields);
let unwind_ladder = if self.is_cleanup {
None
let unwind_ladder = vec![Unwind::InCleanup; fields.len() + 1];
let unwind_ladder: Vec<_> = if let Unwind::To(target) = self.unwind {
let halfladder = self.drop_halfladder(&unwind_ladder, target, &fields);
Some(self.unwind).into_iter().chain(halfladder.into_iter().map(Unwind::To))
.collect()
} else {
let unwind = self.unwind.unwrap(); // FIXME(#6393)
Some(self.drop_halfladder(None, unwind, &fields, true))
unwind_ladder
};
let succ = self.succ; // FIXME(#6393)
let is_cleanup = self.is_cleanup;
let normal_ladder =
self.drop_halfladder(unwind_ladder.as_ref().map(|x| &**x),
succ, &fields, is_cleanup);
self.drop_halfladder(&unwind_ladder, succ, &fields);
(normal_ladder.last().cloned().unwrap_or(succ),
unwind_ladder.and_then(|l| l.last().cloned()).or(self.unwind))
unwind_ladder.last().cloned().unwrap_or(self.unwind))
}
fn open_drop_for_tuple<'a>(&mut self, tys: &[Ty<'tcx>])
@ -320,13 +334,13 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
let interior_path = self.elaborator.deref_subpath(self.path);
let succ = self.succ; // FIXME(#6393)
let is_cleanup = self.is_cleanup;
let succ = self.box_free_block(ty, succ, is_cleanup);
let unwind_succ = self.unwind.map(|u| {
self.box_free_block(ty, u, true)
let unwind = self.unwind;
let succ = self.box_free_block(ty, succ, unwind);
let unwind_succ = self.unwind.map(|unwind| {
self.box_free_block(ty, unwind, Unwind::InCleanup)
});
self.drop_subpath(is_cleanup, &interior, interior_path, succ, unwind_succ)
self.drop_subpath(&interior, interior_path, succ, unwind_succ)
}
fn open_drop_for_adt<'a>(&mut self, adt: &'tcx ty::AdtDef, substs: &'tcx Substs<'tcx>)
@ -339,7 +353,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
source_info: self.source_info,
kind: TerminatorKind::Unreachable
}),
is_cleanup: self.is_cleanup
is_cleanup: self.unwind.is_cleanup()
});
}
@ -358,7 +372,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
fn open_drop_for_adt_contents<'a>(&mut self, adt: &'tcx ty::AdtDef,
substs: &'tcx Substs<'tcx>)
-> (BasicBlock, Option<BasicBlock>) {
-> (BasicBlock, Unwind) {
match adt.variants.len() {
1 => {
let fields = self.move_paths_for_fields(
@ -370,13 +384,12 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
self.drop_ladder(fields)
}
_ => {
let is_cleanup = self.is_cleanup;
let succ = self.succ;
let unwind = self.unwind; // FIXME(#6393)
let mut values = Vec::with_capacity(adt.variants.len());
let mut normal_blocks = Vec::with_capacity(adt.variants.len());
let mut unwind_blocks = if is_cleanup {
let mut unwind_blocks = if unwind.is_cleanup() {
None
} else {
Some(Vec::with_capacity(adt.variants.len()))
@ -396,7 +409,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
&adt.variants[variant_index],
substs);
values.push(discr);
if let Some(ref mut unwind_blocks) = unwind_blocks {
if let Unwind::To(unwind) = unwind {
// We can't use the half-ladder from the original
// drop ladder, because this breaks the
// "funclet can't have 2 successor funclets"
@ -415,12 +428,11 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
// I want to minimize the divergence between MSVC
// and non-MSVC.
let unwind = unwind.unwrap();
let halfladder = self.drop_halfladder(
None, unwind, &fields, true);
unwind_blocks.push(
halfladder.last().cloned().unwrap_or(unwind)
);
let unwind_blocks = unwind_blocks.as_mut().unwrap();
let unwind_ladder = vec![Unwind::InCleanup; fields.len() + 1];
let halfladder =
self.drop_halfladder(&unwind_ladder, unwind, &fields);
unwind_blocks.push(halfladder.last().cloned().unwrap_or(unwind));
}
let (normal, _) = self.drop_ladder(fields);
normal_blocks.push(normal);
@ -428,14 +440,16 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
// variant not found - drop the entire enum
if let None = otherwise {
otherwise = Some(self.complete_drop(
is_cleanup,
Some(DropFlagMode::Shallow),
succ));
unwind_otherwise = unwind.map(|unwind| self.complete_drop(
true,
Some(DropFlagMode::Shallow),
unwind
));
succ,
unwind));
if let Unwind::To(unwind) = unwind {
unwind_otherwise = Some(self.complete_drop(
Some(DropFlagMode::Shallow),
unwind,
Unwind::InCleanup
));
}
}
}
}
@ -448,10 +462,10 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
values.pop();
}
(self.adt_switch_block(is_cleanup, adt, normal_blocks, &values, succ),
unwind_blocks.map(|unwind_blocks| {
(self.adt_switch_block(adt, normal_blocks, &values, succ, unwind),
unwind.map(|unwind| {
self.adt_switch_block(
is_cleanup, adt, unwind_blocks, &values, unwind.unwrap()
adt, unwind_blocks.unwrap(), &values, unwind, Unwind::InCleanup
)
}))
}
@ -459,11 +473,11 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
}
fn adt_switch_block(&mut self,
is_cleanup: bool,
adt: &'tcx ty::AdtDef,
blocks: Vec<BasicBlock>,
values: &[ConstInt],
succ: BasicBlock)
succ: BasicBlock,
unwind: Unwind)
-> BasicBlock {
// If there are multiple variants, then if something
// is present within the enum the discriminant, tracked
@ -491,12 +505,12 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
targets: blocks,
}
}),
is_cleanup: is_cleanup,
is_cleanup: unwind.is_cleanup(),
});
self.drop_flag_test_block(is_cleanup, switch_block, succ)
self.drop_flag_test_block(switch_block, succ, unwind)
}
fn destructor_call_block<'a>(&mut self, (succ, unwind): (BasicBlock, Option<BasicBlock>))
fn destructor_call_block<'a>(&mut self, (succ, unwind): (BasicBlock, Unwind))
-> BasicBlock
{
debug!("destructor_call_block({:?}, {:?})", self, succ);
@ -527,11 +541,11 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
self.source_info.span),
args: vec![Operand::Consume(Lvalue::Local(ref_lvalue))],
destination: Some((unit_temp, succ)),
cleanup: unwind,
cleanup: unwind.into_option(),
},
source_info: self.source_info
}),
is_cleanup: self.is_cleanup,
is_cleanup: unwind.is_cleanup(),
})
}
@ -541,16 +555,15 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
/// can_go = index < len
/// if can_go then drop-block else succ
/// drop-block:
/// ptr = &mut LV[len]
/// ptr = &mut LV[index]
/// index = index + 1
/// drop(ptr)
fn drop_loop(&mut self,
unwind: Option<BasicBlock>,
succ: BasicBlock,
index: &Lvalue<'tcx>,
length: &Lvalue<'tcx>,
ety: Ty<'tcx>,
is_cleanup: bool)
unwind: Unwind)
-> BasicBlock
{
let use_ = |lv: &Lvalue<'tcx>| Operand::Consume(lv.clone());
@ -576,10 +589,11 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
index.clone(), Rvalue::BinaryOp(BinOp::Add, use_(index), one)
)},
],
is_cleanup,
is_cleanup: unwind.is_cleanup(),
terminator: Some(Terminator {
source_info: self.source_info,
kind: TerminatorKind::Resume,
// this gets overwritten by drop elaboration.
kind: TerminatorKind::Unreachable,
})
});
@ -589,7 +603,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
can_go.clone(), Rvalue::BinaryOp(BinOp::Lt, use_(index), use_(length))
)},
],
is_cleanup,
is_cleanup: unwind.is_cleanup(),
terminator: Some(Terminator {
source_info: self.source_info,
kind: TerminatorKind::if_(tcx, use_(can_go), drop_block, succ)
@ -599,7 +613,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
self.elaborator.patch().patch_terminator(drop_block, TerminatorKind::Drop {
location: ptr.clone().deref(),
target: loop_block,
unwind: unwind
unwind: unwind.into_option()
});
loop_block
@ -614,12 +628,11 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
let length = &Lvalue::Local(self.new_temp(tcx.types.usize));
let unwind = self.unwind.map(|unwind| {
self.drop_loop(None, unwind, index, length, ety, true)
self.drop_loop(unwind, index, length, ety, Unwind::InCleanup)
});
let is_cleanup = self.is_cleanup;
let succ = self.succ; // FIXME(#6393)
let loop_block = self.drop_loop(unwind, succ, index, length, ety, is_cleanup);
let loop_block = self.drop_loop(succ, index, length, ety, unwind);
let zero = self.constant_usize(0);
let drop_block = self.elaborator.patch().new_block(BasicBlockData {
@ -631,7 +644,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
index.clone(), Rvalue::Use(zero),
)},
],
is_cleanup,
is_cleanup: unwind.is_cleanup(),
terminator: Some(Terminator {
source_info: self.source_info,
kind: TerminatorKind::Goto { target: loop_block }
@ -640,7 +653,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
// FIXME(#34708): handle partially-dropped array/slice elements.
self.drop_flag_test_and_reset_block(
is_cleanup, Some(DropFlagMode::Deep), drop_block, succ)
Some(DropFlagMode::Deep), drop_block, succ, unwind)
}
/// The slow-path - create an "open", elaborated drop for a type
@ -653,8 +666,6 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
/// ADT, both in the success case or if one of the destructors fail.
fn open_drop<'a>(&mut self) -> BasicBlock {
let ty = self.lvalue_ty(self.lvalue);
let is_cleanup = self.is_cleanup; // FIXME(#6393)
let succ = self.succ;
match ty.sty {
ty::TyClosure(def_id, substs) => {
let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect();
@ -670,7 +681,9 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
self.open_drop_for_adt(def, substs)
}
ty::TyDynamic(..) => {
self.complete_drop(is_cleanup, Some(DropFlagMode::Deep), succ)
let unwind = self.unwind; // FIXME(#6393)
let succ = self.succ;
self.complete_drop(Some(DropFlagMode::Deep), succ, unwind)
}
ty::TyArray(ety, _) | ty::TySlice(ety) => {
self.open_drop_for_array(ety)
@ -687,21 +700,21 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
/// if let Some(mode) = mode: FLAG(self.path)[mode] = false
/// drop(self.lv)
fn complete_drop<'a>(&mut self,
is_cleanup: bool,
drop_mode: Option<DropFlagMode>,
succ: BasicBlock) -> BasicBlock
succ: BasicBlock,
unwind: Unwind) -> BasicBlock
{
debug!("complete_drop({:?},{:?})", self, drop_mode);
let drop_block = self.drop_block(is_cleanup, succ);
self.drop_flag_test_and_reset_block(is_cleanup, drop_mode, drop_block, succ)
let drop_block = self.drop_block(succ, unwind);
self.drop_flag_test_and_reset_block(drop_mode, drop_block, succ, unwind)
}
fn drop_flag_test_and_reset_block(&mut self,
is_cleanup: bool,
drop_mode: Option<DropFlagMode>,
drop_block: BasicBlock,
succ: BasicBlock) -> BasicBlock
succ: BasicBlock,
unwind: Unwind) -> BasicBlock
{
debug!("drop_flag_test_and_reset_block({:?},{:?})", self, drop_mode);
@ -710,14 +723,14 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
self.elaborator.clear_drop_flag(block_start, self.path, mode);
}
self.drop_flag_test_block(is_cleanup, drop_block, succ)
self.drop_flag_test_block(drop_block, succ, unwind)
}
fn elaborated_drop_block<'a>(&mut self) -> BasicBlock {
debug!("elaborated_drop_block({:?})", self);
let is_cleanup = self.is_cleanup; // FIXME(#6393)
let unwind = self.unwind; // FIXME(#6393)
let succ = self.succ;
let blk = self.drop_block(is_cleanup, succ);
let blk = self.drop_block(succ, unwind);
self.elaborate_drop(blk);
blk
}
@ -726,17 +739,17 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
&mut self,
ty: Ty<'tcx>,
target: BasicBlock,
is_cleanup: bool
unwind: Unwind,
) -> BasicBlock {
let block = self.unelaborated_free_block(ty, target, is_cleanup);
self.drop_flag_test_block(is_cleanup, block, target)
let block = self.unelaborated_free_block(ty, target, unwind);
self.drop_flag_test_block(block, target, unwind)
}
fn unelaborated_free_block<'a>(
&mut self,
ty: Ty<'tcx>,
target: BasicBlock,
is_cleanup: bool
unwind: Unwind
) -> BasicBlock {
let tcx = self.tcx();
let unit_temp = Lvalue::Local(self.new_temp(tcx.mk_nil()));
@ -749,31 +762,31 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
destination: Some((unit_temp, target)),
cleanup: None
}; // FIXME(#6393)
let free_block = self.new_block(is_cleanup, call);
let free_block = self.new_block(unwind, call);
let block_start = Location { block: free_block, statement_index: 0 };
self.elaborator.clear_drop_flag(block_start, self.path, DropFlagMode::Shallow);
free_block
}
fn drop_block<'a>(&mut self, is_cleanup: bool, succ: BasicBlock) -> BasicBlock {
fn drop_block<'a>(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock {
let block = TerminatorKind::Drop {
location: self.lvalue.clone(),
target: succ,
unwind: if is_cleanup { None } else { self.unwind }
target: target,
unwind: unwind.into_option()
};
self.new_block(is_cleanup, block)
self.new_block(unwind, block)
}
fn drop_flag_test_block(&mut self,
is_cleanup: bool,
on_set: BasicBlock,
on_unset: BasicBlock)
on_unset: BasicBlock,
unwind: Unwind)
-> BasicBlock
{
let style = self.elaborator.drop_style(self.path, DropFlagMode::Shallow);
debug!("drop_flag_test_block({:?},{:?},{:?}) - {:?}",
self, is_cleanup, on_set, style);
debug!("drop_flag_test_block({:?},{:?},{:?},{:?}) - {:?}",
self, on_set, on_unset, unwind, style);
match style {
DropStyle::Dead => on_unset,
@ -781,13 +794,13 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
DropStyle::Conditional | DropStyle::Open => {
let flag = self.elaborator.get_drop_flag(self.path).unwrap();
let term = TerminatorKind::if_(self.tcx(), flag, on_set, on_unset);
self.new_block(is_cleanup, term)
self.new_block(unwind, term)
}
}
}
fn new_block<'a>(&mut self,
is_cleanup: bool,
unwind: Unwind,
k: TerminatorKind<'tcx>)
-> BasicBlock
{
@ -796,7 +809,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
terminator: Some(Terminator {
source_info: self.source_info, kind: k
}),
is_cleanup: is_cleanup
is_cleanup: unwind.is_cleanup()
})
}
@ -809,7 +822,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
self.elaborator.patch().terminator_loc(mir, bb)
}
fn constant_usize(&self, val: usize) -> Operand<'tcx> {
fn constant_usize(&self, val: u16) -> Operand<'tcx> {
Operand::Constant(box Constant {
span: self.source_info.span,
ty: self.tcx().types.usize,