drop zst fields of null pointer optimized structs and enums

fixes #25
This commit is contained in:
Oliver Schneider 2017-02-15 10:56:02 +01:00
parent 1a697f9bba
commit de42764b52
No known key found for this signature in database
GPG key ID: A69F8D225B3AD7D9
2 changed files with 27 additions and 24 deletions

View file

@ -132,31 +132,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
None => return Err(EvalError::InvalidDiscriminant),
}
},
Layout::StructWrappedNullablePointer { nndiscr, .. } => {
Layout::StructWrappedNullablePointer { .. } |
Layout::RawNullablePointer { .. } => {
let discr = self.read_discriminant_value(adt_ptr, ty)?;
if discr == nndiscr as u128 {
assert_eq!(discr as usize as u128, discr);
&adt_def.variants[discr as usize].fields
} else {
// FIXME: the zst variant might contain zst types that impl Drop
return Ok(()); // nothing to do, this is zero sized (e.g. `None`)
}
},
Layout::RawNullablePointer { nndiscr, .. } => {
let discr = self.read_discriminant_value(adt_ptr, ty)?;
if discr == nndiscr as u128 {
assert_eq!(discr as usize as u128, discr);
assert_eq!(adt_def.variants[discr as usize].fields.len(), 1);
let field_ty = &adt_def.variants[discr as usize].fields[0];
let field_ty = monomorphize_field_ty(self.tcx, field_ty, substs);
// FIXME: once read_discriminant_value works with lvalue, don't force
// alloc in the RawNullablePointer case
self.drop(lval, field_ty, drop)?;
return Ok(());
} else {
// FIXME: the zst variant might contain zst types that impl Drop
return Ok(()); // nothing to do, this is zero sized (e.g. `None`)
}
assert_eq!(discr as usize as u128, discr);
&adt_def.variants[discr as usize].fields
},
Layout::CEnum { .. } => return Ok(()),
_ => bug!("{:?} is not an adt layout", layout),

View file

@ -0,0 +1,23 @@
struct Foo;
impl Drop for Foo {
fn drop(&mut self) {
unsafe {
FOO = true;
}
}
}
static mut FOO: bool = false;
enum Bar {
A(Box<i32>),
B(Foo),
}
fn main() {
assert!(unsafe { !FOO });
drop(Bar::A(Box::new(42)));
assert!(unsafe { !FOO });
drop(Bar::B(Foo));
assert!(unsafe { FOO });
}