diff options
| author | Jonas Schievink <jonasschievink@gmail.com> | 2021-01-31 01:47:27 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-31 01:47:27 +0100 |
| commit | caf2c0652a2aa2db136abcc0a37c85bfb254e2cb (patch) | |
| tree | 6027f0bedd2ae2df2c4967e4e6442a30a4e38856 /library/alloc/src | |
| parent | 1e99f26894a766f5861ae2805c13e915e74493f0 (diff) | |
| parent | 12014d29b89557836a22fa46d74101371d81daf1 (diff) | |
| download | rust-caf2c0652a2aa2db136abcc0a37c85bfb254e2cb.tar.gz rust-caf2c0652a2aa2db136abcc0a37c85bfb254e2cb.zip | |
Rollup merge of #80945 - sdroege:downcast-send-sync, r=m-ou-se
Add Box::downcast() for dyn Any + Send + Sync Looks like a plain omission, but unfortunately I just needed that in my code :)
Diffstat (limited to 'library/alloc/src')
| -rw-r--r-- | library/alloc/src/boxed.rs | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index a3c0be69813..949079e5b69 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1372,6 +1372,39 @@ impl<A: Allocator> Box<dyn Any + Send, A> { } } +impl<A: Allocator> Box<dyn Any + Send + Sync, A> { + #[inline] + #[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")] + /// Attempt to downcast the box to a concrete type. + /// + /// # Examples + /// + /// ``` + /// use std::any::Any; + /// + /// fn print_if_string(value: Box<dyn Any + Send + Sync>) { + /// if let Ok(string) = value.downcast::<String>() { + /// println!("String ({}): {}", string.len(), string); + /// } + /// } + /// + /// let my_string = "Hello World".to_string(); + /// print_if_string(Box::new(my_string)); + /// print_if_string(Box::new(0i8)); + /// ``` + pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> { + if self.is::<T>() { + unsafe { + let (raw, alloc): (*mut (dyn Any + Send + Sync), _) = + Box::into_raw_with_allocator(self); + Ok(Box::from_raw_in(raw as *mut T, alloc)) + } + } else { + Err(self) + } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<T: fmt::Display + ?Sized, A: Allocator> fmt::Display for Box<T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
