about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libgreen/simple.rs1
-rw-r--r--src/libgreen/task.rs1
-rw-r--r--src/libnative/task.rs1
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/libserialize/json.rs1
-rw-r--r--src/libstd/any.rs156
-rw-r--r--src/libstd/prelude.rs1
-rw-r--r--src/libstd/raw.rs18
-rw-r--r--src/libsync/sync/mod.rs7
-rw-r--r--src/test/run-fail/fail-macro-any.rs2
-rw-r--r--src/test/run-pass/unit-like-struct-drop-run.rs1
11 files changed, 70 insertions, 120 deletions
diff --git a/src/libgreen/simple.rs b/src/libgreen/simple.rs
index 297c22e2cd6..27ad3b9b919 100644
--- a/src/libgreen/simple.rs
+++ b/src/libgreen/simple.rs
@@ -11,6 +11,7 @@
 //! A small module implementing a simple "runtime" used for bootstrapping a rust
 //! scheduler pool and then interacting with it.
 
+use std::any::Any;
 use std::cast;
 use std::rt::Runtime;
 use std::rt::local::Local;
diff --git a/src/libgreen/task.rs b/src/libgreen/task.rs
index bf0ea14ca87..47c1445fb22 100644
--- a/src/libgreen/task.rs
+++ b/src/libgreen/task.rs
@@ -18,6 +18,7 @@
 //! contains the rust task itself in order to juggle around ownership of the
 //! values.
 
+use std::any::Any;
 use std::cast;
 use std::rt::env;
 use std::rt::Runtime;
diff --git a/src/libnative/task.rs b/src/libnative/task.rs
index 5682697ebfc..aa3afd4c1a5 100644
--- a/src/libnative/task.rs
+++ b/src/libnative/task.rs
@@ -14,6 +14,7 @@
 //! by rust tasks. This implements the necessary API traits laid out by std::rt
 //! in order to spawn new tasks and deschedule the current task.
 
+use std::any::Any;
 use std::cast;
 use std::rt::env;
 use std::rt::local::Local;
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 4018e70b4f5..74592139e7d 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -46,6 +46,7 @@ use middle::lint;
 
 use d = driver::driver;
 
