Skip to content

Commit de42764

Browse files
committed
drop zst fields of null pointer optimized structs and enums
fixes rust-lang#25
1 parent 1a697f9 commit de42764

File tree

2 files changed

+27
-24
lines changed

2 files changed

+27
-24
lines changed

src/terminator/drop.rs

+4-24
Original file line numberDiff line numberDiff line change
@@ -132,31 +132,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
132132
None => return Err(EvalError::InvalidDiscriminant),
133133
}
134134
},
135-
Layout::StructWrappedNullablePointer { nndiscr, .. } => {
135+
Layout::StructWrappedNullablePointer { .. } |
136+
Layout::RawNullablePointer { .. } => {
136137
let discr = self.read_discriminant_value(adt_ptr, ty)?;
137-
if discr == nndiscr as u128 {
138-
assert_eq!(discr as usize as u128, discr);
139-
&adt_def.variants[discr as usize].fields
140-
} else {
141-
// FIXME: the zst variant might contain zst types that impl Drop
142-
return Ok(()); // nothing to do, this is zero sized (e.g. `None`)
143-
}
144-
},
145-
Layout::RawNullablePointer { nndiscr, .. } => {
146-
let discr = self.read_discriminant_value(adt_ptr, ty)?;
147-
if discr == nndiscr as u128 {
148-
assert_eq!(discr as usize as u128, discr);
149-
assert_eq!(adt_def.variants[discr as usize].fields.len(), 1);
150-
let field_ty = &adt_def.variants[discr as usize].fields[0];
151-
let field_ty = monomorphize_field_ty(self.tcx, field_ty, substs);
152-
// FIXME: once read_discriminant_value works with lvalue, don't force
153-
// alloc in the RawNullablePointer case
154-
self.drop(lval, field_ty, drop)?;
155-
return Ok(());
156-
} else {
157-
// FIXME: the zst variant might contain zst types that impl Drop
158-
return Ok(()); // nothing to do, this is zero sized (e.g. `None`)
159-
}
138+
assert_eq!(discr as usize as u128, discr);
139+
&adt_def.variants[discr as usize].fields
160140
},
161141
Layout::CEnum { .. } => return Ok(()),
162142
_ => bug!("{:?} is not an adt layout", layout),

tests/run-pass/zst_variant_drop.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
struct Foo;
2+
impl Drop for Foo {
3+
fn drop(&mut self) {
4+
unsafe {
5+
FOO = true;
6+
}
7+
}
8+
}
9+
10+
static mut FOO: bool = false;
11+
12+
enum Bar {
13+
A(Box<i32>),
14+
B(Foo),
15+
}
16+
17+
fn main() {
18+
assert!(unsafe { !FOO });
19+
drop(Bar::A(Box::new(42)));
20+
assert!(unsafe { !FOO });
21+
drop(Bar::B(Foo));
22+
assert!(unsafe { FOO });
23+
}

0 commit comments

Comments
 (0)