]> git.lizzy.rs Git - rust.git/blobdiff - library/alloc/src/rc.rs
Rollup merge of #96609 - ibraheemdev:arc-downcast-unchecked, r=m-ou-se
[rust.git] / library / alloc / src / rc.rs
index 2b3736019ba40ee05627208d74604a33228d46c8..a248cd458df81b40b9ceb7a048d1f64457a4924d 100644 (file)
@@ -1254,8 +1254,6 @@ pub fn unwrap_or_clone(this: Self) -> T {
 }
 
 impl Rc<dyn Any> {
-    #[inline]
-    #[stable(feature = "rc_downcast", since = "1.29.0")]
     /// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
     ///
     /// # Examples
@@ -1274,6 +1272,8 @@ impl Rc<dyn Any> {
     /// print_if_string(Rc::new(my_string));
     /// print_if_string(Rc::new(0i8));
     /// ```
+    #[inline]
+    #[stable(feature = "rc_downcast", since = "1.29.0")]
     pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
         if (*self).is::<T>() {
             unsafe {
@@ -1285,6 +1285,42 @@ pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
             Err(self)
         }
     }
+
+    /// Downcasts the `Rc<dyn Any>` to a concrete type.
+    ///
+    /// For a safe alternative see [`downcast`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(downcast_unchecked)]
+    ///
+    /// use std::any::Any;
+    /// use std::rc::Rc;
+    ///
+    /// let x: Rc<dyn Any> = Rc::new(1_usize);
+    ///
+    /// unsafe {
+    ///     assert_eq!(*x.downcast_unchecked::<usize>(), 1);
+    /// }
+    /// ```
+    ///
+    /// # Safety
+    ///
+    /// The contained value must be of type `T`. Calling this method
+    /// with the incorrect type is *undefined behavior*.
+    ///
+    ///
+    /// [`downcast`]: Self::downcast
+    #[inline]
+    #[unstable(feature = "downcast_unchecked", issue = "90850")]
+    pub unsafe fn downcast_unchecked<T: Any>(self) -> Rc<T> {
+        unsafe {
+            let ptr = self.ptr.cast::<RcBox<T>>();
+            mem::forget(self);
+            Rc::from_inner(ptr)
+        }
+    }
 }
 
 impl<T: ?Sized> Rc<T> {