X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=library%2Falloc%2Fsrc%2Fboxed.rs;h=4898b9ca8fc3545add1c05dbd69f50a7284e89f6;hb=4ec5cdc94b83e1a37c628033597c17c4d7645128;hp=f6332b072cf30237425386602ce9222d69a9404e;hpb=5bc09362dc90a9c4037907c0bb8e0773268344b1;p=rust.git diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index f6332b072cf..4898b9ca8fc 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1482,8 +1482,6 @@ fn try_from(boxed_slice: Box<[T]>) -> Result { } impl Box { - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] /// Attempt to downcast the box to a concrete type. /// /// # Examples @@ -1501,21 +1499,48 @@ impl Box { /// print_if_string(Box::new(my_string)); /// print_if_string(Box::new(0i8)); /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] pub fn downcast(self) -> Result, Self> { - if self.is::() { - unsafe { - let (raw, alloc): (*mut dyn Any, _) = Box::into_raw_with_allocator(self); - Ok(Box::from_raw_in(raw as *mut T, alloc)) - } - } else { - Err(self) + if self.is::() { unsafe { Ok(self.downcast_unchecked::()) } } else { Err(self) } + } + + /// Downcasts the box to a concrete type. + /// + /// For a safe alternative see [`downcast`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(downcast_unchecked)] + /// + /// use std::any::Any; + /// + /// let x: Box = Box::new(1_usize); + /// + /// unsafe { + /// assert_eq!(*x.downcast_unchecked::(), 1); + /// } + /// ``` + /// + /// # Safety + /// + /// The contained value must be of type `T`. Calling this method + /// with the incorrect type is *undefined behavior*. + /// + /// [`downcast`]: Self::downcast + #[inline] + #[unstable(feature = "downcast_unchecked", issue = "90850")] + pub unsafe fn downcast_unchecked(self) -> Box { + debug_assert!(self.is::()); + unsafe { + let (raw, alloc): (*mut dyn Any, _) = Box::into_raw_with_allocator(self); + Box::from_raw_in(raw as *mut T, alloc) } } } impl Box { - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] /// Attempt to downcast the box to a concrete type. /// /// # Examples @@ -1533,21 +1558,48 @@ impl Box { /// print_if_string(Box::new(my_string)); /// print_if_string(Box::new(0i8)); /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] pub fn downcast(self) -> Result, Self> { - if self.is::() { - unsafe { - let (raw, alloc): (*mut (dyn Any + Send), _) = Box::into_raw_with_allocator(self); - Ok(Box::from_raw_in(raw as *mut T, alloc)) - } - } else { - Err(self) + if self.is::() { unsafe { Ok(self.downcast_unchecked::()) } } else { Err(self) } + } + + /// Downcasts the box to a concrete type. + /// + /// For a safe alternative see [`downcast`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(downcast_unchecked)] + /// + /// use std::any::Any; + /// + /// let x: Box = Box::new(1_usize); + /// + /// unsafe { + /// assert_eq!(*x.downcast_unchecked::(), 1); + /// } + /// ``` + /// + /// # Safety + /// + /// The contained value must be of type `T`. Calling this method + /// with the incorrect type is *undefined behavior*. + /// + /// [`downcast`]: Self::downcast + #[inline] + #[unstable(feature = "downcast_unchecked", issue = "90850")] + pub unsafe fn downcast_unchecked(self) -> Box { + debug_assert!(self.is::()); + unsafe { + let (raw, alloc): (*mut (dyn Any + Send), _) = Box::into_raw_with_allocator(self); + Box::from_raw_in(raw as *mut T, alloc) } } } impl Box { - #[inline] - #[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")] /// Attempt to downcast the box to a concrete type. /// /// # Examples @@ -1565,15 +1617,44 @@ impl Box { /// print_if_string(Box::new(my_string)); /// print_if_string(Box::new(0i8)); /// ``` + #[inline] + #[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")] pub fn downcast(self) -> Result, Self> { - if self.is::() { - unsafe { - let (raw, alloc): (*mut (dyn Any + Send + Sync), _) = - Box::into_raw_with_allocator(self); - Ok(Box::from_raw_in(raw as *mut T, alloc)) - } - } else { - Err(self) + if self.is::() { unsafe { Ok(self.downcast_unchecked::()) } } else { Err(self) } + } + + /// Downcasts the box to a concrete type. + /// + /// For a safe alternative see [`downcast`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(downcast_unchecked)] + /// + /// use std::any::Any; + /// + /// let x: Box = Box::new(1_usize); + /// + /// unsafe { + /// assert_eq!(*x.downcast_unchecked::(), 1); + /// } + /// ``` + /// + /// # Safety + /// + /// The contained value must be of type `T`. Calling this method + /// with the incorrect type is *undefined behavior*. + /// + /// [`downcast`]: Self::downcast + #[inline] + #[unstable(feature = "downcast_unchecked", issue = "90850")] + pub unsafe fn downcast_unchecked(self) -> Box { + debug_assert!(self.is::()); + unsafe { + let (raw, alloc): (*mut (dyn Any + Send + Sync), _) = + Box::into_raw_with_allocator(self); + Box::from_raw_in(raw as *mut T, alloc) } } }