fix the block processing for the drop_in_place intrinsic
This commit is contained in:
parent
893f16389e
commit
07c752cc82
3 changed files with 31 additions and 3 deletions
|
|
@ -18,6 +18,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
dest: Lvalue<'tcx>,
|
||||
dest_ty: Ty<'tcx>,
|
||||
dest_layout: &'tcx Layout,
|
||||
target: mir::BasicBlock,
|
||||
) -> EvalResult<'tcx, ()> {
|
||||
let arg_vals: EvalResult<Vec<Value>> = args.iter()
|
||||
.map(|arg| self.eval_operand(arg))
|
||||
|
|
@ -137,7 +138,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
};
|
||||
let mut drops = Vec::new();
|
||||
self.drop(lvalue, ty, &mut drops)?;
|
||||
self.eval_drop_impls(drops)?;
|
||||
// need to change the block before pushing the drop impl stack frames
|
||||
// we could do this for all intrinsics before evaluating the intrinsics, but if
|
||||
// the evaluation fails, we should not have moved forward
|
||||
self.goto_block(target);
|
||||
return self.eval_drop_impls(drops);
|
||||
}
|
||||
|
||||
"fabsf32" => {
|
||||
|
|
@ -341,6 +346,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
name => return Err(EvalError::Unimplemented(format!("unimplemented intrinsic: {}", name))),
|
||||
}
|
||||
|
||||
self.goto_block(target);
|
||||
|
||||
// Since we pushed no stack frame, the main loop will act
|
||||
// as if the call just completed and it's returning to the
|
||||
// current frame.
|
||||
|
|
|
|||
|
|
@ -187,8 +187,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
let ty = fn_ty.sig.0.output;
|
||||
let layout = self.type_layout(ty);
|
||||
let (ret, target) = destination.unwrap();
|
||||
self.call_intrinsic(def_id, substs, arg_operands, ret, ty, layout)?;
|
||||
self.goto_block(target);
|
||||
self.call_intrinsic(def_id, substs, arg_operands, ret, ty, layout, target)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
22
tests/run-pass/call_drop_through_trait_object_rc.rs
Normal file
22
tests/run-pass/call_drop_through_trait_object_rc.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
trait Foo {}
|
||||
|
||||
struct Bar;
|
||||
|
||||
static mut DROP_CALLED: bool = false;
|
||||
|
||||
impl Drop for Bar {
|
||||
fn drop(&mut self) {
|
||||
unsafe { DROP_CALLED = true; }
|
||||
}
|
||||
}
|
||||
|
||||
impl Foo for Bar {}
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
fn main() {
|
||||
let b: Rc<Foo> = Rc::new(Bar);
|
||||
assert!(unsafe { !DROP_CALLED });
|
||||
drop(b);
|
||||
assert!(unsafe { DROP_CALLED });
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue