Skip to content

Commit

Permalink
std: Second pass stabilization for boxed
Browse files Browse the repository at this point in the history
This commit performs a second pass over the `std::boxed` module, taking the
following actions:

* `boxed` is now stable
* `Box` is now stable
* `BoxAny` is removed in favor of a direct `impl Box<Any>`
* `Box::downcast` remains unstable while the name of the `downcast` family of
  methods is determined.

This is a breaking change due to the removal of the `BoxAny` trait (note that
the `downcast` method still exists), and existing consumers of `BoxAny` simply
need to remove the import in their modules.

[breaking-change]
  • Loading branch information
alexcrichton committed Jan 2, 2015
1 parent cd61416 commit f2ccdfd
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
27 changes: 24 additions & 3 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

//! A unique pointer type.

#![stable]

use core::any::{Any, AnyRefExt};
use core::clone::Clone;
use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
Expand Down Expand Up @@ -44,7 +46,7 @@ pub static HEAP: () = ();

/// A type that represents a uniquely-owned value.
#[lang = "owned_box"]
#[unstable = "custom allocators will add an additional type parameter (with default)"]
#[stable]
pub struct Box<T>(Unique<T>);

#[stable]
Expand Down Expand Up @@ -111,18 +113,37 @@ impl<S: hash::Writer, Sized? T: Hash<S>> Hash<S> for Box<T> {
}
}

#[cfg(not(stage0))]
impl Box<Any> {
pub fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
if self.is::<T>() {
unsafe {
// Get the raw representation of the trait object
let to: TraitObject =
mem::transmute::<Box<Any>, TraitObject>(self);

// Extract the data pointer
Ok(mem::transmute(to.data))
}
} else {
Err(self)
}
}
}

/// Extension methods for an owning `Any` trait object.
#[unstable = "post-DST and coherence changes, this will not be a trait but \
rather a direct `impl` on `Box<Any>`"]
#[cfg(stage0)]
pub trait BoxAny {
/// Returns the boxed value if it is of type `T`, or
/// `Err(Self)` if it isn't.
#[unstable = "naming conventions around accessing innards may change"]
#[stable]
fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;
}

#[stable]
#[cfg(stage0)]
impl BoxAny for Box<Any> {
#[inline]
fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
Expand All @@ -147,7 +168,7 @@ impl<Sized? T: fmt::Show> fmt::Show for Box<T> {
}
}

impl fmt::Show for Box<Any+'static> {
impl fmt::Show for Box<Any> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Box<Any>")
}
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_typeck/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
ty::ty_trait(ref data) => {
self.check_def_id(item.span, data.principal_def_id());
}
ty::ty_uniq(..) => {
self.check_def_id(item.span,
self.tcx.lang_items.owned_box()
.unwrap());
}
_ => {
span_err!(self.tcx.sess, item.span, E0118,
"no base type found for inherent implementation; \
Expand Down

0 comments on commit f2ccdfd

Please sign in to comment.