about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-06-28 18:21:34 +0000
committerbors <bors@rust-lang.org>2014-06-28 18:21:34 +0000
commitde337f3ddfbef800a8cf731e0b593e341af1e3e5 (patch)
tree7f35eb443f0b58d81dc39f6d19da42bac4645d7e /src/liballoc
parentb47f2226a25654c5b781d27a91f2fa5274b3a347 (diff)
parent05e3248a7974f55b64f75a2483b37ff8c001a4ff (diff)
downloadrust-de337f3ddfbef800a8cf731e0b593e341af1e3e5.tar.gz
rust-de337f3ddfbef800a8cf731e0b593e341af1e3e5.zip
auto merge of #15191 : pcwalton/rust/variance-in-trait-matching, r=huonw
I believe that #5781 got fixed by the DST work. It duplicated the
variance inference work in #12828. Therefore, all that is left in #5781
is adding a test.

Closes #5781.

r? @huonw
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/owned.rs29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/liballoc/owned.rs b/src/liballoc/owned.rs
index 6f5d3293556..94b8bee8cc9 100644
--- a/src/liballoc/owned.rs
+++ b/src/liballoc/owned.rs
@@ -16,6 +16,7 @@ use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
 use core::default::Default;
 use core::fmt;
 use core::intrinsics;
+use core::kinds::Send;
 use core::mem;
 use core::raw::TraitObject;
 use core::result::{Ok, Err, Result};
@@ -106,6 +107,34 @@ impl AnyOwnExt for Box<Any> {
     }
 }
 
+/// Extension methods for an owning `Any+Send` trait object
+pub trait AnySendOwnExt {
+    /// Returns the boxed value if it is of type `T`, or
+    /// `Err(Self)` if it isn't.
+    fn move_send<T: 'static>(self) -> Result<Box<T>, Self>;
+}
+
+impl AnySendOwnExt for Box<Any+Send> {
+    #[inline]
+    fn move_send<T: 'static>(self) -> Result<Box<T>, Box<Any+Send>> {
+        if self.is::<T>() {
+            unsafe {
+                // Get the raw representation of the trait object
+                let to: TraitObject =
+                    *mem::transmute::<&Box<Any+Send>, &TraitObject>(&self);
+
+                // Prevent destructor on self being run
+                intrinsics::forget(self);
+
+                // Extract the data pointer
+                Ok(mem::transmute(to.data))
+            }
+        } else {
+            Err(self)
+        }
+    }
+}
+
 impl<T: fmt::Show> fmt::Show for Box<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         (**self).fmt(f)