From f2ccdfd8914b7b8f8f8f2053f9ecd98d54ef95a6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 1 Jan 2015 22:24:06 -0800 Subject: [PATCH] std: Second pass stabilization for `boxed` 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` * `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] --- src/liballoc/boxed.rs | 27 ++++++++++++++++++++++--- src/librustc_typeck/coherence/orphan.rs | 5 +++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 74f0599e486e1..415416199459f 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -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}; @@ -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(Unique); #[stable] @@ -111,18 +113,37 @@ impl> Hash for Box { } } +#[cfg(not(stage0))] +impl Box { + pub fn downcast(self) -> Result, Box> { + if self.is::() { + unsafe { + // Get the raw representation of the trait object + let to: TraitObject = + mem::transmute::, 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`"] +#[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(self) -> Result, Self>; } #[stable] +#[cfg(stage0)] impl BoxAny for Box { #[inline] fn downcast(self) -> Result, Box> { @@ -147,7 +168,7 @@ impl fmt::Show for Box { } } -impl fmt::Show for Box { +impl fmt::Show for Box { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.pad("Box") } diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 79443200ddf0e..49f150cf027d5 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -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; \