summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-05-15 18:18:00 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-06-11 09:11:40 -0700
commit531ed3d599000de2517cba102c83fe44a1f1e252 (patch)
treef6da0ce70539e996d6a533f78e699ab1434a9ede /src/libstd
parentea41101b3522f2a7d121758be489404cbb0fde5a (diff)
downloadrust-531ed3d599000de2517cba102c83fe44a1f1e252.tar.gz
rust-531ed3d599000de2517cba102c83fe44a1f1e252.zip
rustc: Update how Gc<T> is recognized
This commit uses the same trick as ~/Box to map Gc<T> to @T internally inside
the compiler. This moves a number of implementations of traits to the `gc`
module in the standard library.

This removes functions such as `Gc::new`, `Gc::borrow`, and `Gc::ptr_eq` in
favor of the more modern equivalents, `box(GC)`, `Deref`, and pointer equality.

The Gc pointer itself should be much more useful now, and subsequent commits
will move the compiler away from @T towards Gc<T>

[breaking-change]
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/gc.rs95
-rw-r--r--src/libstd/lib.rs3
2 files changed, 64 insertions, 34 deletions
diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs
index 9260d8d7ab2..7988735e80f 100644
--- a/src/libstd/gc.rs
+++ b/src/libstd/gc.rs
@@ -18,52 +18,33 @@ collector is task-local so `Gc<T>` is not sendable.
 
 #![allow(experimental)]
 
-use kinds::marker;
 use clone::Clone;
+use cmp::{TotalOrd, Ord, Ordering, TotalEq, Eq};
+use default::Default;
+use fmt;
+use hash::Hash;
+use io::Writer;
+use kinds::marker;
+use ops::Deref;
+use raw;
 
 /// Immutable garbage-collected pointer type
 #[lang="gc"]
-#[cfg(not(test))]
 #[experimental = "Gc is currently based on reference-counting and will not collect cycles until \
                   task annihilation. For now, cycles need to be broken manually by using `Rc<T>` \
                   with a non-owning `Weak<T>` pointer. A tracing garbage collector is planned."]
 pub struct Gc<T> {
+    #[cfg(stage0)]
     ptr: @T,
+    #[cfg(not(stage0))]
+    ptr: *T,
     marker: marker::NoSend,
 }
 
-#[cfg(test)]
-pub struct Gc<T> {
-    ptr: @T,
-    marker: marker::NoSend,
-}
-
-impl<T: 'static> Gc<T> {
-    /// Construct a new garbage-collected box
-    #[inline]
-    pub fn new(value: T) -> Gc<T> {
-        Gc { ptr: @value, marker: marker::NoSend }
-    }
-
-    /// Borrow the value contained in the garbage-collected box
-    #[inline]
-    pub fn borrow<'r>(&'r self) -> &'r T {
-        &*self.ptr
-    }
-
-    /// Determine if two garbage-collected boxes point to the same object
-    #[inline]
-    pub fn ptr_eq(&self, other: &Gc<T>) -> bool {
-        self.borrow() as *T == other.borrow() as *T
-    }
-}
-
-impl<T> Clone for Gc<T> {
+impl<T: 'static> Clone for Gc<T> {
     /// Clone the pointer only
     #[inline]
-    fn clone(&self) -> Gc<T> {
-        Gc{ ptr: self.ptr, marker: marker::NoSend }
-    }
+    fn clone(&self) -> Gc<T> { *self }
 }
 
 /// An value that represents the task-local managed heap.
@@ -73,8 +54,54 @@ impl<T> Clone for Gc<T> {
 #[cfg(not(test))]
 pub static GC: () = ();
 
-#[cfg(test)]
-pub static GC: () = ();
+impl<T: Eq + 'static> Eq for Gc<T> {
+    #[inline]
+    fn eq(&self, other: &Gc<T>) -> bool { *(*self) == *(*other) }
+    #[inline]
+    fn ne(&self, other: &Gc<T>) -> bool { *(*self) != *(*other) }
+}
+impl<T: Ord + 'static> Ord for Gc<T> {
+    #[inline]
+    fn lt(&self, other: &Gc<T>) -> bool { *(*self) < *(*other) }
+    #[inline]
+    fn le(&self, other: &Gc<T>) -> bool { *(*self) <= *(*other) }
+    #[inline]
+    fn ge(&self, other: &Gc<T>) -> bool { *(*self) >= *(*other) }
+    #[inline]
+    fn gt(&self, other: &Gc<T>) -> bool { *(*self) > *(*other) }
+}
+impl<T: TotalOrd + 'static> TotalOrd for Gc<T> {
+    #[inline]
+    fn cmp(&self, other: &Gc<T>) -> Ordering { (**self).cmp(&**other) }
+}
+impl<T: TotalEq + 'static> TotalEq for Gc<T> {}
+
+impl<T: 'static> Deref<T> for Gc<T> {
+    #[cfg(stage0)]
+    fn deref<'a>(&'a self) -> &'a T { &*self.ptr }
+    #[cfg(not(stage0))]
+    fn deref<'a>(&'a self) -> &'a T { &**self }
+}
+
+impl<T: Default + 'static> Default for Gc<T> {
+    fn default() -> Gc<T> {
+        box(GC) Default::default()
+    }
+}
+
+impl<T: 'static> raw::Repr<*raw::Box<T>> for Gc<T> {}
+
+impl<S: Writer, T: Hash<S> + 'static> Hash<S> for Gc<T> {
+    fn hash(&self, s: &mut S) {
+        (**self).hash(s)
+    }
+}
+
+impl<T: 'static + fmt::Show> fmt::Show for Gc<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        (**self).fmt(f)
+    }
+}
 
 #[cfg(test)]
 mod tests {
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index e147997334c..318410c45c1 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -135,6 +135,8 @@ extern crate rustrt;
 #[cfg(test)] pub use realstd::ops;
 #[cfg(test)] pub use realstd::cmp;
 #[cfg(test)] pub use realstd::ty;
+#[cfg(test)] pub use realstd::owned;
+#[cfg(test)] pub use realstd::gc;
 
 
 // NB: These reexports are in the order they should be listed in rustdoc
@@ -219,6 +221,7 @@ pub mod rand;
 
 pub mod ascii;
 
+#[cfg(not(test))]
 pub mod gc;
 
 /* Common traits */