@@ -1482,8 +1482,6 @@ impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
1482
1482
}
1483
1483
1484
1484
impl < A : Allocator > Box < dyn Any , A > {
1485
- #[ inline]
1486
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1487
1485
/// Attempt to downcast the box to a concrete type.
1488
1486
///
1489
1487
/// # Examples
@@ -1501,21 +1499,46 @@ impl<A: Allocator> Box<dyn Any, A> {
1501
1499
/// print_if_string(Box::new(my_string));
1502
1500
/// print_if_string(Box::new(0i8));
1503
1501
/// ```
1502
+ #[ inline]
1503
+ #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
1504
1504
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)
1512
1537
}
1513
1538
}
1514
1539
}
1515
1540
1516
1541
impl < A : Allocator > Box < dyn Any + Send , A > {
1517
- #[ inline]
1518
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1519
1542
/// Attempt to downcast the box to a concrete type.
1520
1543
///
1521
1544
/// # Examples
@@ -1533,21 +1556,46 @@ impl<A: Allocator> Box<dyn Any + Send, A> {
1533
1556
/// print_if_string(Box::new(my_string));
1534
1557
/// print_if_string(Box::new(0i8));
1535
1558
/// ```
1559
+ #[ inline]
1560
+ #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
1536
1561
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)
1544
1594
}
1545
1595
}
1546
1596
}
1547
1597
1548
1598
impl < A : Allocator > Box < dyn Any + Send + Sync , A > {
1549
- #[ inline]
1550
- #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
1551
1599
/// Attempt to downcast the box to a concrete type.
1552
1600
///
1553
1601
/// # Examples
@@ -1565,15 +1613,42 @@ impl<A: Allocator> Box<dyn Any + Send + Sync, A> {
1565
1613
/// print_if_string(Box::new(my_string));
1566
1614
/// print_if_string(Box::new(0i8));
1567
1615
/// ```
1616
+ #[ inline]
1617
+ #[ stable( feature = "box_send_sync_any_downcast" , since = "1.51.0" ) ]
1568
1618
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)
1577
1652
}
1578
1653
}
1579
1654
}
0 commit comments