From 1b487a890695e7d6dfbfe5dcd7d4fa0e8ca8003f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 27 Aug 2014 21:46:52 -0400 Subject: Implement generalized object and type parameter bounds (Fixes #16462) --- src/libsync/comm/mod.rs | 8 ++++++++ src/libsync/comm/select.rs | 20 +++++++++++++++++++- src/libsync/lib.rs | 1 + src/libsync/lock.rs | 34 ++++++++++++++++++++++++++++++++++ src/libsync/raw.rs | 7 +++++++ src/libsync/spsc_queue.rs | 21 --------------------- 6 files changed, 69 insertions(+), 22 deletions(-) (limited to 'src/libsync') 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 { /// 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 +} + +/// Stage0 only +#[cfg(stage0)] +#[unstable] pub struct Messages<'a, T> { rx: &'a Receiver } 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, +} + +/// 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 { /// 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 { /// 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 { } #[must_use] +#[cfg(stage0)] struct SemGuard<'a, Q> { sem: &'a Sem, } +#[must_use] +#[cfg(not(stage0))] +struct SemGuard<'a, Q:'a> { + sem: &'a Sem, +} + impl Sem { fn new(count: int, q: Q) -> Sem { 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); -- cgit 1.4.1-3-g733a5