about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2017-01-21 22:44:44 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2017-01-30 23:14:15 +0300
commit4a4f8ff0a3eeb0855f03ad88c2f11f12761041f0 (patch)
treea3754f8245c5d5ecad4afac3db82eb8445ef523e /src
parentffba0cea621c2609582b4e201b76b3b19860ec4f (diff)
downloadrust-4a4f8ff0a3eeb0855f03ad88c2f11f12761041f0.tar.gz
rust-4a4f8ff0a3eeb0855f03ad88c2f11f12761041f0.zip
Implement Drop for Box
Diffstat (limited to 'src')
-rw-r--r--src/liballoc/boxed.rs8
-rw-r--r--src/librustc/ty/contents.rs27
-rw-r--r--src/librustc/ty/sty.rs3
-rw-r--r--src/librustc_borrowck/borrowck/mir/elaborate_drops.rs2
-rw-r--r--src/librustc_borrowck/borrowck/mir/gather_moves.rs2
-rw-r--r--src/librustc_borrowck/borrowck/mir/mod.rs2
-rw-r--r--src/librustc_trans/collector.rs2
-rw-r--r--src/librustc_trans/glue.rs5
8 files changed, 18 insertions, 33 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index d98bc189292..b6f490e09cd 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -293,6 +293,14 @@ impl<T: ?Sized> Box<T> {
     }
 }
 
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl<#[may_dangle] T: ?Sized> Drop for Box<T> {
+    fn drop(&mut self) {
+        // FIXME: Do nothing, drop is currently performed by compiler.
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Default> Default for Box<T> {
     /// Creates a `Box<T>`, with the `Default` value for T.
diff --git a/src/librustc/ty/contents.rs b/src/librustc/ty/contents.rs
index 53e8a1d0e37..00c6dca21b1 100644
--- a/src/librustc/ty/contents.rs
+++ b/src/librustc/ty/contents.rs
@@ -56,12 +56,8 @@ def_type_content_sets! {
         // InteriorAll                         = 0b00000000__00000000__1111,
 
         // Things that are owned by the value (second and third nibbles):
-        OwnsOwned                           = 0b0000_0000__0000_0001__0000,
         OwnsDtor                            = 0b0000_0000__0000_0010__0000,
-        OwnsAll                             = 0b0000_0000__1111_1111__0000,
-
-        // Things that mean drop glue is necessary
-        NeedsDrop                           = 0b0000_0000__0000_0111__0000,
+        // OwnsAll                             = 0b0000_0000__1111_1111__0000,
 
         // All bits
         All                                 = 0b1111_1111__1111_1111__1111
@@ -77,10 +73,6 @@ impl TypeContents {
         (self.bits & tc.bits) != 0
     }
 
-    pub fn owns_owned(&self) -> bool {
-        self.intersects(TC::OwnsOwned)
-    }
-
     pub fn interior_param(&self) -> bool {
         self.intersects(TC::InteriorParam)
     }
@@ -90,12 +82,7 @@ impl TypeContents {
     }
 
     pub fn needs_drop(&self, _: TyCtxt) -> bool {
-        self.intersects(TC::NeedsDrop)
-    }
-
-    /// Includes only those bits that still apply when indirected through a `Box` pointer
-    pub fn owned_pointer(&self) -> TypeContents {
-        TC::OwnsOwned | (*self & TC::OwnsAll)
+        self.intersects(TC::OwnsDtor)
     }
 
     pub fn union<I, T, F>(v: I, mut f: F) -> TypeContents where
@@ -104,10 +91,6 @@ impl TypeContents {
     {
         v.into_iter().fold(TC::None, |tc, ty| tc | f(ty))
     }
-
-    pub fn has_dtor(&self) -> bool {
-        self.intersects(TC::OwnsDtor)
-    }
 }
 
 impl ops::BitOr for TypeContents {
@@ -223,10 +206,6 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
                                         |ty| tc_ty(tcx, *ty, cache))
                 }
 
-                ty::TyAdt(def, _) if def.is_box() => {
-                    tc_ty(tcx, ty.boxed_ty(), cache).owned_pointer()
-                }
-
                 ty::TyAdt(def, substs) => {
                     let mut res =
                         TypeContents::union(&def.variants, |v| {
@@ -237,7 +216,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
 
                     if def.is_union() {
                         // unions don't have destructors regardless of the child types
-                        res = res - TC::NeedsDrop;
+                        res = res - TC::OwnsDtor;
                     }
 
                     if def.has_dtor() {
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index d7686b60ae3..113534e4529 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1142,8 +1142,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
 
     pub fn boxed_ty(&self) -> Ty<'tcx> {
         match self.sty {
-            TyAdt(def, substs) if def.is_box() =>
-                substs.types().next().expect("Box<T> doesn't have type parameters"),
+            TyAdt(def, substs) if def.is_box() => substs.type_at(0),
             _ => bug!("`boxed_ty` is called on non-box type {:?}", self),
         }
     }
diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
index d555502c3ff..9e89a3689c7 100644
--- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
+++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
@@ -895,7 +895,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
 
         match ty.sty {
             ty::TyAdt(def, _) => {
-                if def.has_dtor() {
+                if def.has_dtor() && !def.is_box() {
                     self.tcx.sess.span_warn(
                         c.source_info.span,
                         &format!("dataflow bug??? moving out of type with dtor {:?}",
diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs
index 2a9acaf58b8..7cf6ab2999c 100644
--- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs
+++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs
@@ -289,7 +289,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
             // error: can't move out of borrowed content
             ty::TyRef(..) | ty::TyRawPtr(..) => return Err(MovePathError::IllegalMove),
             // error: can't move out of struct with destructor
-            ty::TyAdt(adt, _) if adt.has_dtor() =>
+            ty::TyAdt(adt, _) if adt.has_dtor() && !adt.is_box() =>
                 return Err(MovePathError::IllegalMove),
             // move out of union - always move the entire union
             ty::TyAdt(adt, _) if adt.is_union() =>
diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs
index 372eb1d5d64..a0c36139ddc 100644
--- a/src/librustc_borrowck/borrowck/mir/mod.rs
+++ b/src/librustc_borrowck/borrowck/mir/mod.rs
@@ -248,7 +248,7 @@ fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
                    lv, ty);
             true
         }
-        ty::TyAdt(def, _) if def.has_dtor() || def.is_union() => {
+        ty::TyAdt(def, _) if (def.has_dtor() && !def.is_box()) || def.is_union() => {
             debug!("lvalue_contents_drop_state_cannot_differ lv: {:?} ty: {:?} Drop => true",
                    lv, ty);
             true
diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs
index 9766b816d9b..392c270c130 100644
--- a/src/librustc_trans/collector.rs
+++ b/src/librustc_trans/collector.rs
@@ -740,7 +740,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
         _ => None
     };
 
-    if let Some(destructor_did) = destructor_did {
+    if let (Some(destructor_did), false) = (destructor_did, ty.is_box()) {
         use rustc::ty::ToPolyTraitRef;
 
         let drop_trait_def_id = scx.tcx()
diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs
index 65f3c7add4d..350c8f950dd 100644
--- a/src/librustc_trans/glue.rs
+++ b/src/librustc_trans/glue.rs
@@ -211,9 +211,8 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi
 
     let bcx = match t.sty {
         ty::TyAdt(def, _) if def.is_box() => {
-            // Support for Box is built-in and its drop glue is
-            // special. It may move to library and have Drop impl. As
-            // a safe-guard, assert Box not used with TyContents.
+            // Support for Box is built-in as yet and its drop glue is special
+            // despite having a dummy Drop impl in the library.
             assert!(!skip_dtor);
             let content_ty = t.boxed_ty();
             let ptr = if !bcx.ccx.shared().type_is_sized(content_ty) {