From d7b5bc3c2f673ac3edd818cb7bd42555c2cbc2a2 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 13 Feb 2015 22:58:37 +1100 Subject: Update the libraries to reflect Send loosing the 'static bound. In most places this preserves the current API by adding an explicit `'static` bound. Notably absent are some impls like `unsafe impl Send for Foo` and the `std::thread` module. It is likely that it will be possible to remove these after auditing the code to ensure restricted lifetimes are safe. More progress on #22251. --- src/libstd/rt/at_exit_imp.rs | 4 ++-- src/libstd/rt/mod.rs | 2 +- src/libstd/rt/unwind.rs | 4 ++-- src/libstd/sync/future.rs | 8 ++++---- src/libstd/sync/mpsc/mod.rs | 30 +++++++++++++++--------------- src/libstd/sync/mpsc/mpsc_queue.rs | 6 +++--- src/libstd/sync/mpsc/oneshot.rs | 4 ++-- src/libstd/sync/mpsc/select.rs | 6 +++--- src/libstd/sync/mpsc/shared.rs | 4 ++-- src/libstd/sync/mpsc/spsc_queue.rs | 10 +++++----- src/libstd/sync/mpsc/stream.rs | 4 ++-- src/libstd/sync/mpsc/sync.rs | 12 ++++++------ src/libstd/sync/mutex.rs | 8 ++++---- src/libstd/sync/task_pool.rs | 10 +++++----- src/libstd/sys/common/helper_thread.rs | 2 +- src/libstd/thread.rs | 14 +++++++------- src/libstd/thunk.rs | 19 +++++++++++-------- 17 files changed, 75 insertions(+), 72 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs index 3f15cf71ec3..72486fc55d4 100644 --- a/src/libstd/rt/at_exit_imp.rs +++ b/src/libstd/rt/at_exit_imp.rs @@ -20,7 +20,7 @@ use mem; use thunk::Thunk; use sys_common::mutex::{Mutex, MUTEX_INIT}; -type Queue = Vec; +type Queue = Vec>; // NB these are specifically not types from `std::sync` as they currently rely // on poisoning and this module needs to operate at a lower level than requiring @@ -65,7 +65,7 @@ pub fn cleanup() { } } -pub fn push(f: Thunk) { +pub fn push(f: Thunk<'static>) { unsafe { LOCK.lock(); init(); diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 00088d6d99a..42cca73e5e2 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -148,7 +148,7 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int { /// /// It is forbidden for procedures to register more `at_exit` handlers when they /// are running, and doing so will lead to a process abort. -pub fn at_exit(f: F) { +pub fn at_exit(f: F) { at_exit_imp::push(Thunk::new(f)); } diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs index c9bbea27e4a..1f5eb3af695 100644 --- a/src/libstd/rt/unwind.rs +++ b/src/libstd/rt/unwind.rs @@ -74,7 +74,7 @@ use rt::libunwind as uw; struct Exception { uwe: uw::_Unwind_Exception, - cause: Option>, + cause: Option>, } pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: uint); @@ -161,7 +161,7 @@ pub fn panicking() -> bool { #[inline(never)] #[no_mangle] #[allow(private_no_mangle_fns)] -fn rust_panic(cause: Box) -> ! { +fn rust_panic(cause: Box) -> ! { rtdebug!("begin_unwind()"); unsafe { diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs index a230e35dac8..ae2a8db0342 100644 --- a/src/libstd/sync/future.rs +++ b/src/libstd/sync/future.rs @@ -46,7 +46,7 @@ pub struct Future { } enum FutureState { - Pending(Thunk<(),A>), + Pending(Thunk<'static,(),A>), Evaluating, Forced(A) } @@ -103,7 +103,7 @@ impl Future { } pub fn from_fn(f: F) -> Future - where F : FnOnce() -> A, F : Send + where F : FnOnce() -> A, F : Send + 'static { /*! * Create a future from a function. @@ -117,7 +117,7 @@ impl Future { } } -impl Future { +impl Future { pub fn from_receiver(rx: Receiver) -> Future { /*! * Create a future from a port @@ -132,7 +132,7 @@ impl Future { } pub fn spawn(blk: F) -> Future - where F : FnOnce() -> A, F : Send + where F : FnOnce() -> A, F : Send + 'static { /*! * Create a future from a unique closure. diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index d783acd57ac..4ba4e544764 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -345,7 +345,7 @@ pub struct Receiver { // The receiver port can be sent from place to place, so long as it // is not used to receive non-sendable things. -unsafe impl Send for Receiver { } +unsafe impl Send for Receiver { } /// An iterator over messages on a receiver, this iterator will block /// whenever `next` is called, waiting for a new message, and `None` will be @@ -364,7 +364,7 @@ pub struct Sender { // The send port can be sent from place to place, so long as it // is not used to send non-sendable things. -unsafe impl Send for Sender { } +unsafe impl Send for Sender { } /// The sending-half of Rust's synchronous channel type. This half can only be /// owned by one task, but it can be cloned to send to other tasks. @@ -373,7 +373,7 @@ pub struct SyncSender { inner: Arc>>, } -unsafe impl Send for SyncSender {} +unsafe impl Send for SyncSender {} impl !Sync for SyncSender {} @@ -485,7 +485,7 @@ impl UnsafeFlavor for Receiver { /// println!("{:?}", rx.recv().unwrap()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub fn channel() -> (Sender, Receiver) { +pub fn channel() -> (Sender, Receiver) { let a = Arc::new(UnsafeCell::new(oneshot::Packet::new())); (Sender::new(Flavor::Oneshot(a.clone())), Receiver::new(Flavor::Oneshot(a))) } @@ -525,7 +525,7 @@ pub fn channel() -> (Sender, Receiver) { /// assert_eq!(rx.recv().unwrap(), 2); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub fn sync_channel(bound: uint) -> (SyncSender, Receiver) { +pub fn sync_channel(bound: uint) -> (SyncSender, Receiver) { let a = Arc::new(UnsafeCell::new(sync::Packet::new(bound))); (SyncSender::new(a.clone()), Receiver::new(Flavor::Sync(a))) } @@ -534,7 +534,7 @@ pub fn sync_channel(bound: uint) -> (SyncSender, Receiver) { // Sender //////////////////////////////////////////////////////////////////////////////// -impl Sender { +impl Sender { fn new(inner: Flavor) -> Sender { Sender { inner: UnsafeCell::new(inner), @@ -616,7 +616,7 @@ impl Sender { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Sender { +impl Clone for Sender { fn clone(&self) -> Sender { let (packet, sleeper, guard) = match *unsafe { self.inner() } { Flavor::Oneshot(ref p) => { @@ -662,7 +662,7 @@ impl Clone for Sender { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for Sender { +impl Drop for Sender { fn drop(&mut self) { match *unsafe { self.inner_mut() } { Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_chan(); }, @@ -677,7 +677,7 @@ impl Drop for Sender { // SyncSender //////////////////////////////////////////////////////////////////////////////// -impl SyncSender { +impl SyncSender { fn new(inner: Arc>>) -> SyncSender { SyncSender { inner: inner } } @@ -717,7 +717,7 @@ impl SyncSender { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for SyncSender { +impl Clone for SyncSender { fn clone(&self) -> SyncSender { unsafe { (*self.inner.get()).clone_chan(); } return SyncSender::new(self.inner.clone()); @@ -726,7 +726,7 @@ impl Clone for SyncSender { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for SyncSender { +impl Drop for SyncSender { fn drop(&mut self) { unsafe { (*self.inner.get()).drop_chan(); } } @@ -736,7 +736,7 @@ impl Drop for SyncSender { // Receiver //////////////////////////////////////////////////////////////////////////////// -impl Receiver { +impl Receiver { fn new(inner: Flavor) -> Receiver { Receiver { inner: UnsafeCell::new(inner) } } @@ -855,7 +855,7 @@ impl Receiver { } } -impl select::Packet for Receiver { +impl select::Packet for Receiver { fn can_recv(&self) -> bool { loop { let new_port = match *unsafe { self.inner() } { @@ -942,7 +942,7 @@ impl select::Packet for Receiver { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T: Send> Iterator for Iter<'a, T> { +impl<'a, T: Send + 'static> Iterator for Iter<'a, T> { type Item = T; fn next(&mut self) -> Option { self.rx.recv().ok() } @@ -950,7 +950,7 @@ impl<'a, T: Send> Iterator for Iter<'a, T> { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for Receiver { +impl Drop for Receiver { fn drop(&mut self) { match *unsafe { self.inner_mut() } { Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_port(); }, diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs index 3980d2a1fef..dceef683c2d 100644 --- a/src/libstd/sync/mpsc/mpsc_queue.rs +++ b/src/libstd/sync/mpsc/mpsc_queue.rs @@ -78,7 +78,7 @@ pub struct Queue { } unsafe impl Send for Queue { } -unsafe impl Sync for Queue { } +unsafe impl Sync for Queue { } impl Node { unsafe fn new(v: Option) -> *mut Node { @@ -89,7 +89,7 @@ impl Node { } } -impl Queue { +impl Queue { /// Creates a new queue that is safe to share among multiple producers and /// one consumer. pub fn new() -> Queue { @@ -140,7 +140,7 @@ impl Queue { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for Queue { +impl Drop for Queue { fn drop(&mut self) { unsafe { let mut cur = *self.tail.get(); diff --git a/src/libstd/sync/mpsc/oneshot.rs b/src/libstd/sync/mpsc/oneshot.rs index eb45681fa62..55b2caf7c6d 100644 --- a/src/libstd/sync/mpsc/oneshot.rs +++ b/src/libstd/sync/mpsc/oneshot.rs @@ -88,7 +88,7 @@ enum MyUpgrade { GoUp(Receiver), } -impl Packet { +impl Packet { pub fn new() -> Packet { Packet { data: None, @@ -368,7 +368,7 @@ impl Packet { } #[unsafe_destructor] -impl Drop for Packet { +impl Drop for Packet { fn drop(&mut self) { assert_eq!(self.state.load(Ordering::SeqCst), DISCONNECTED); } diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs index 87b2fe8f100..820b2da15ac 100644 --- a/src/libstd/sync/mpsc/select.rs +++ b/src/libstd/sync/mpsc/select.rs @@ -134,7 +134,7 @@ impl Select { /// Creates a new handle into this receiver set for a new receiver. Note /// that this does *not* add the receiver to the receiver set, for that you /// must call the `add` method on the handle itself. - pub fn handle<'a, T: Send>(&'a self, rx: &'a Receiver) -> Handle<'a, T> { + pub fn handle<'a, T: Send + 'static>(&'a self, rx: &'a Receiver) -> Handle<'a, T> { let id = self.next_id.get(); self.next_id.set(id + 1); Handle { @@ -251,7 +251,7 @@ impl Select { fn iter(&self) -> Packets { Packets { cur: self.head } } } -impl<'rx, T: Send> Handle<'rx, T> { +impl<'rx, T: Send + 'static> Handle<'rx, T> { /// Retrieve the id of this handle. #[inline] pub fn id(&self) -> uint { self.id } @@ -322,7 +322,7 @@ impl Drop for Select { } #[unsafe_destructor] -impl<'rx, T: Send> Drop for Handle<'rx, T> { +impl<'rx, T: Send + 'static> Drop for Handle<'rx, T> { fn drop(&mut self) { unsafe { self.remove() } } diff --git a/src/libstd/sync/mpsc/shared.rs b/src/libstd/sync/mpsc/shared.rs index 6c31fb92591..3db98a44dd5 100644 --- a/src/libstd/sync/mpsc/shared.rs +++ b/src/libstd/sync/mpsc/shared.rs @@ -64,7 +64,7 @@ pub enum Failure { Disconnected, } -impl Packet { +impl Packet { // Creation of a packet *must* be followed by a call to postinit_lock // and later by inherit_blocker pub fn new() -> Packet { @@ -474,7 +474,7 @@ impl Packet { } #[unsafe_destructor] -impl Drop for Packet { +impl Drop for Packet { fn drop(&mut self) { // Note that this load is not only an assert for correctness about // disconnection, but also a proper fence before the read of diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs index f0558c33d1e..8e9a14ffafd 100644 --- a/src/libstd/sync/mpsc/spsc_queue.rs +++ b/src/libstd/sync/mpsc/spsc_queue.rs @@ -74,11 +74,11 @@ pub struct Queue { cache_subtractions: AtomicUsize, } -unsafe impl Send for Queue { } +unsafe impl Send for Queue { } -unsafe impl Sync for Queue { } +unsafe impl Sync for Queue { } -impl Node { +impl Node { fn new() -> *mut Node { unsafe { mem::transmute(box Node { @@ -89,7 +89,7 @@ impl Node { } } -impl Queue { +impl Queue { /// Creates a new queue. /// /// This is unsafe as the type system doesn't enforce a single @@ -227,7 +227,7 @@ impl Queue { } #[unsafe_destructor] -impl Drop for Queue { +impl Drop for Queue { fn drop(&mut self) { unsafe { let mut cur = *self.first.get(); diff --git a/src/libstd/sync/mpsc/stream.rs b/src/libstd/sync/mpsc/stream.rs index ab9bd6b2ed7..395819404c8 100644 --- a/src/libstd/sync/mpsc/stream.rs +++ b/src/libstd/sync/mpsc/stream.rs @@ -74,7 +74,7 @@ enum Message { GoUp(Receiver), } -impl Packet { +impl Packet { pub fn new() -> Packet { Packet { queue: unsafe { spsc::Queue::new(128) }, @@ -472,7 +472,7 @@ impl Packet { } #[unsafe_destructor] -impl Drop for Packet { +impl Drop for Packet { fn drop(&mut self) { // Note that this load is not only an assert for correctness about // disconnection, but also a proper fence before the read of diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs index da3ce51a652..ae96a2491dc 100644 --- a/src/libstd/sync/mpsc/sync.rs +++ b/src/libstd/sync/mpsc/sync.rs @@ -55,9 +55,9 @@ pub struct Packet { lock: Mutex>, } -unsafe impl Send for Packet { } +unsafe impl Send for Packet { } -unsafe impl Sync for Packet { } +unsafe impl Sync for Packet { } struct State { disconnected: bool, // Is the channel disconnected yet? @@ -75,7 +75,7 @@ struct State { canceled: Option<&'static mut bool>, } -unsafe impl Send for State {} +unsafe impl Send for State {} /// Possible flavors of threads who can be blocked on this channel. enum Blocker { @@ -113,7 +113,7 @@ pub enum Failure { /// Atomically blocks the current thread, placing it into `slot`, unlocking `lock` /// in the meantime. This re-locks the mutex upon returning. -fn wait<'a, 'b, T: Send>(lock: &'a Mutex>, +fn wait<'a, 'b, T: Send + 'static>(lock: &'a Mutex>, mut guard: MutexGuard<'b, State>, f: fn(SignalToken) -> Blocker) -> MutexGuard<'a, State> @@ -136,7 +136,7 @@ fn wakeup(token: SignalToken, guard: MutexGuard>) { token.signal(); } -impl Packet { +impl Packet { pub fn new(cap: uint) -> Packet { Packet { channels: AtomicUsize::new(1), @@ -412,7 +412,7 @@ impl Packet { } #[unsafe_destructor] -impl Drop for Packet { +impl Drop for Packet { fn drop(&mut self) { assert_eq!(self.channels.load(Ordering::SeqCst), 0); let mut guard = self.lock.lock().unwrap(); diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 74692c1273c..7e27f13f515 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -120,9 +120,9 @@ pub struct Mutex { data: UnsafeCell, } -unsafe impl Send for Mutex { } +unsafe impl Send for Mutex { } -unsafe impl Sync for Mutex { } +unsafe impl Sync for Mutex { } /// The static mutex type is provided to allow for static allocation of mutexes. /// @@ -180,7 +180,7 @@ pub const MUTEX_INIT: StaticMutex = StaticMutex { poison: poison::FLAG_INIT, }; -impl Mutex { +impl Mutex { /// Creates a new mutex in an unlocked state ready for use. #[stable(feature = "rust1", since = "1.0.0")] pub fn new(t: T) -> Mutex { @@ -243,7 +243,7 @@ impl Mutex { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for Mutex { +impl Drop for Mutex { fn drop(&mut self) { // This is actually safe b/c we know that there is no further usage of // this mutex (it's up to the user to arrange for a mutex to get diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs index 684a46fd6ff..831c4d315b1 100644 --- a/src/libstd/sync/task_pool.rs +++ b/src/libstd/sync/task_pool.rs @@ -24,12 +24,12 @@ use thread::Thread; use thunk::Thunk; struct Sentinel<'a> { - jobs: &'a Arc>>, + jobs: &'a Arc>>>, active: bool } impl<'a> Sentinel<'a> { - fn new(jobs: &Arc>>) -> Sentinel { + fn new(jobs: &'a Arc>>>) -> Sentinel<'a> { Sentinel { jobs: jobs, active: true @@ -80,7 +80,7 @@ pub struct TaskPool { // // This is the only such Sender, so when it is dropped all subthreads will // quit. - jobs: Sender + jobs: Sender> } impl TaskPool { @@ -105,13 +105,13 @@ impl TaskPool { /// Executes the function `job` on a thread in the pool. pub fn execute(&self, job: F) - where F : FnOnce(), F : Send + where F : FnOnce(), F : Send + 'static { self.jobs.send(Thunk::new(job)).unwrap(); } } -fn spawn_in_pool(jobs: Arc>>) { +fn spawn_in_pool(jobs: Arc>>>) { Thread::spawn(move || { // Will spawn a new thread on panic unless it is cancelled. let sentinel = Sentinel::new(&jobs); diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index 255f474d4f4..ad2f733165e 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -81,7 +81,7 @@ impl Helper { /// /// This function is safe to be called many times. pub fn boot(&'static self, f: F, helper: fn(helper_signal::signal, Receiver, T)) where - T: Send, + T: Send + 'static, F: FnOnce() -> T, { unsafe { diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index cc9d7492441..3b758c83980 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -175,9 +175,9 @@ pub struct Builder { // The size of the stack for the spawned thread stack_size: Option, // Thread-local stdout - stdout: Option>, + stdout: Option>, // Thread-local stderr - stderr: Option>, + stderr: Option>, } impl Builder { @@ -211,7 +211,7 @@ impl Builder { /// Redirect thread-local stdout. #[unstable(feature = "std_misc", reason = "Will likely go away after proc removal")] - pub fn stdout(mut self, stdout: Box) -> Builder { + pub fn stdout(mut self, stdout: Box) -> Builder { self.stdout = Some(stdout); self } @@ -219,7 +219,7 @@ impl Builder { /// Redirect thread-local stderr. #[unstable(feature = "std_misc", reason = "Will likely go away after proc removal")] - pub fn stderr(mut self, stderr: Box) -> Builder { + pub fn stderr(mut self, stderr: Box) -> Builder { self.stderr = Some(stderr); self } @@ -469,11 +469,11 @@ impl thread_info::NewThread for Thread { /// /// A thread that completes without panicking is considered to exit successfully. #[stable(feature = "rust1", since = "1.0.0")] -pub type Result = ::result::Result>; +pub type Result = ::result::Result>; struct Packet(Arc>>>); -unsafe impl Send for Packet {} +unsafe impl Send for Packet {} unsafe impl Sync for Packet {} /// An RAII-style guard that will block until thread termination when dropped. @@ -515,7 +515,7 @@ impl<'a, T: Send + 'a> JoinGuard<'a, T> { } } -impl JoinGuard<'static, T> { +impl JoinGuard<'static, T> { /// Detaches the child thread, allowing it to outlive its parent. #[unstable(feature = "std_misc", reason = "unsure whether this API imposes limitations elsewhere")] diff --git a/src/libstd/thunk.rs b/src/libstd/thunk.rs index 0831242f954..1412dbd70b9 100644 --- a/src/libstd/thunk.rs +++ b/src/libstd/thunk.rs @@ -16,21 +16,24 @@ use alloc::boxed::Box; use core::marker::Send; use core::ops::FnOnce; -pub struct Thunk { - invoke: Box+Send> +pub struct Thunk<'a, A=(),R=()> { + #[cfg(stage0)] // // SNAP ac134f7 remove after stage0 + invoke: Box+Send>, + #[cfg(not(stage0))] + invoke: Box+Send + 'a>, } -impl Thunk<(),R> { - pub fn new(func: F) -> Thunk<(),R> - where F : FnOnce() -> R, F : Send +impl<'a, R> Thunk<'a,(),R> { + pub fn new(func: F) -> Thunk<'a,(),R> + where F : FnOnce() -> R, F : Send + 'a { Thunk::with_arg(move|()| func()) } } -impl Thunk { - pub fn with_arg(func: F) -> Thunk - where F : FnOnce(A) -> R, F : Send +impl<'a,A,R> Thunk<'a,A,R> { + pub fn with_arg(func: F) -> Thunk<'a,A,R> + where F : FnOnce(A) -> R, F : Send + 'a { Thunk { invoke: box func -- cgit 1.4.1-3-g733a5 From adfcd93f0c3b624399934558f63d945b7b6b663a Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Tue, 17 Feb 2015 23:09:14 +1100 Subject: Add missing marker to std::thread::JoinGuard. The lifetime was previously, incorrectly unconstrained. --- src/libstd/thread.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index 3b758c83980..c662a1dafa1 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -151,7 +151,7 @@ use any::Any; use boxed::Box; use cell::UnsafeCell; use clone::Clone; -use marker::{Send, Sync}; +use marker::{Send, Sync, CovariantType}; use ops::{Drop, FnOnce}; use option::Option::{self, Some, None}; use result::Result::{Err, Ok}; @@ -255,6 +255,7 @@ impl Builder { joined: false, packet: my_packet, thread: thread, + _marker: CovariantType, } } @@ -487,6 +488,7 @@ pub struct JoinGuard<'a, T: 'a> { thread: Thread, joined: bool, packet: Packet, + _marker: CovariantType<&'a T>, } #[stable(feature = "rust1", since = "1.0.0")] -- cgit 1.4.1-3-g733a5 From 7a14f4994eb4527a38d02c61fa83822df02f7b5d Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Tue, 17 Feb 2015 23:48:32 +1100 Subject: Update tests for the Send - 'static change. --- src/libstd/old_io/net/pipe.rs | 2 +- src/libstd/process.rs | 2 +- src/libstd/thread.rs | 4 +- src/test/auxiliary/cci_capture_clause.rs | 2 +- src/test/bench/shootout-reverse-complement.rs | 19 ++--- src/test/bench/shootout-spectralnorm.rs | 18 ++--- src/test/compile-fail/builtin-superkinds-simple.rs | 4 +- src/test/compile-fail/coherence-impls-builtin.rs | 9 ++- src/test/compile-fail/kindck-impl-type-params.rs | 2 +- src/test/compile-fail/kindck-send-object.rs | 4 +- src/test/compile-fail/kindck-send-object1.rs | 8 +-- src/test/compile-fail/kindck-send-object2.rs | 4 +- src/test/compile-fail/kindck-send-owned.rs | 4 +- .../compile-fail/kindck-send-region-pointers.rs | 34 --------- src/test/compile-fail/regions-bounded-by-send.rs | 83 ---------------------- .../regions-pattern-typing-issue-19552.rs | 4 +- src/test/compile-fail/trait-bounds-cant-coerce.rs | 2 +- .../builtin-superkinds-capabilities-transitive.rs | 2 +- .../run-pass/builtin-superkinds-capabilities-xc.rs | 2 +- .../run-pass/builtin-superkinds-capabilities.rs | 2 +- src/test/run-pass/builtin-superkinds-self-type.rs | 4 +- src/test/run-pass/issue-18188.rs | 10 +-- src/test/run-pass/issue-21058.rs | 4 +- src/test/run-pass/issue-2190-1.rs | 4 +- src/test/run-pass/send-type-inference.rs | 2 +- 25 files changed, 52 insertions(+), 183 deletions(-) delete mode 100644 src/test/compile-fail/kindck-send-region-pointers.rs delete mode 100644 src/test/compile-fail/regions-bounded-by-send.rs (limited to 'src/libstd') diff --git a/src/libstd/old_io/net/pipe.rs b/src/libstd/old_io/net/pipe.rs index 8c4a10a55d4..6dd73273122 100644 --- a/src/libstd/old_io/net/pipe.rs +++ b/src/libstd/old_io/net/pipe.rs @@ -287,7 +287,7 @@ mod tests { pub fn smalltest(server: F, client: G) where F : FnOnce(UnixStream), F : Send, - G : FnOnce(UnixStream), G : Send + G : FnOnce(UnixStream), G : Send + 'static { let path1 = next_test_unix(); let path2 = path1.clone(); diff --git a/src/libstd/process.rs b/src/libstd/process.rs index d2b98ec8939..05b5e47103f 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -458,7 +458,7 @@ impl Child { /// the parent waits for the child to exit. pub fn wait_with_output(mut self) -> io::Result { drop(self.stdin.take()); - fn read(stream: Option) -> Receiver>> { + fn read(stream: Option) -> Receiver>> { let (tx, rx) = channel(); match stream { Some(stream) => { diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index c662a1dafa1..d5dcdca5fbf 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -630,7 +630,7 @@ mod test { rx.recv().unwrap(); } - fn avoid_copying_the_body(spawnfn: F) where F: FnOnce(Thunk) { + fn avoid_copying_the_body(spawnfn: F) where F: FnOnce(Thunk<'static>) { let (tx, rx) = channel::(); let x = box 1; @@ -677,7 +677,7 @@ mod test { // (well, it would if the constant were 8000+ - I lowered it to be more // valgrind-friendly. try this at home, instead..!) static GENERATIONS: uint = 16; - fn child_no(x: uint) -> Thunk { + fn child_no(x: uint) -> Thunk<'static> { return Thunk::new(move|| { if x < GENERATIONS { Thread::spawn(move|| child_no(x+1).invoke(())); diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/auxiliary/cci_capture_clause.rs index 673c38697b7..2053f635c44 100644 --- a/src/test/auxiliary/cci_capture_clause.rs +++ b/src/test/auxiliary/cci_capture_clause.rs @@ -11,7 +11,7 @@ use std::thread::Thread; use std::sync::mpsc::{Receiver, channel}; -pub fn foo(x: T) -> Receiver { +pub fn foo(x: T) -> Receiver { let (tx, rx) = channel(); Thread::spawn(move|| { tx.send(x.clone()); diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs index 94438319954..469923d80b6 100644 --- a/src/test/bench/shootout-reverse-complement.rs +++ b/src/test/bench/shootout-reverse-complement.rs @@ -229,21 +229,12 @@ unsafe impl Send for Racy {} /// Executes a closure in parallel over the given iterator over mutable slice. /// The closure `f` is run in parallel with an element of `iter`. -fn parallel<'a, I, T, F>(iter: I, f: F) - where T: 'a+Send + Sync, - I: Iterator, - F: Fn(&mut [T]) + Sync { - use std::mem; - use std::raw::Repr; - - iter.map(|chunk| { - // Need to convert `f` and `chunk` to something that can cross the task - // boundary. - let f = Racy(&f as *const F as *const uint); - let raw = Racy(chunk.repr()); +fn parallel<'a, I: Iterator, F>(iter: I, ref f: F) + where I::Item: Send + 'a, + F: Fn(I::Item) + Sync + 'a { + iter.map(|x| { Thread::scoped(move|| { - let f = f.0 as *const F; - unsafe { (*f)(mem::transmute(raw.0)) } + f(x) }) }).collect::>(); } diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index 8356df8d8a1..0c77120e506 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -112,26 +112,16 @@ fn dot(v: &[f64], u: &[f64]) -> f64 { } -struct Racy(T); - -unsafe impl Send for Racy {} - // Executes a closure in parallel over the given mutable slice. The closure `f` // is run in parallel and yielded the starting index within `v` as well as a // sub-slice of `v`. -fn parallel(v: &mut [T], f: F) - where T: Send + Sync, - F: Fn(uint, &mut [T]) + Sync { +fn parallel<'a,T, F>(v: &mut [T], ref f: F) + where T: Send + Sync + 'a, + F: Fn(uint, &mut [T]) + Sync + 'a { let size = v.len() / os::num_cpus() + 1; - v.chunks_mut(size).enumerate().map(|(i, chunk)| { - // Need to convert `f` and `chunk` to something that can cross the task - // boundary. - let f = Racy(&f as *const _ as *const uint); - let raw = Racy(chunk.repr()); Thread::scoped(move|| { - let f = f.0 as *const F; - unsafe { (*f)(i * size, mem::transmute(raw.0)) } + f(i * size, chunk) }) }).collect::>(); } diff --git a/src/test/compile-fail/builtin-superkinds-simple.rs b/src/test/compile-fail/builtin-superkinds-simple.rs index c7b75ade555..c3fb6a1be87 100644 --- a/src/test/compile-fail/builtin-superkinds-simple.rs +++ b/src/test/compile-fail/builtin-superkinds-simple.rs @@ -13,7 +13,7 @@ trait Foo : Send { } -impl <'a> Foo for &'a mut () { } -//~^ ERROR the type `&'a mut ()` does not fulfill the required lifetime +impl Foo for std::rc::Rc { } +//~^ ERROR the trait `core::marker::Send` is not implemented fn main() { } diff --git a/src/test/compile-fail/coherence-impls-builtin.rs b/src/test/compile-fail/coherence-impls-builtin.rs index 2ca288b60a3..38730d241f6 100644 --- a/src/test/compile-fail/coherence-impls-builtin.rs +++ b/src/test/compile-fail/coherence-impls-builtin.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(optin_builtin_traits)] + use std::marker::Send; enum TestE { @@ -16,18 +18,21 @@ enum TestE { struct MyType; +struct NotSync; +impl !Sync for NotSync {} + unsafe impl Send for TestE {} unsafe impl Send for MyType {} unsafe impl Send for (MyType, MyType) {} //~^ ERROR builtin traits can only be implemented on structs or enums -unsafe impl Send for &'static MyType {} +unsafe impl Send for &'static NotSync {} //~^ ERROR builtin traits can only be implemented on structs or enums unsafe impl Send for [MyType] {} //~^ ERROR builtin traits can only be implemented on structs or enums -unsafe impl Send for &'static [MyType] {} +unsafe impl Send for &'static [NotSync] {} //~^ ERROR builtin traits can only be implemented on structs or enums fn is_send() {} diff --git a/src/test/compile-fail/kindck-impl-type-params.rs b/src/test/compile-fail/kindck-impl-type-params.rs index de7639c6213..d5276efa8be 100644 --- a/src/test/compile-fail/kindck-impl-type-params.rs +++ b/src/test/compile-fail/kindck-impl-type-params.rs @@ -17,7 +17,7 @@ struct S; trait Gettable {} -impl Gettable for S {} +impl Gettable for S {} fn f(val: T) { let t: S = S; diff --git a/src/test/compile-fail/kindck-send-object.rs b/src/test/compile-fail/kindck-send-object.rs index 7984b3b32c2..570f7ad7fe3 100644 --- a/src/test/compile-fail/kindck-send-object.rs +++ b/src/test/compile-fail/kindck-send-object.rs @@ -20,7 +20,7 @@ trait Message : Send { } fn object_ref_with_static_bound_not_ok() { assert_send::<&'static (Dummy+'static)>(); - //~^ ERROR the trait `core::marker::Send` is not implemented + //~^ ERROR the trait `core::marker::Sync` is not implemented } fn box_object_with_no_bound_not_ok<'a>() { @@ -28,7 +28,7 @@ fn box_object_with_no_bound_not_ok<'a>() { } fn object_with_send_bound_ok() { - assert_send::<&'static (Dummy+Send)>(); + assert_send::<&'static (Dummy+Sync)>(); assert_send::>(); } diff --git a/src/test/compile-fail/kindck-send-object1.rs b/src/test/compile-fail/kindck-send-object1.rs index 3d47d33d7c3..48d5215b708 100644 --- a/src/test/compile-fail/kindck-send-object1.rs +++ b/src/test/compile-fail/kindck-send-object1.rs @@ -12,22 +12,22 @@ // is broken into two parts because some errors occur in distinct // phases in the compiler. See kindck-send-object2.rs as well! -fn assert_send() { } +fn assert_send() { } trait Dummy { } // careful with object types, who knows what they close over... fn test51<'a>() { assert_send::<&'a Dummy>(); - //~^ ERROR the trait `core::marker::Send` is not implemented + //~^ ERROR the trait `core::marker::Sync` is not implemented } fn test52<'a>() { - assert_send::<&'a (Dummy+Send)>(); + assert_send::<&'a (Dummy+Sync)>(); //~^ ERROR does not fulfill the required lifetime } // ...unless they are properly bounded fn test60() { - assert_send::<&'static (Dummy+Send)>(); + assert_send::<&'static (Dummy+Sync)>(); } fn test61() { assert_send::>(); diff --git a/src/test/compile-fail/kindck-send-object2.rs b/src/test/compile-fail/kindck-send-object2.rs index 75bae09b37f..d3d166e2a69 100644 --- a/src/test/compile-fail/kindck-send-object2.rs +++ b/src/test/compile-fail/kindck-send-object2.rs @@ -14,7 +14,7 @@ fn assert_send() { } trait Dummy { } fn test50() { - assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Send` is not implemented + assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Sync` is not implemented } fn test53() { @@ -23,7 +23,7 @@ fn test53() { // ...unless they are properly bounded fn test60() { - assert_send::<&'static (Dummy+Send)>(); + assert_send::<&'static (Dummy+Sync)>(); } fn test61() { assert_send::>(); diff --git a/src/test/compile-fail/kindck-send-owned.rs b/src/test/compile-fail/kindck-send-owned.rs index 266b6156656..406711902a5 100644 --- a/src/test/compile-fail/kindck-send-owned.rs +++ b/src/test/compile-fail/kindck-send-owned.rs @@ -18,8 +18,8 @@ fn test31() { assert_send::(); } fn test32() { assert_send:: >(); } // but not if they own a bad thing -fn test40<'a>(_: &'a isize) { - assert_send::>(); //~ ERROR does not fulfill the required lifetime +fn test40() { + assert_send::>(); //~ ERROR `core::marker::Send` is not implemented } fn main() { } diff --git a/src/test/compile-fail/kindck-send-region-pointers.rs b/src/test/compile-fail/kindck-send-region-pointers.rs deleted file mode 100644 index e2a5b0678a6..00000000000 --- a/src/test/compile-fail/kindck-send-region-pointers.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that borrowed pointers are not sendable unless 'static. - -fn assert_send() { } - -// lifetime pointers with 'static lifetime are ok -fn test01() { assert_send::<&'static isize>(); } -fn test02() { assert_send::<&'static str>(); } -fn test03() { assert_send::<&'static [isize]>(); } - -// whether or not they are mutable -fn test10() { assert_send::<&'static mut isize>(); } - -// otherwise lifetime pointers are not ok -fn test20<'a>(_: &'a isize) { - assert_send::<&'a isize>(); //~ ERROR does not fulfill the required lifetime -} -fn test21<'a>(_: &'a isize) { - assert_send::<&'a str>(); //~ ERROR does not fulfill the required lifetime -} -fn test22<'a>(_: &'a isize) { - assert_send::<&'a [isize]>(); //~ ERROR does not fulfill the required lifetime -} - -fn main() { } diff --git a/src/test/compile-fail/regions-bounded-by-send.rs b/src/test/compile-fail/regions-bounded-by-send.rs deleted file mode 100644 index 71254e15d32..00000000000 --- a/src/test/compile-fail/regions-bounded-by-send.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test which of the builtin types are considered sendable. The tests -// in this file all test region bound and lifetime violations that are -// detected during type check. - -extern crate core; -use core::ptr::Unique; - -fn assert_send() { } -trait Dummy:Send { } - -// lifetime pointers with 'static lifetime are ok - -fn static_lifime_ok<'a,T,U:Send>(_: &'a isize) { - assert_send::<&'static isize>(); - assert_send::<&'static str>(); - assert_send::<&'static [isize]>(); - - // whether or not they are mutable - assert_send::<&'static mut isize>(); -} - -// otherwise lifetime pointers are not ok - -fn param_not_ok<'a>(x: &'a isize) { - assert_send::<&'a isize>(); //~ ERROR does not fulfill the required lifetime -} - -fn param_not_ok1<'a>(_: &'a isize) { - assert_send::<&'a str>(); //~ ERROR does not fulfill the required lifetime -} - -fn param_not_ok2<'a>(_: &'a isize) { - assert_send::<&'a [isize]>(); //~ ERROR does not fulfill the required lifetime -} - -// boxes are ok - -fn box_ok() { - assert_send::>(); - assert_send::(); - assert_send::>(); -} - -// but not if they own a bad thing - -fn box_with_region_not_ok<'a>() { - assert_send::>(); //~ ERROR does not fulfill the required lifetime -} - -// objects with insufficient bounds no ok - -fn object_with_random_bound_not_ok<'a>() { - assert_send::<&'a (Dummy+'a)>(); - //~^ ERROR reference has a longer lifetime -} - -fn object_with_send_bound_not_ok<'a>() { - assert_send::<&'a (Dummy+Send)>(); - //~^ ERROR does not fulfill the required lifetime -} - -// unsafe pointers are ok unless they point at unsendable things - -struct UniqueUnsafePtr(Unique<*const isize>); - -unsafe impl Send for UniqueUnsafePtr {} - -fn unsafe_ok1<'a>(_: &'a isize) { - assert_send::(); -} - -fn main() { -} diff --git a/src/test/compile-fail/regions-pattern-typing-issue-19552.rs b/src/test/compile-fail/regions-pattern-typing-issue-19552.rs index 57ea607cbf6..3401dd1becd 100644 --- a/src/test/compile-fail/regions-pattern-typing-issue-19552.rs +++ b/src/test/compile-fail/regions-pattern-typing-issue-19552.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn assert_send(_t: T) {} +fn assert_static(_t: T) {} fn main() { let line = String::new(); match [&*line] { //~ ERROR `line` does not live long enough - [ word ] => { assert_send(word); } + [ word ] => { assert_static(word); } } } diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs index 89e89cf8246..79174552ae0 100644 --- a/src/test/compile-fail/trait-bounds-cant-coerce.rs +++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs @@ -22,7 +22,7 @@ fn c(x: Box) { fn d(x: Box) { a(x); //~ ERROR mismatched types //~| expected `Box` - //~| found `Box` + //~| found `Box` //~| expected bounds `Send` //~| found no bounds } diff --git a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs index 3df9dd25d86..379ac12a954 100644 --- a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs +++ b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs @@ -22,7 +22,7 @@ trait Foo : Bar { } impl Foo for T { } impl Bar for T { } -fn foo(val: T, chan: Sender) { +fn foo(val: T, chan: Sender) { chan.send(val).unwrap(); } diff --git a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs index 52b826393e9..cd019c21a3d 100644 --- a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs +++ b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs @@ -25,7 +25,7 @@ struct X(T); impl RequiresShare for X { } impl RequiresRequiresShareAndSend for X { } -fn foo(val: T, chan: Sender) { +fn foo(val: T, chan: Sender) { chan.send(val).unwrap(); } diff --git a/src/test/run-pass/builtin-superkinds-capabilities.rs b/src/test/run-pass/builtin-superkinds-capabilities.rs index 034e5ff2d3a..dc61508eec4 100644 --- a/src/test/run-pass/builtin-superkinds-capabilities.rs +++ b/src/test/run-pass/builtin-superkinds-capabilities.rs @@ -18,7 +18,7 @@ trait Foo : Send { } impl Foo for T { } -fn foo(val: T, chan: Sender) { +fn foo(val: T, chan: Sender) { chan.send(val).unwrap(); } diff --git a/src/test/run-pass/builtin-superkinds-self-type.rs b/src/test/run-pass/builtin-superkinds-self-type.rs index 1b3070ba3b0..1d05a7baa53 100644 --- a/src/test/run-pass/builtin-superkinds-self-type.rs +++ b/src/test/run-pass/builtin-superkinds-self-type.rs @@ -13,13 +13,13 @@ use std::sync::mpsc::{Sender, channel}; -trait Foo : Send + Sized { +trait Foo : Send + Sized + 'static { fn foo(self, tx: Sender) { tx.send(self).unwrap(); } } -impl Foo for T { } +impl Foo for T { } pub fn main() { let (tx, rx) = channel(); diff --git a/src/test/run-pass/issue-18188.rs b/src/test/run-pass/issue-18188.rs index 7a5a86822af..a4b09eb08e0 100644 --- a/src/test/run-pass/issue-18188.rs +++ b/src/test/run-pass/issue-18188.rs @@ -14,12 +14,12 @@ use std::thunk::Thunk; pub trait Promisable: Send + Sync {} impl Promisable for T {} -pub fn propagate(action: F) -> Thunk, Result> +pub fn propagate<'a, T, E, F, G>(action: F) -> Thunk<'a,Result, Result> where - T: Promisable + Clone, - E: Promisable + Clone, - F: FnOnce(&T) -> Result + Send, - G: FnOnce(Result) -> Result { + T: Promisable + Clone + 'a, + E: Promisable + Clone + 'a, + F: FnOnce(&T) -> Result + Send + 'a, + G: FnOnce(Result) -> Result + 'a { Thunk::with_arg(move |result: Result| { match result { Ok(ref t) => action(t), diff --git a/src/test/run-pass/issue-21058.rs b/src/test/run-pass/issue-21058.rs index 044d43a57fa..3cdd57aed5a 100644 --- a/src/test/run-pass/issue-21058.rs +++ b/src/test/run-pass/issue-21058.rs @@ -14,7 +14,7 @@ struct DST { a: u32, b: str } fn main() { // get_tydesc should support unsized types - assert!(unsafe {( + assert_eq!(unsafe {( // Slice (*std::intrinsics::get_tydesc::<[u8]>()).name, // str @@ -25,5 +25,5 @@ fn main() { (*std::intrinsics::get_tydesc::()).name, // DST (*std::intrinsics::get_tydesc::()).name - )} == ("[u8]", "str", "core::marker::Copy + 'static", "NT", "DST")); + )}, ("[u8]", "str", "core::marker::Copy", "NT", "DST")); } diff --git a/src/test/run-pass/issue-2190-1.rs b/src/test/run-pass/issue-2190-1.rs index 810bf385d7e..3025741694f 100644 --- a/src/test/run-pass/issue-2190-1.rs +++ b/src/test/run-pass/issue-2190-1.rs @@ -13,11 +13,11 @@ use std::thunk::Thunk; static generations: uint = 1024+256+128+49; -fn spawn(f: Thunk) { +fn spawn(f: Thunk<'static>) { Builder::new().stack_size(32 * 1024).spawn(move|| f.invoke(())); } -fn child_no(x: uint) -> Thunk { +fn child_no(x: uint) -> Thunk<'static> { Thunk::new(move|| { if x < generations { spawn(child_no(x+1)); diff --git a/src/test/run-pass/send-type-inference.rs b/src/test/run-pass/send-type-inference.rs index ae992a0a358..60093803f0b 100644 --- a/src/test/run-pass/send-type-inference.rs +++ b/src/test/run-pass/send-type-inference.rs @@ -16,7 +16,7 @@ struct Command { val: V } -fn cache_server(mut tx: Sender>>) { +fn cache_server(mut tx: Sender>>) { let (tx1, _rx) = channel(); tx.send(tx1); } -- cgit 1.4.1-3-g733a5