]> git.lizzy.rs Git - rust.git/commitdiff
drop zst fields of null pointer optimized structs and enums
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Wed, 15 Feb 2017 09:56:02 +0000 (10:56 +0100)
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Fri, 24 Feb 2017 10:04:13 +0000 (11:04 +0100)
fixes #25

src/terminator/drop.rs
tests/run-pass/zst_variant_drop.rs [new file with mode: 0644]

index f334e9e7685de51ea7e625948c1d70d51b1b6fd0..289bae89c3c64e79409b1eebc90b409b4a2d81c4 100644 (file)
@@ -132,31 +132,11 @@ pub fn drop(
                             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 (file)
index 0000000..a76f64c
--- /dev/null
@@ -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 });
+}