Skip to content

Commit f2ccdfd

Browse files
committed
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<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]
1 parent cd61416 commit f2ccdfd

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

src/liballoc/boxed.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
//! A unique pointer type.
1212
13+
#![stable]
14+
1315
use core::any::{Any, AnyRefExt};
1416
use core::clone::Clone;
1517
use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
@@ -44,7 +46,7 @@ pub static HEAP: () = ();
4446

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

5052
#[stable]
@@ -111,18 +113,37 @@ impl<S: hash::Writer, Sized? T: Hash<S>> Hash<S> for Box<T> {
111113
}
112114
}
113115

116+
#[cfg(not(stage0))]
117+
impl Box<Any> {
118+
pub fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
119+
if self.is::<T>() {
120+
unsafe {
121+
// Get the raw representation of the trait object
122+
let to: TraitObject =
123+
mem::transmute::<Box<Any>, TraitObject>(self);
124+
125+
// Extract the data pointer
126+
Ok(mem::transmute(to.data))
127+
}
128+
} else {
129+
Err(self)
130+
}
131+
}
132+
}
114133

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

125145
#[stable]
146+
#[cfg(stage0)]
126147
impl BoxAny for Box<Any> {
127148
#[inline]
128149
fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
@@ -147,7 +168,7 @@ impl<Sized? T: fmt::Show> fmt::Show for Box<T> {
147168
}
148169
}
149170

150-
impl fmt::Show for Box<Any+'static> {
171+
impl fmt::Show for Box<Any> {
151172
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
152173
f.pad("Box<Any>")
153174
}

src/librustc_typeck/coherence/orphan.rs

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
5757
ty::ty_trait(ref data) => {
5858
self.check_def_id(item.span, data.principal_def_id());
5959
}
60+
ty::ty_uniq(..) => {
61+
self.check_def_id(item.span,
62+
self.tcx.lang_items.owned_box()
63+
.unwrap());
64+
}
6065
_ => {
6166
span_err!(self.tcx.sess, item.span, E0118,
6267
"no base type found for inherent implementation; \

0 commit comments

Comments
 (0)