@@ -1518,8 +1518,6 @@ impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
1518
1518
}
1519
1519
1520
1520
impl < A : Allocator > Box < dyn Any , A > {
1521
- #[ inline]
1522
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1523
1521
/// Attempt to downcast the box to a concrete type.
1524
1522
///
1525
1523
/// # Examples
@@ -1537,21 +1535,48 @@ impl<A: Allocator> Box<dyn Any, A> {
1537
1535
/// print_if_string(Box::new(my_string));
1538
1536
/// print_if_string(Box::new(0i8));
1539
1537
/// ```
1538
+ #[ inline]
1539
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1540
1540
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)
1548
1575
}
1549
1576
}
1550
1577
}
1551
1578
1552
1579
impl < A : Allocator > Box < dyn Any + Send , A > {
1553
- #[ inline]
1554
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1555
1580
/// Attempt to downcast the box to a concrete type.
1556
1581
///
1557
1582
/// # Examples
@@ -1569,21 +1594,48 @@ impl<A: Allocator> Box<dyn Any + Send, A> {
1569
1594
/// print_if_string(Box::new(my_string));
1570
1595
/// print_if_string(Box::new(0i8));
1571
1596
/// ```
1597
+ #[ inline]
1598
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1572
1599
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)
1580
1634
}
1581
1635
}
1582
1636
}
1583
1637
1584
1638
impl < A : Allocator > Box < dyn Any + Send + Sync , A > {
1585
- #[ inline]
1586
- #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
1587
1639
/// Attempt to downcast the box to a concrete type.
1588
1640
///
1589
1641
/// # Examples
@@ -1601,15 +1653,44 @@ impl<A: Allocator> Box<dyn Any + Send + Sync, A> {
1601
1653
/// print_if_string(Box::new(my_string));
1602
1654
/// print_if_string(Box::new(0i8));
1603
1655
/// ```
1656
+ #[ inline]
1657
+ #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
1604
1658
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)
1613
1694
}
1614
1695
}
1615
1696
}
0 commit comments