about summary refs log tree commit diff
path: root/src/libsync
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-08-27 21:46:52 -0400
committerNiko Matsakis <niko@alum.mit.edu>2014-08-27 21:46:52 -0400
commit1b487a890695e7d6dfbfe5dcd7d4fa0e8ca8003f (patch)
tree552fabade603ab0d148a49ae3cf1abd3f399740a /src/libsync
parent3ee047ae1ffab454270bc1859b3beef3556ef8f9 (diff)
downloadrust-1b487a890695e7d6dfbfe5dcd7d4fa0e8ca8003f.tar.gz
rust-1b487a890695e7d6dfbfe5dcd7d4fa0e8ca8003f.zip
Implement generalized object and type parameter bounds (Fixes #16462)
Diffstat (limited to 'src/libsync')
-rw-r--r--src/libsync/comm/mod.rs8
-rw-r--r--src/libsync/comm/select.rs20
-rw-r--r--src/libsync/lib.rs1
-rw-r--r--src/libsync/lock.rs34
-rw-r--r--src/libsync/raw.rs7
-rw-r--r--src/libsync/spsc_queue.rs21
6 files changed, 69 insertions, 22 deletions
diff --git a/src/libsync/comm/mod.rs b/src/libsync/comm/mod.rs
index 16bcdd9bbb6..16f6eea6144 100644
--- a/src/libsync/comm/mod.rs
+++ b/src/libsync/comm/mod.rs
@@ -386,6 +386,14 @@ pub struct Receiver<T> {
 /// whenever `next` is called, waiting for a new message, and `None` will be
 /// returned when the corresponding channel has hung up.
 #[unstable]
+#[cfg(not(stage0))]
+pub struct Messages<'a, T:'a> {
+    rx: &'a Receiver<T>
+}
+
+/// Stage0 only
+#[cfg(stage0)]
+#[unstable]
 pub struct Messages<'a, T> {
     rx: &'a Receiver<T>
 }
diff --git a/src/libsync/comm/select.rs b/src/libsync/comm/select.rs
index 737a4bfe299..dc9891dd1ee 100644
--- a/src/libsync/comm/select.rs
+++ b/src/libsync/comm/select.rs
@@ -76,6 +76,24 @@ pub struct Select {
 /// A handle to a receiver which is currently a member of a `Select` set of
 /// receivers.  This handle is used to keep the receiver in the set as well as
 /// interact with the underlying receiver.
+#[cfg(not(stage0))]
+pub struct Handle<'rx, T:'rx> {
+    /// The ID of this handle, used to compare against the return value of
+    /// `Select::wait()`
+    id: uint,
+    selector: &'rx Select,
+    next: *mut Handle<'static, ()>,
+    prev: *mut Handle<'static, ()>,
+    added: bool,
+    packet: &'rx Packet+'rx,
+
+    // due to our fun transmutes, we be sure to place this at the end. (nothing
+    // previous relies on T)
+    rx: &'rx Receiver<T>,
+}
+
+/// Stage0 only
+#[cfg(stage0)]
 pub struct Handle<'rx, T> {
     /// The ID of this handle, used to compare against the return value of
     /// `Select::wait()`
@@ -84,7 +102,7 @@ pub struct Handle<'rx, T> {
     next: *mut Handle<'static, ()>,
     prev: *mut Handle<'static, ()>,
     added: bool,
-    packet: &'rx Packet,
+    packet: &'rx Packet+'rx,
 
     // due to our fun transmutes, we be sure to place this at the end. (nothing
     // previous relies on T)
diff --git a/src/libsync/lib.rs b/src/libsync/lib.rs
index bed90743503..c2744751ee5 100644
--- a/src/libsync/lib.rs
+++ b/src/libsync/lib.rs
@@ -29,6 +29,7 @@
 
 #![feature(phase, globs, macro_rules, unsafe_destructor)]
 #![feature(import_shadowing)]
+#![feature(issue_5723_bootstrap)]
 #![deny(missing_doc)]
 #![no_std]
 
diff --git a/src/libsync/lock.rs b/src/libsync/lock.rs
index b07d06ca18e..e1cae6c62d5 100644
--- a/src/libsync/lock.rs
+++ b/src/libsync/lock.rs
@@ -180,6 +180,18 @@ pub struct Mutex<T> {
 
 /// An guard which is created by locking a mutex. Through this guard the
 /// underlying data can be accessed.
+#[cfg(not(stage0))]
+pub struct MutexGuard<'a, T:'a> {
+    // FIXME #12808: strange name to try to avoid interfering with
+    // field accesses of the contained type via Deref
+    _data: &'a mut T,
+    /// Inner condition variable connected to the locked mutex that this guard
+    /// was created from. This can be used for atomic-unlock-and-deschedule.
+    pub cond: Condvar<'a>,
+}
+
+/// stage0 only
+#[cfg(stage0)]
 pub struct MutexGuard<'a, T> {
     // FIXME #12808: strange name to try to avoid interfering with
     // field accesses of the contained type via Deref
@@ -280,6 +292,18 @@ pub struct RWLock<T> {
 
 /// A guard which is created by locking an rwlock in write mode. Through this
 /// guard the underlying data can be accessed.
+#[cfg(not(stage0))]
+pub struct RWLockWriteGuard<'a, T:'a> {
+    // FIXME #12808: strange name to try to avoid interfering with
+    // field accesses of the contained type via Deref
+    _data: &'a mut T,
+    /// Inner condition variable that can be used to sleep on the write mode of
+    /// this rwlock.
+    pub cond: Condvar<'a>,
+}
+
+/// stage0 only
+#[cfg(stage0)]
 pub struct RWLockWriteGuard<'a, T> {
     // FIXME #12808: strange name to try to avoid interfering with
     // field accesses of the contained type via Deref
@@ -291,6 +315,16 @@ pub struct RWLockWriteGuard<'a, T> {
 
 /// A guard which is created by locking an rwlock in read mode. Through this
 /// guard the underlying data can be accessed.
+#[cfg(not(stage0))]
+pub struct RWLockReadGuard<'a, T:'a> {
+    // FIXME #12808: strange names to try to avoid interfering with
+    // field accesses of the contained type via Deref
+    _data: &'a T,
+    _guard: raw::RWLockReadGuard<'a>,
+}
+
+/// Stage0 only
+#[cfg(stage0)]
 pub struct RWLockReadGuard<'a, T> {
     // FIXME #12808: strange names to try to avoid interfering with
     // field accesses of the contained type via Deref
diff --git a/src/libsync/raw.rs b/src/libsync/raw.rs
index c42d567fc18..98934d87474 100644
--- a/src/libsync/raw.rs
+++ b/src/libsync/raw.rs
@@ -103,10 +103,17 @@ struct SemInner<Q> {
 }
 
 #[must_use]
+#[cfg(stage0)]
 struct SemGuard<'a, Q> {
     sem: &'a Sem<Q>,
 }
 
+#[must_use]
+#[cfg(not(stage0))]
+struct SemGuard<'a, Q:'a> {
+    sem: &'a Sem<Q>,
+}
+
 impl<Q: Send> Sem<Q> {
     fn new(count: int, q: Q) -> Sem<Q> {
         assert!(count >= 0,
diff --git a/src/libsync/spsc_queue.rs b/src/libsync/spsc_queue.rs
index 578e518cb8f..32b77be78a4 100644
--- a/src/libsync/spsc_queue.rs
+++ b/src/libsync/spsc_queue.rs
@@ -315,27 +315,6 @@ mod test {
         assert_eq!(consumer.pop(), None);
     }
 
-    // This behaviour is blocked by the type system if using the safe constructor
-    #[test]
-    fn pop_peeked_unchecked() {
-        let q = unsafe { Queue::new(0) };
-        q.push(vec![1i]);
-        q.push(vec![2]);
-        let peeked = q.peek().unwrap();
-
-        assert_eq!(*peeked, vec![1]);
-        assert_eq!(q.pop(), Some(vec![1]));
-
-        assert_eq!(*peeked, vec![1]);
-        q.push(vec![7]);
-
-        // Note: This should actually expect 1, but this test is to highlight
-        // the unsafety allowed by the unchecked usage. A Rust user would not
-        // expect their peeked value to mutate like this without the type system
-        // complaining.
-        assert_eq!(*peeked, vec![7]);
-    }
-
     #[test]
     fn peek() {
         let (mut consumer, mut producer) = queue(0);