Skip to content

Commit 7372bf8

Browse files
authored
Rollup merge of rust-lang#96609 - ibraheemdev:arc-downcast-unchecked, r=m-ou-se
Add `{Arc, Rc}::downcast_unchecked` Part of rust-lang#90850.
2 parents 99620ad + 1ac5440 commit 7372bf8

File tree

2 files changed

+80
-5
lines changed

2 files changed

+80
-5
lines changed

library/alloc/src/rc.rs

+38-2
Original file line numberDiff line numberDiff line change
@@ -1254,8 +1254,6 @@ impl<T: Clone> Rc<T> {
12541254
}
12551255

12561256
impl Rc<dyn Any> {
1257-
#[inline]
1258-
#[stable(feature = "rc_downcast", since = "1.29.0")]
12591257
/// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
12601258
///
12611259
/// # Examples
@@ -1274,6 +1272,8 @@ impl Rc<dyn Any> {
12741272
/// print_if_string(Rc::new(my_string));
12751273
/// print_if_string(Rc::new(0i8));
12761274
/// ```
1275+
#[inline]
1276+
#[stable(feature = "rc_downcast", since = "1.29.0")]
12771277
pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
12781278
if (*self).is::<T>() {
12791279
unsafe {
@@ -1285,6 +1285,42 @@ impl Rc<dyn Any> {
12851285
Err(self)
12861286
}
12871287
}
1288+
1289+
/// Downcasts the `Rc<dyn Any>` to a concrete type.
1290+
///
1291+
/// For a safe alternative see [`downcast`].
1292+
///
1293+
/// # Examples
1294+
///
1295+
/// ```
1296+
/// #![feature(downcast_unchecked)]
1297+
///
1298+
/// use std::any::Any;
1299+
/// use std::rc::Rc;
1300+
///
1301+
/// let x: Rc<dyn Any> = Rc::new(1_usize);
1302+
///
1303+
/// unsafe {
1304+
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
1305+
/// }
1306+
/// ```
1307+
///
1308+
/// # Safety
1309+
///
1310+
/// The contained value must be of type `T`. Calling this method
1311+
/// with the incorrect type is *undefined behavior*.
1312+
///
1313+
///
1314+
/// [`downcast`]: Self::downcast
1315+
#[inline]
1316+
#[unstable(feature = "downcast_unchecked", issue = "90850")]
1317+
pub unsafe fn downcast_unchecked<T: Any>(self) -> Rc<T> {
1318+
unsafe {
1319+
let ptr = self.ptr.cast::<RcBox<T>>();
1320+
mem::forget(self);
1321+
Rc::from_inner(ptr)
1322+
}
1323+
}
12881324
}
12891325

12901326
impl<T: ?Sized> Rc<T> {

library/alloc/src/sync.rs

+42-3
Original file line numberDiff line numberDiff line change
@@ -1705,8 +1705,6 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {
17051705
}
17061706

17071707
impl Arc<dyn Any + Send + Sync> {
1708-
#[inline]
1709-
#[stable(feature = "rc_downcast", since = "1.29.0")]
17101708
/// Attempt to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.
17111709
///
17121710
/// # Examples
@@ -1725,9 +1723,11 @@ impl Arc<dyn Any + Send + Sync> {
17251723
/// print_if_string(Arc::new(my_string));
17261724
/// print_if_string(Arc::new(0i8));
17271725
/// ```
1726+
#[inline]
1727+
#[stable(feature = "rc_downcast", since = "1.29.0")]
17281728
pub fn downcast<T>(self) -> Result<Arc<T>, Self>
17291729
where
1730-
T: Any + Send + Sync + 'static,
1730+
T: Any + Send + Sync,
17311731
{
17321732
if (*self).is::<T>() {
17331733
unsafe {
@@ -1739,6 +1739,45 @@ impl Arc<dyn Any + Send + Sync> {
17391739
Err(self)
17401740
}
17411741
}
1742+
1743+
/// Downcasts the `Arc<dyn Any + Send + Sync>` to a concrete type.
1744+
///
1745+
/// For a safe alternative see [`downcast`].
1746+
///
1747+
/// # Examples
1748+
///
1749+
/// ```
1750+
/// #![feature(downcast_unchecked)]
1751+
///
1752+
/// use std::any::Any;
1753+
/// use std::sync::Arc;
1754+
///
1755+
/// let x: Arc<dyn Any + Send + Sync> = Arc::new(1_usize);
1756+
///
1757+
/// unsafe {
1758+
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
1759+
/// }
1760+
/// ```
1761+
///
1762+
/// # Safety
1763+
///
1764+
/// The contained value must be of type `T`. Calling this method
1765+
/// with the incorrect type is *undefined behavior*.
1766+
///
1767+
///
1768+
/// [`downcast`]: Self::downcast
1769+
#[inline]
1770+
#[unstable(feature = "downcast_unchecked", issue = "90850")]
1771+
pub unsafe fn downcast_unchecked<T>(self) -> Arc<T>
1772+
where
1773+
T: Any + Send + Sync,
1774+
{
1775+
unsafe {
1776+
let ptr = self.ptr.cast::<ArcInner<T>>();
1777+
mem::forget(self);
1778+
Arc::from_inner(ptr)
1779+
}
1780+
}
17421781
}
17431782

17441783
impl<T> Weak<T> {

0 commit comments

Comments
 (0)