X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fliballoc%2Fboxed.rs;h=2801cf38cb75529d94912551a60a5eab51597235;hb=82dcec7ee4a8a71fdfb8e8771ae6785261ec1d5b;hp=f9bd0ab2f1e0fdbe1e3cb88fcb61413d1e21b8b6;hpb=890f0ab10a81720606805db36628f61f29d0e816;p=rust.git diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index f9bd0ab2f1e..2801cf38cb7 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -51,13 +51,12 @@ use core::any::Any; use core::cmp::Ordering; use core::default::Default; -use core::error::{Error, FromError}; use core::fmt; use core::hash::{self, Hash}; use core::mem; use core::ops::{Deref, DerefMut}; -use core::ptr::Unique; -use core::raw::TraitObject; +use core::ptr::{Unique}; +use core::raw::{TraitObject}; /// A value that represents the heap. This is the default place that the `box` /// keyword allocates into when no place is supplied. @@ -84,6 +83,7 @@ /// See the [module-level documentation](../../std/boxed/index.html) for more. #[lang = "owned_box"] #[stable(feature = "rust1", since = "1.0.0")] +#[fundamental] pub struct Box(Unique); impl Box { @@ -233,24 +233,10 @@ fn hash(&self, state: &mut H) { } } -/// Extension methods for an owning `Any` trait object. -#[unstable(feature = "alloc", - reason = "this trait will likely disappear once compiler bugs blocking \ - a direct impl on `Box` have been fixed ")] -// FIXME(#18737): this should be a direct impl on `Box`. If you're -// removing this please make sure that you can downcase on -// `Box` as well as `Box` -pub trait BoxAny { - /// Returns the boxed value if it is of type `T`, or - /// `Err(Self)` if it isn't. - #[stable(feature = "rust1", since = "1.0.0")] - fn downcast(self) -> Result, Box>; -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl BoxAny for Box { +impl Box { #[inline] - fn downcast(self) -> Result, Box> { + #[stable(feature = "rust1", since = "1.0.0")] + pub fn downcast(self) -> Result, Box> { if self.is::() { unsafe { // Get the raw representation of the trait object @@ -267,10 +253,10 @@ fn downcast(self) -> Result, Box> { } } -#[stable(feature = "rust1", since = "1.0.0")] -impl BoxAny for Box { +impl Box { #[inline] - fn downcast(self) -> Result, Box> { + #[stable(feature = "rust1", since = "1.0.0")] + pub fn downcast(self) -> Result, Box> { >::downcast(self) } } @@ -289,13 +275,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -#[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for Box { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad("Box") - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl Deref for Box { type Target = T; @@ -321,9 +300,74 @@ fn next_back(&mut self) -> Option { (**self).next_back() } #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for Box {} -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, E: Error + 'a> FromError for Box { - fn from_error(err: E) -> Box { - Box::new(err) + +/// `FnBox` is a version of the `FnOnce` intended for use with boxed +/// closure objects. The idea is that where one would normally store a +/// `Box` in a data structure, you should use +/// `Box`. The two traits behave essentially the same, except +/// that a `FnBox` closure can only be called if it is boxed. (Note +/// that `FnBox` may be deprecated in the future if `Box` +/// closures become directly usable.) +/// +/// ### Example +/// +/// Here is a snippet of code which creates a hashmap full of boxed +/// once closures and then removes them one by one, calling each +/// closure as it is removed. Note that the type of the closures +/// stored in the map is `Box i32>` and not `Box i32>`. +/// +/// ``` +/// #![feature(core)] +/// +/// use std::boxed::FnBox; +/// use std::collections::HashMap; +/// +/// fn make_map() -> HashMap i32>> { +/// let mut map: HashMap i32>> = HashMap::new(); +/// map.insert(1, Box::new(|| 22)); +/// map.insert(2, Box::new(|| 44)); +/// map +/// } +/// +/// fn main() { +/// let mut map = make_map(); +/// for i in &[1, 2] { +/// let f = map.remove(&i).unwrap(); +/// assert_eq!(f(), i * 22); +/// } +/// } +/// ``` +#[rustc_paren_sugar] +#[unstable(feature = "core", reason = "Newly introduced")] +pub trait FnBox { + type Output; + + fn call_box(self: Box, args: A) -> Self::Output; +} + +impl FnBox for F + where F: FnOnce +{ + type Output = F::Output; + + fn call_box(self: Box, args: A) -> F::Output { + self.call_once(args) + } +} + +impl<'a,A,R> FnOnce for Box+'a> { + type Output = R; + + extern "rust-call" fn call_once(self, args: A) -> R { + self.call_box(args) + } +} + +impl<'a,A,R> FnOnce for Box+Send+'a> { + type Output = R; + + extern "rust-call" fn call_once(self, args: A) -> R { + self.call_box(args) } }