From de42764b5231bf2a8d9ebaaa5572cc1e46dce7f8 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 15 Feb 2017 10:56:02 +0100 Subject: [PATCH] drop zst fields of null pointer optimized structs and enums fixes #25 --- src/terminator/drop.rs | 28 ++++------------------------ tests/run-pass/zst_variant_drop.rs | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 24 deletions(-) create mode 100644 tests/run-pass/zst_variant_drop.rs diff --git a/src/terminator/drop.rs b/src/terminator/drop.rs index f334e9e7685d..289bae89c3c6 100644 --- a/src/terminator/drop.rs +++ b/src/terminator/drop.rs @@ -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), diff --git a/tests/run-pass/zst_variant_drop.rs b/tests/run-pass/zst_variant_drop.rs new file mode 100644 index 000000000000..a76f64ce29df --- /dev/null +++ b/tests/run-pass/zst_variant_drop.rs @@ -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), + B(Foo), +} + +fn main() { + assert!(unsafe { !FOO }); + drop(Bar::A(Box::new(42))); + assert!(unsafe { !FOO }); + drop(Bar::B(Foo)); + assert!(unsafe { FOO }); +}