diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-05-15 18:18:00 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-06-11 09:11:40 -0700 |
| commit | 531ed3d599000de2517cba102c83fe44a1f1e252 (patch) | |
| tree | f6da0ce70539e996d6a533f78e699ab1434a9ede /src/libstd | |
| parent | ea41101b3522f2a7d121758be489404cbb0fde5a (diff) | |
| download | rust-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.rs | 95 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 3 |
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 */ |