+use std::any::AnyRefExt;
 use std::cmp;
 use std::io;
 use std::os;
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 5fd5767d890..517f4e9ab69 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -2229,6 +2229,7 @@ mod tests {
         B(~str)
     }
     fn check_err<T: Decodable<Decoder>>(to_parse: &'static str, expected_error: &str) {
+        use std::any::AnyRefExt;
         use std::task;
         let res = task::try(proc() {
             // either fails in `decode` (which is what we want), or
diff --git a/src/libstd/any.rs b/src/libstd/any.rs
index 709da1ee34d..80ead34b68a 100644
--- a/src/libstd/any.rs
+++ b/src/libstd/any.rs
@@ -20,9 +20,10 @@
 //! value. `~Any` adds the `move` method, which will unwrap a `~T` from the object.  See the
 //! extension traits (`*Ext`) for the full details.
 
-use cast::transmute;
+use cast::{transmute, transmute_copy};
 use fmt;
 use option::{Option, Some, None};
+use raw::TraitObject;
 use result::{Result, Ok, Err};
 use intrinsics::TypeId;
 use intrinsics;
@@ -39,12 +40,6 @@ pub enum Void { }
 pub trait Any {
     /// Get the `TypeId` of `self`
     fn get_type_id(&self) -> TypeId;
-
-    /// Get a void pointer to `self`
-    fn as_void_ptr(&self) -> *Void;
-
-    /// Get a mutable void pointer to `self`
-    fn as_mut_void_ptr(&mut self) -> *mut Void;
 }
 
 impl<T: 'static> Any for T {
@@ -52,21 +47,11 @@ impl<T: 'static> Any for T {
     fn get_type_id(&self) -> TypeId {
         TypeId::of::<T>()
     }
-
-    /// Get a void pointer to `self`
-    fn as_void_ptr(&self) -> *Void {
-        self as *T as *Void
-    }
-
-    /// Get a mutable void pointer to `self`
-    fn as_mut_void_ptr(&mut self) -> *mut Void {
-        self as *mut T as *mut Void
-    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // Extension methods for Any trait objects.
-// Implemented as three extension traits so that generics work.
+// Implemented as three extension traits so that the methods can be generic.
 ///////////////////////////////////////////////////////////////////////////////
 
 /// Extension methods for a referenced `Any` trait object
@@ -95,7 +80,13 @@ impl<'a> AnyRefExt<'a> for &'a Any {
     #[inline]
     fn as_ref<T: 'static>(self) -> Option<&'a T> {
         if self.is::<T>() {
-            Some(unsafe { transmute(self.as_void_ptr()) })
+            unsafe {
+                // Get the raw representation of the trait object
+                let to: TraitObject = transmute_copy(&self);
+
+                // Extract the data pointer
+                Some(transmute(to.data))
+            }
         } else {
             None
         }
@@ -113,7 +104,13 @@ impl<'a> AnyMutRefExt<'a> for &'a mut Any {
     #[inline]
     fn as_mut<T: 'static>(self) -> Option<&'a mut T> {
         if self.is::<T>() {
-            Some(unsafe { transmute(self.as_mut_void_ptr()) })
+            unsafe {
+                // Get the raw representation of the trait object
+                let to: TraitObject = transmute_copy(&self);
+
+                // Extract the data pointer
+                Some(transmute(to.data))
+            }
         } else {
             None
         }
@@ -132,13 +129,14 @@ impl AnyOwnExt for ~Any {
     fn move<T: 'static>(self) -> Result<~T, ~Any> {
         if self.is::<T>() {
             unsafe {
-                // Extract the pointer to the boxed value, temporary alias with self
-                let ptr: ~T = transmute(self.as_void_ptr());
+                // Get the raw representation of the trait object
+                let to: TraitObject = transmute_copy(&self);
 
                 // Prevent destructor on self being run
                 intrinsics::forget(self);
 
-                Ok(ptr)
+                // Extract the data pointer
+                Ok(transmute(to.data))
             }
         } else {
             Err(self)
@@ -173,100 +171,6 @@ mod tests {
     static TEST: &'static str = "Test";
 
     #[test]
-    fn any_as_void_ptr() {
-        let (a, b, c) = (~5u as ~Any, ~TEST as ~Any, ~Test as ~Any);
-        let a_r: &Any = a;
-        let b_r: &Any = b;
-        let c_r: &Any = c;
-
-        assert_eq!(a.as_void_ptr(), a_r.as_void_ptr());
-        assert_eq!(b.as_void_ptr(), b_r.as_void_ptr());
-        assert_eq!(c.as_void_ptr(), c_r.as_void_ptr());
-
-        let (a, b, c) = (&5u as &Any, &TEST as &Any, &Test as &Any);
-        let a_r: &Any = a;
-        let b_r: &Any = b;
-        let c_r: &Any = c;
-
-        assert_eq!(a.as_void_ptr(), a_r.as_void_ptr());
-        assert_eq!(b.as_void_ptr(), b_r.as_void_ptr());
-        assert_eq!(c.as_void_ptr(), c_r.as_void_ptr());
-
-        let mut x = Test;
-        let mut y: &'static str = "Test";
-        let (a, b, c) = (&mut 5u as &mut Any,
-                         &mut y as &mut Any,
-                         &mut x as &mut Any);
-        let a_r: &Any = a;
-        let b_r: &Any = b;
-        let c_r: &Any = c;
-
-        assert_eq!(a.as_void_ptr(), a_r.as_void_ptr());
-        assert_eq!(b.as_void_ptr(), b_r.as_void_ptr());
-        assert_eq!(c.as_void_ptr(), c_r.as_void_ptr());
-
-        let (a, b, c) = (5u, "hello", Test);
-        let (a_r, b_r, c_r) = (&a as &Any, &b as &Any, &c as &Any);
-
-        assert_eq!(a.as_void_ptr(), a_r.as_void_ptr());
-        assert_eq!(b.as_void_ptr(), b_r.as_void_ptr());
-        assert_eq!(c.as_void_ptr(), c_r.as_void_ptr());
-    }
-
-    #[test]
-    fn any_as_mut_void_ptr() {
-        let y: &'static str = "Test";
-        let mut a = ~5u as ~Any;
-        let mut b = ~y as ~Any;
-        let mut c = ~Test as ~Any;
-
-        let a_ptr = a.as_mut_void_ptr();
-        let b_ptr = b.as_mut_void_ptr();
-        let c_ptr = c.as_mut_void_ptr();
-
-        let a_r: &mut Any = a;
-        let b_r: &mut Any = b;
-        let c_r: &mut Any = c;
-
-        assert_eq!(a_ptr, a_r.as_mut_void_ptr());
-        assert_eq!(b_ptr, b_r.as_mut_void_ptr());
-        assert_eq!(c_ptr, c_r.as_mut_void_ptr());
-
-        let mut x = Test;
-        let mut y: &'static str = "Test";
-        let a = &mut 5u as &mut Any;
-        let b = &mut y as &mut Any;
-        let c = &mut x as &mut Any;
-
-        let a_ptr = a.as_mut_void_ptr();
-        let b_ptr = b.as_mut_void_ptr();
-        let c_ptr = c.as_mut_void_ptr();
-
-        let a_r: &mut Any = a;
-        let b_r: &mut Any = b;
-        let c_r: &mut Any = c;
-
-        assert_eq!(a_ptr, a_r.as_mut_void_ptr());
-        assert_eq!(b_ptr, b_r.as_mut_void_ptr());
-        assert_eq!(c_ptr, c_r.as_mut_void_ptr());
-
-        let y: &'static str = "Test";
-        let mut a = 5u;
-        let mut b = y;
-        let mut c = Test;
-
-        let a_ptr = a.as_mut_void_ptr();
-        let b_ptr = b.as_mut_void_ptr();
-        let c_ptr = c.as_mut_void_ptr();
-
-        let (a_r, b_r, c_r) = (&mut a as &mut Any, &mut b as &mut Any, &mut c as &mut Any);
-
-        assert_eq!(a_ptr, a_r.as_mut_void_ptr());
-        assert_eq!(b_ptr, b_r.as_mut_void_ptr());
-        assert_eq!(c_ptr, c_r.as_mut_void_ptr());
-    }
-
-    #[test]
     fn any_referenced() {
         let (a, b, c) = (&5u as &Any, &TEST as &Any, &Test as &Any);
 
@@ -395,3 +299,21 @@ mod tests {
         assert_eq!(format!("{}", b), ~"&Any");
     }
 }
+
+#[cfg(test)]
+mod bench {
+    extern crate test;
+
+    use any::{Any, AnyRefExt};
+    use option::Some;
+    use self::test::BenchHarness;
+
+    #[bench]
+    fn bench_as_ref(bh: &mut BenchHarness) {
+        bh.iter(|| {
+            let mut x = 0; let mut y = &mut x as &mut Any;
+            test::black_box(&mut y);
+            test::black_box(y.as_ref::<int>() == Some(&0));
+        });
+    }
+}
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index 5ea00c2f67d..19848f65097 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -35,7 +35,6 @@ pub use mem::drop;
 
 // Reexported types and traits
 
-pub use any::{Any, AnyOwnExt, AnyRefExt, AnyMutRefExt};
 pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr, IntoBytes};
 pub use c_str::ToCStr;
 pub use char::Char;
diff --git a/src/libstd/raw.rs b/src/libstd/raw.rs
index c7ba2ad3932..94ad268f512 100644
--- a/src/libstd/raw.rs
+++ b/src/libstd/raw.rs
@@ -10,6 +10,13 @@
 
 #[allow(missing_doc)];
 
+//! Contains struct definitions for the layout of compiler built-in types.
+//!
+//! They can be used as targets of transmutes in unsafe code for manipulating
+//! the raw representations directly.
+//!
+//! Their definitition should always match the ABI defined in `rustc::back::abi`.
+
 use cast;
 
 /// The representation of a Rust managed box
@@ -49,13 +56,22 @@ pub struct Procedure {
     env: *(),
 }
 
+/// The representation of a Rust trait object.
+///
+/// This struct does not have a `Repr` implementation
+/// because there is no way to refer to all trait objects generically.
+pub struct TraitObject {
+    vtable: *(),
+    data: *(),
+}
+
 /// This trait is meant to map equivalences between raw structs and their
 /// corresponding rust values.
 pub trait Repr<T> {
     /// This function "unwraps" a rust value (without consuming it) into its raw
     /// struct representation. This can be used to read/write different values
     /// for the struct. This is a safe method because by default it does not
-    /// give write-access to the struct returned.
+    /// enable write-access to the fields of the return value in safe code.
     #[inline]
     fn repr(&self) -> T { unsafe { cast::transmute_copy(self) } }
 }
diff --git a/src/libsync/sync/mod.rs b/src/libsync/sync/mod.rs
index 7078f01945e..9fe585c263f 100644
--- a/src/libsync/sync/mod.rs
+++ b/src/libsync/sync/mod.rs
@@ -976,6 +976,8 @@ mod tests {
     }
     #[test]
     fn test_mutex_killed_simple() {
+        use std::any::Any;
+
         // Mutex must get automatically unlocked if failed/killed within.
         let m = Mutex::new();
         let m2 = m.clone();
@@ -992,6 +994,8 @@ mod tests {
     #[ignore(reason = "linked failure")]
     #[test]
     fn test_mutex_killed_cond() {
+        use std::any::Any;
+
         // Getting killed during cond wait must not corrupt the mutex while
         // unwinding (e.g. double unlock).
         let m = Mutex::new();
@@ -1019,6 +1023,7 @@ mod tests {
     #[ignore(reason = "linked failure")]
     #[test]
     fn test_mutex_killed_broadcast() {
+        use std::any::Any;
         use std::unstable::finally::Finally;
 
         let m = Mutex::new();
@@ -1329,6 +1334,8 @@ mod tests {
     }
     #[cfg(test)]
     fn rwlock_kill_helper(mode1: RWLockMode, mode2: RWLockMode) {
+        use std::any::Any;
+
         // Mutex must get automatically unlocked if failed/killed within.
         let x = RWLock::new();
         let x2 = x.clone();
diff --git a/src/test/run-fail/fail-macro-any.rs b/src/test/run-fail/fail-macro-any.rs
index 58f3522ce7a..9bedd8c8cc8 100644
--- a/src/test/run-fail/fail-macro-any.rs
+++ b/src/test/run-fail/fail-macro-any.rs
@@ -11,5 +11,5 @@
 // error-pattern:failed at '~Any'
 
 fn main() {
-    fail!(~413 as ~Any);
+    fail!(~413 as ~::std::any::Any);
 }
diff --git a/src/test/run-pass/unit-like-struct-drop-run.rs b/src/test/run-pass/unit-like-struct-drop-run.rs
index 04507dd01ce..29dbe35752a 100644
--- a/src/test/run-pass/unit-like-struct-drop-run.rs
+++ b/src/test/run-pass/unit-like-struct-drop-run.rs
@@ -10,6 +10,7 @@
 
 // Make sure the destructor is run for unit-like structs.
 
+use std::any::AnyOwnExt;
 use std::task;
 
 struct Foo;