Skip to content

Commit

Permalink
drop zst fields of null pointer optimized structs and enums
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Feb 24, 2017
1 parent 1a697f9 commit de42764
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 24 deletions.
28 changes: 4 additions & 24 deletions src/terminator/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
23 changes: 23 additions & 0 deletions tests/run-pass/zst_variant_drop.rs
Original file line number Diff line number Diff line change
@@ -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 });
}

0 comments on commit de42764

Please sign in to comment.