@@ -1482,8 +1482,6 @@ impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
14821482}
14831483
14841484impl < A : Allocator > Box < dyn Any , A > {
1485- #[ inline]
1486- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
14871485 /// Attempt to downcast the box to a concrete type.
14881486 ///
14891487 /// # Examples
@@ -1501,21 +1499,46 @@ impl<A: Allocator> Box<dyn Any, A> {
15011499 /// print_if_string(Box::new(my_string));
15021500 /// print_if_string(Box::new(0i8));
15031501 /// ```
1502+ #[ inline]
1503+ #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
15041504 pub fn downcast < T : Any > ( self ) -> Result < Box < T , A > , Self > {
1505- if self . is :: < T > ( ) {
1506- unsafe {
1507- let ( raw, alloc) : ( * mut dyn Any , _ ) = Box :: into_raw_with_allocator ( self ) ;
1508- Ok ( Box :: from_raw_in ( raw as * mut T , alloc) )
1509- }
1510- } else {
1511- Err ( self )
1505+ if self . is :: < T > ( ) { unsafe { Ok ( self . downcast_unchecked :: < T > ( ) ) } } else { Err ( self ) }
1506+ }
1507+
1508+ /// Downcasts the box to a concrete type.
1509+ ///
1510+ /// For a safe alternative see [`downcast`].
1511+ ///
1512+ /// # Examples
1513+ ///
1514+ /// ```
1515+ /// #![feature(downcast_unchecked)]
1516+ ///
1517+ /// use std::any::Any;
1518+ ///
1519+ /// let x: Box<dyn Any> = Box::new(1_usize);
1520+ ///
1521+ /// unsafe {
1522+ /// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
1523+ /// }
1524+ /// ```
1525+ ///
1526+ /// # Safety
1527+ ///
1528+ /// The contained value must be of type `T`. Calling this method
1529+ /// with the incorrect type is *undefined behavior*.
1530+ #[ inline]
1531+ #[ unstable( feature = "downcast_unchecked" , issue = "none" ) ]
1532+ pub unsafe fn downcast_unchecked < T : Any > ( self ) -> Box < T , A > {
1533+ debug_assert ! ( self . is:: <T >( ) ) ;
1534+ unsafe {
1535+ let ( raw, alloc) : ( * mut dyn Any , _ ) = Box :: into_raw_with_allocator ( self ) ;
1536+ Box :: from_raw_in ( raw as * mut T , alloc)
15121537 }
15131538 }
15141539}
15151540
15161541impl < A : Allocator > Box < dyn Any + Send , A > {
1517- #[ inline]
1518- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
15191542 /// Attempt to downcast the box to a concrete type.
15201543 ///
15211544 /// # Examples
@@ -1533,21 +1556,46 @@ impl<A: Allocator> Box<dyn Any + Send, A> {
15331556 /// print_if_string(Box::new(my_string));
15341557 /// print_if_string(Box::new(0i8));
15351558 /// ```
1559+ #[ inline]
1560+ #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
15361561 pub fn downcast < T : Any > ( self ) -> Result < Box < T , A > , Self > {
1537- if self . is :: < T > ( ) {
1538- unsafe {
1539- let ( raw, alloc) : ( * mut ( dyn Any + Send ) , _ ) = Box :: into_raw_with_allocator ( self ) ;
1540- Ok ( Box :: from_raw_in ( raw as * mut T , alloc) )
1541- }
1542- } else {
1543- Err ( self )
1562+ if self . is :: < T > ( ) { unsafe { Ok ( self . downcast_unchecked :: < T > ( ) ) } } else { Err ( self ) }
1563+ }
1564+
1565+ /// Downcasts the box to a concrete type.
1566+ ///
1567+ /// For a safe alternative see [`downcast`].
1568+ ///
1569+ /// # Examples
1570+ ///
1571+ /// ```
1572+ /// #![feature(downcast_unchecked)]
1573+ ///
1574+ /// use std::any::Any;
1575+ ///
1576+ /// let x: Box<dyn Any + Send> = Box::new(1_usize);
1577+ ///
1578+ /// unsafe {
1579+ /// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
1580+ /// }
1581+ /// ```
1582+ ///
1583+ /// # Safety
1584+ ///
1585+ /// The contained value must be of type `T`. Calling this method
1586+ /// with the incorrect type is *undefined behavior*.
1587+ #[ inline]
1588+ #[ unstable( feature = "downcast_unchecked" , issue = "none" ) ]
1589+ pub unsafe fn downcast_unchecked < T : Any > ( self ) -> Box < T , A > {
1590+ debug_assert ! ( self . is:: <T >( ) ) ;
1591+ unsafe {
1592+ let ( raw, alloc) : ( * mut ( dyn Any + Send ) , _ ) = Box :: into_raw_with_allocator ( self ) ;
1593+ Box :: from_raw_in ( raw as * mut T , alloc)
15441594 }
15451595 }
15461596}
15471597
15481598impl < A : Allocator > Box < dyn Any + Send + Sync , A > {
1549- #[ inline]
1550- #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
15511599 /// Attempt to downcast the box to a concrete type.
15521600 ///
15531601 /// # Examples
@@ -1565,15 +1613,42 @@ impl<A: Allocator> Box<dyn Any + Send + Sync, A> {
15651613 /// print_if_string(Box::new(my_string));
15661614 /// print_if_string(Box::new(0i8));
15671615 /// ```
1616+ #[ inline]
1617+ #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
15681618 pub fn downcast < T : Any > ( self ) -> Result < Box < T , A > , Self > {
1569- if self . is :: < T > ( ) {
1570- unsafe {
1571- let ( raw, alloc) : ( * mut ( dyn Any + Send + Sync ) , _ ) =
1572- Box :: into_raw_with_allocator ( self ) ;
1573- Ok ( Box :: from_raw_in ( raw as * mut T , alloc) )
1574- }
1575- } else {
1576- Err ( self )
1619+ if self . is :: < T > ( ) { unsafe { Ok ( self . downcast_unchecked :: < T > ( ) ) } } else { Err ( self ) }
1620+ }
1621+
1622+ /// Downcasts the box to a concrete type.
1623+ ///
1624+ /// For a safe alternative see [`downcast`].
1625+ ///
1626+ /// # Examples
1627+ ///
1628+ /// ```
1629+ /// #![feature(downcast_unchecked)]
1630+ ///
1631+ /// use std::any::Any;
1632+ ///
1633+ /// let x: Box<dyn Any + Send + Sync> = Box::new(1_usize);
1634+ ///
1635+ /// unsafe {
1636+ /// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
1637+ /// }
1638+ /// ```
1639+ ///
1640+ /// # Safety
1641+ ///
1642+ /// The contained value must be of type `T`. Calling this method
1643+ /// with the incorrect type is *undefined behavior*.
1644+ #[ inline]
1645+ #[ unstable( feature = "downcast_unchecked" , issue = "none" ) ]
1646+ pub unsafe fn downcast_unchecked < T : Any > ( self ) -> Box < T , A > {
1647+ debug_assert ! ( self . is:: <T >( ) ) ;
1648+ unsafe {
1649+ let ( raw, alloc) : ( * mut ( dyn Any + Send + Sync ) , _ ) =
1650+ Box :: into_raw_with_allocator ( self ) ;
1651+ Box :: from_raw_in ( raw as * mut T , alloc)
15771652 }
15781653 }
15791654}
0 commit comments