Implement Drop for Box
This commit is contained in:
@@ -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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: Default> Default for Box<T> {
|
impl<T: Default> Default for Box<T> {
|
||||||
/// Creates a `Box<T>`, with the `Default` value for T.
|
/// Creates a `Box<T>`, with the `Default` value for T.
|
||||||
|
|||||||
@@ -56,12 +56,8 @@ def_type_content_sets! {
|
|||||||
// InteriorAll = 0b00000000__00000000__1111,
|
// InteriorAll = 0b00000000__00000000__1111,
|
||||||
|
|
||||||
// Things that are owned by the value (second and third nibbles):
|
// Things that are owned by the value (second and third nibbles):
|
||||||
OwnsOwned = 0b0000_0000__0000_0001__0000,
|
|
||||||
OwnsDtor = 0b0000_0000__0000_0010__0000,
|
OwnsDtor = 0b0000_0000__0000_0010__0000,
|
||||||
OwnsAll = 0b0000_0000__1111_1111__0000,
|
// OwnsAll = 0b0000_0000__1111_1111__0000,
|
||||||
|
|
||||||
// Things that mean drop glue is necessary
|
|
||||||
NeedsDrop = 0b0000_0000__0000_0111__0000,
|
|
||||||
|
|
||||||
// All bits
|
// All bits
|
||||||
All = 0b1111_1111__1111_1111__1111
|
All = 0b1111_1111__1111_1111__1111
|
||||||
@@ -77,10 +73,6 @@ impl TypeContents {
|
|||||||
(self.bits & tc.bits) != 0
|
(self.bits & tc.bits) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn owns_owned(&self) -> bool {
|
|
||||||
self.intersects(TC::OwnsOwned)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn interior_param(&self) -> bool {
|
pub fn interior_param(&self) -> bool {
|
||||||
self.intersects(TC::InteriorParam)
|
self.intersects(TC::InteriorParam)
|
||||||
}
|
}
|
||||||
@@ -90,12 +82,7 @@ impl TypeContents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn needs_drop(&self, _: TyCtxt) -> bool {
|
pub fn needs_drop(&self, _: TyCtxt) -> bool {
|
||||||
self.intersects(TC::NeedsDrop)
|
self.intersects(TC::OwnsDtor)
|
||||||
}
|
|
||||||
|
|
||||||
/// Includes only those bits that still apply when indirected through a `Box` pointer
|
|
||||||
pub fn owned_pointer(&self) -> TypeContents {
|
|
||||||
TC::OwnsOwned | (*self & TC::OwnsAll)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn union<I, T, F>(v: I, mut f: F) -> TypeContents where
|
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))
|
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 {
|
impl ops::BitOr for TypeContents {
|
||||||
@@ -223,10 +206,6 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
|||||||
|ty| tc_ty(tcx, *ty, cache))
|
|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) => {
|
ty::TyAdt(def, substs) => {
|
||||||
let mut res =
|
let mut res =
|
||||||
TypeContents::union(&def.variants, |v| {
|
TypeContents::union(&def.variants, |v| {
|
||||||
@@ -237,7 +216,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
|||||||
|
|
||||||
if def.is_union() {
|
if def.is_union() {
|
||||||
// unions don't have destructors regardless of the child types
|
// unions don't have destructors regardless of the child types
|
||||||
res = res - TC::NeedsDrop;
|
res = res - TC::OwnsDtor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if def.has_dtor() {
|
if def.has_dtor() {
|
||||||
|
|||||||
@@ -1142,8 +1142,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||||||
|
|
||||||
pub fn boxed_ty(&self) -> Ty<'tcx> {
|
pub fn boxed_ty(&self) -> Ty<'tcx> {
|
||||||
match self.sty {
|
match self.sty {
|
||||||
TyAdt(def, substs) if def.is_box() =>
|
TyAdt(def, substs) if def.is_box() => substs.type_at(0),
|
||||||
substs.types().next().expect("Box<T> doesn't have type parameters"),
|
|
||||||
_ => bug!("`boxed_ty` is called on non-box type {:?}", self),
|
_ => bug!("`boxed_ty` is called on non-box type {:?}", self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -895,7 +895,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||||||
|
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyAdt(def, _) => {
|
ty::TyAdt(def, _) => {
|
||||||
if def.has_dtor() {
|
if def.has_dtor() && !def.is_box() {
|
||||||
self.tcx.sess.span_warn(
|
self.tcx.sess.span_warn(
|
||||||
c.source_info.span,
|
c.source_info.span,
|
||||||
&format!("dataflow bug??? moving out of type with dtor {:?}",
|
&format!("dataflow bug??? moving out of type with dtor {:?}",
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
|||||||
// error: can't move out of borrowed content
|
// error: can't move out of borrowed content
|
||||||
ty::TyRef(..) | ty::TyRawPtr(..) => return Err(MovePathError::IllegalMove),
|
ty::TyRef(..) | ty::TyRawPtr(..) => return Err(MovePathError::IllegalMove),
|
||||||
// error: can't move out of struct with destructor
|
// 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),
|
return Err(MovePathError::IllegalMove),
|
||||||
// move out of union - always move the entire union
|
// move out of union - always move the entire union
|
||||||
ty::TyAdt(adt, _) if adt.is_union() =>
|
ty::TyAdt(adt, _) if adt.is_union() =>
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
|
|||||||
lv, ty);
|
lv, ty);
|
||||||
true
|
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",
|
debug!("lvalue_contents_drop_state_cannot_differ lv: {:?} ty: {:?} Drop => true",
|
||||||
lv, ty);
|
lv, ty);
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -740,7 +740,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
|
|||||||
_ => None
|
_ => None
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(destructor_did) = destructor_did {
|
if let (Some(destructor_did), false) = (destructor_did, ty.is_box()) {
|
||||||
use rustc::ty::ToPolyTraitRef;
|
use rustc::ty::ToPolyTraitRef;
|
||||||
|
|
||||||
let drop_trait_def_id = scx.tcx()
|
let drop_trait_def_id = scx.tcx()
|
||||||
|
|||||||
@@ -211,9 +211,8 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi
|
|||||||
|
|
||||||
let bcx = match t.sty {
|
let bcx = match t.sty {
|
||||||
ty::TyAdt(def, _) if def.is_box() => {
|
ty::TyAdt(def, _) if def.is_box() => {
|
||||||
// Support for Box is built-in and its drop glue is
|
// Support for Box is built-in as yet and its drop glue is special
|
||||||
// special. It may move to library and have Drop impl. As
|
// despite having a dummy Drop impl in the library.
|
||||||
// a safe-guard, assert Box not used with TyContents.
|
|
||||||
assert!(!skip_dtor);
|
assert!(!skip_dtor);
|
||||||
let content_ty = t.boxed_ty();
|
let content_ty = t.boxed_ty();
|
||||||
let ptr = if !bcx.ccx.shared().type_is_sized(content_ty) {
|
let ptr = if !bcx.ccx.shared().type_is_sized(content_ty) {
|
||||||
|
|||||||
Reference in New Issue
Block a user