@@ -1518,8 +1518,6 @@ impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
15181518}
15191519
15201520impl < A : Allocator > Box < dyn Any , A > {
1521- #[ inline]
1522- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
15231521 /// Attempt to downcast the box to a concrete type.
15241522 ///
15251523 /// # Examples
@@ -1537,21 +1535,48 @@ impl<A: Allocator> Box<dyn Any, A> {
15371535 /// print_if_string(Box::new(my_string));
15381536 /// print_if_string(Box::new(0i8));
15391537 /// ```
1538+ #[ inline]
1539+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
15401540 pub fn downcast < T : Any > ( self ) -> Result < Box < T , A > , Self > {
1541- if self . is :: < T > ( ) {
1542- unsafe {
1543- let ( raw, alloc) : ( * mut dyn Any , _ ) = Box :: into_raw_with_allocator ( self ) ;
1544- Ok ( Box :: from_raw_in ( raw as * mut T , alloc) )
1545- }
1546- } else {
1547- Err ( self )
1541+ if self . is :: < T > ( ) { unsafe { Ok ( self . downcast_unchecked :: < T > ( ) ) } } else { Err ( self ) }
1542+ }
1543+
1544+ /// Downcasts the box to a concrete type.
1545+ ///
1546+ /// For a safe alternative see [`downcast`].
1547+ ///
1548+ /// # Examples
1549+ ///
1550+ /// ```
1551+ /// #![feature(downcast_unchecked)]
1552+ ///
1553+ /// use std::any::Any;
1554+ ///
1555+ /// let x: Box<dyn Any> = Box::new(1_usize);
1556+ ///
1557+ /// unsafe {
1558+ /// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
1559+ /// }
1560+ /// ```
1561+ ///
1562+ /// # Safety
1563+ ///
1564+ /// The contained value must be of type `T`. Calling this method
1565+ /// with the incorrect type is *undefined behavior*.
1566+ ///
1567+ /// [`downcast`]: Self::downcast
1568+ #[ inline]
1569+ #[ unstable( feature = "downcast_unchecked" , issue = "90850" ) ]
1570+ pub unsafe fn downcast_unchecked < T : Any > ( self ) -> Box < T , A > {
1571+ debug_assert ! ( self . is:: <T >( ) ) ;
1572+ unsafe {
1573+ let ( raw, alloc) : ( * mut dyn Any , _ ) = Box :: into_raw_with_allocator ( self ) ;
1574+ Box :: from_raw_in ( raw as * mut T , alloc)
15481575 }
15491576 }
15501577}
15511578
15521579impl < A : Allocator > Box < dyn Any + Send , A > {
1553- #[ inline]
1554- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
15551580 /// Attempt to downcast the box to a concrete type.
15561581 ///
15571582 /// # Examples
@@ -1569,21 +1594,48 @@ impl<A: Allocator> Box<dyn Any + Send, A> {
15691594 /// print_if_string(Box::new(my_string));
15701595 /// print_if_string(Box::new(0i8));
15711596 /// ```
1597+ #[ inline]
1598+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
15721599 pub fn downcast < T : Any > ( self ) -> Result < Box < T , A > , Self > {
1573- if self . is :: < T > ( ) {
1574- unsafe {
1575- let ( raw, alloc) : ( * mut ( dyn Any + Send ) , _ ) = Box :: into_raw_with_allocator ( self ) ;
1576- Ok ( Box :: from_raw_in ( raw as * mut T , alloc) )
1577- }
1578- } else {
1579- Err ( self )
1600+ if self . is :: < T > ( ) { unsafe { Ok ( self . downcast_unchecked :: < T > ( ) ) } } else { Err ( self ) }
1601+ }
1602+
1603+ /// Downcasts the box to a concrete type.
1604+ ///
1605+ /// For a safe alternative see [`downcast`].
1606+ ///
1607+ /// # Examples
1608+ ///
1609+ /// ```
1610+ /// #![feature(downcast_unchecked)]
1611+ ///
1612+ /// use std::any::Any;
1613+ ///
1614+ /// let x: Box<dyn Any + Send> = Box::new(1_usize);
1615+ ///
1616+ /// unsafe {
1617+ /// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
1618+ /// }
1619+ /// ```
1620+ ///
1621+ /// # Safety
1622+ ///
1623+ /// The contained value must be of type `T`. Calling this method
1624+ /// with the incorrect type is *undefined behavior*.
1625+ ///
1626+ /// [`downcast`]: Self::downcast
1627+ #[ inline]
1628+ #[ unstable( feature = "downcast_unchecked" , issue = "90850" ) ]
1629+ pub unsafe fn downcast_unchecked < T : Any > ( self ) -> Box < T , A > {
1630+ debug_assert ! ( self . is:: <T >( ) ) ;
1631+ unsafe {
1632+ let ( raw, alloc) : ( * mut ( dyn Any + Send ) , _ ) = Box :: into_raw_with_allocator ( self ) ;
1633+ Box :: from_raw_in ( raw as * mut T , alloc)
15801634 }
15811635 }
15821636}
15831637
15841638impl < A : Allocator > Box < dyn Any + Send + Sync , A > {
1585- #[ inline]
1586- #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
15871639 /// Attempt to downcast the box to a concrete type.
15881640 ///
15891641 /// # Examples
@@ -1601,15 +1653,44 @@ impl<A: Allocator> Box<dyn Any + Send + Sync, A> {
16011653 /// print_if_string(Box::new(my_string));
16021654 /// print_if_string(Box::new(0i8));
16031655 /// ```
1656+ #[ inline]
1657+ #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
16041658 pub fn downcast < T : Any > ( self ) -> Result < Box < T , A > , Self > {
1605- if self . is :: < T > ( ) {
1606- unsafe {
1607- let ( raw, alloc) : ( * mut ( dyn Any + Send + Sync ) , _ ) =
1608- Box :: into_raw_with_allocator ( self ) ;
1609- Ok ( Box :: from_raw_in ( raw as * mut T , alloc) )
1610- }
1611- } else {
1612- Err ( self )
1659+ if self . is :: < T > ( ) { unsafe { Ok ( self . downcast_unchecked :: < T > ( ) ) } } else { Err ( self ) }
1660+ }
1661+
1662+ /// Downcasts the box to a concrete type.
1663+ ///
1664+ /// For a safe alternative see [`downcast`].
1665+ ///
1666+ /// # Examples
1667+ ///
1668+ /// ```
1669+ /// #![feature(downcast_unchecked)]
1670+ ///
1671+ /// use std::any::Any;
1672+ ///
1673+ /// let x: Box<dyn Any + Send + Sync> = Box::new(1_usize);
1674+ ///
1675+ /// unsafe {
1676+ /// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
1677+ /// }
1678+ /// ```
1679+ ///
1680+ /// # Safety
1681+ ///
1682+ /// The contained value must be of type `T`. Calling this method
1683+ /// with the incorrect type is *undefined behavior*.
1684+ ///
1685+ /// [`downcast`]: Self::downcast
1686+ #[ inline]
1687+ #[ unstable( feature = "downcast_unchecked" , issue = "90850" ) ]
1688+ pub unsafe fn downcast_unchecked < T : Any > ( self ) -> Box < T , A > {
1689+ debug_assert ! ( self . is:: <T >( ) ) ;
1690+ unsafe {
1691+ let ( raw, alloc) : ( * mut ( dyn Any + Send + Sync ) , _ ) =
1692+ Box :: into_raw_with_allocator ( self ) ;
1693+ Box :: from_raw_in ( raw as * mut T , alloc)
16131694 }
16141695 }
16151696}
0 commit comments