fix a bug in drop code of structs with unsized fields
This commit is contained in:
parent
eeae478e74
commit
4730cdf825
2 changed files with 34 additions and 5 deletions
|
|
@ -94,10 +94,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
ty::TyAdt(adt_def, substs) => {
|
||||
// FIXME: some structs are represented as ByValPair
|
||||
let mut lval = self.force_allocation(lval)?;
|
||||
let adt_ptr = match lval {
|
||||
Lvalue::Ptr { ptr, .. } => ptr,
|
||||
_ => bug!("force allocation can only yield Lvalue::Ptr"),
|
||||
};
|
||||
let (adt_ptr, extra) = lval.to_ptr_and_extra();
|
||||
|
||||
// run drop impl before the fields' drop impls
|
||||
if let Some(drop_def_id) = adt_def.destructor() {
|
||||
|
|
@ -109,7 +106,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
traits::VtableImpl(data) => data,
|
||||
_ => bug!("dtor for {:?} is not an impl???", ty)
|
||||
};
|
||||
drop.push((drop_def_id, Value::ByVal(PrimVal::Ptr(adt_ptr)), vtable.substs));
|
||||
let val = match extra {
|
||||
LvalueExtra::None => Value::ByVal(PrimVal::Ptr(adt_ptr)),
|
||||
LvalueExtra::DowncastVariant(_) => bug!("downcast variant in drop"),
|
||||
LvalueExtra::Length(n) => Value::ByValPair(PrimVal::Ptr(adt_ptr), PrimVal::from_u128(n as u128)),
|
||||
LvalueExtra::Vtable(vtable) => Value::ByValPair(PrimVal::Ptr(adt_ptr), PrimVal::Ptr(vtable)),
|
||||
};
|
||||
drop.push((drop_def_id, val, vtable.substs));
|
||||
}
|
||||
|
||||
let layout = self.type_layout(ty)?;
|
||||
|
|
|
|||
26
tests/run-pass/issue-26709.rs
Normal file
26
tests/run-pass/issue-26709.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
struct Wrapper<'a, T: ?Sized>(&'a mut i32, T);
|
||||
|
||||
impl<'a, T: ?Sized> Drop for Wrapper<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
*self.0 = 432;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut x = 0;
|
||||
{
|
||||
let wrapper = Box::new(Wrapper(&mut x, 123));
|
||||
let _: Box<Wrapper<Send>> = wrapper;
|
||||
}
|
||||
assert_eq!(432, x)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue