about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/c_vec.rs11
-rw-r--r--src/libstd/io/fs.rs3
-rw-r--r--src/libstd/io/net/tcp.rs11
-rw-r--r--src/libstd/io/net/udp.rs5
-rw-r--r--src/libstd/io/net/unix.rs13
-rw-r--r--src/libstd/io/pipe.rs4
-rw-r--r--src/libstd/io/process.rs2
-rw-r--r--src/libstd/io/stdio.rs21
-rw-r--r--src/libstd/io/timer.rs5
-rw-r--r--src/libstd/local_data.rs11
-rw-r--r--src/libstd/repr.rs2
-rw-r--r--src/libstd/rt/at_exit_imp.rs5
-rw-r--r--src/libstd/rt/mod.rs5
-rw-r--r--src/libstd/rt/rtio.rs159
-rw-r--r--src/libstd/rt/task.rs15
-rw-r--r--src/libstd/rt/thread.rs16
-rw-r--r--src/libstd/rt/unwind.rs6
-rw-r--r--src/libstd/task.rs48
-rw-r--r--src/libstd/unstable/mod.rs2
19 files changed, 177 insertions, 167 deletions
diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs
index 00d250a5fc7..a6cc4c64d20 100644
--- a/src/libstd/c_vec.rs
+++ b/src/libstd/c_vec.rs
@@ -35,17 +35,18 @@
 
 use cast;
 use container::Container;
-use ptr;
+use kinds::Send;
+use ops::Drop;
+use option::{Option, Some, None};
 use ptr::RawPtr;
+use ptr;
 use raw;
-use option::{Option, Some, None};
-use ops::Drop;
 
 /// The type representing a foreign chunk of memory
 pub struct CVec<T> {
     priv base: *mut T,
     priv len: uint,
-    priv dtor: Option<proc()>,
+    priv dtor: Option<proc:Send()>,
 }
 
 #[unsafe_destructor]
@@ -89,7 +90,7 @@ impl<T> CVec<T> {
     /// * dtor - A proc to run when the value is destructed, useful
     ///          for freeing the buffer, etc.
     pub unsafe fn new_with_dtor(base: *mut T, len: uint,
-                                dtor: proc()) -> CVec<T> {
+                                dtor: proc:Send()) -> CVec<T> {
         assert!(base != ptr::mut_null());
         CVec {
             base: base,
diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs
index e66aa8c0046..020f493e24b 100644
--- a/src/libstd/io/fs.rs
+++ b/src/libstd/io/fs.rs
@@ -53,6 +53,7 @@ use c_str::ToCStr;
 use clone::Clone;
 use container::Container;
 use iter::Iterator;
+use kinds::Send;
 use super::{Reader, Writer, Seek};
 use super::{SeekStyle, Read, Write, Open, IoError, Truncate,
             FileMode, FileAccess, FileStat, IoResult, FilePermission};
@@ -77,7 +78,7 @@ use vec::Vec;
 /// configured at creation time, via the `FileAccess` parameter to
 /// `File::open_mode()`.
 pub struct File {
-    priv fd: ~RtioFileStream,
+    priv fd: ~RtioFileStream:Send,
     priv path: Path,
     priv last_nread: int,
 }
diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs
index 7b1dd114d34..e343fdcd325 100644
--- a/src/libstd/io/net/tcp.rs
+++ b/src/libstd/io/net/tcp.rs
@@ -20,9 +20,10 @@
 #[deny(missing_doc)];
 
 use clone::Clone;
+use io::IoResult;
 use io::net::ip::SocketAddr;
 use io::{Reader, Writer, Listener, Acceptor};
-use io::IoResult;
+use kinds::Send;
 use rt::rtio::{IoFactory, LocalIo, RtioSocket, RtioTcpListener};
 use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
 
@@ -45,11 +46,11 @@ use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
 /// drop(stream); // close the connection
 /// ```
 pub struct TcpStream {
-    priv obj: ~RtioTcpStream
+    priv obj: ~RtioTcpStream:Send
 }
 
 impl TcpStream {
-    fn new(s: ~RtioTcpStream) -> TcpStream {
+    fn new(s: ~RtioTcpStream:Send) -> TcpStream {
         TcpStream { obj: s }
     }
 
@@ -127,7 +128,7 @@ impl Writer for TcpStream {
 /// # }
 /// ```
 pub struct TcpListener {
-    priv obj: ~RtioTcpListener
+    priv obj: ~RtioTcpListener:Send
 }
 
 impl TcpListener {
@@ -160,7 +161,7 @@ impl Listener<TcpStream, TcpAcceptor> for TcpListener {
 /// a `TcpListener`'s `listen` method, and this object can be used to accept new
 /// `TcpStream` instances.
 pub struct TcpAcceptor {
-    priv obj: ~RtioTcpAcceptor
+    priv obj: ~RtioTcpAcceptor:Send
 }
 
 impl Acceptor<TcpStream> for TcpAcceptor {
diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs
index 95241813257..8169fc1a917 100644
--- a/src/libstd/io/net/udp.rs
+++ b/src/libstd/io/net/udp.rs
@@ -16,9 +16,10 @@
 //! datagram protocol.
 
 use clone::Clone;
-use result::{Ok, Err};
 use io::net::ip::SocketAddr;
 use io::{Reader, Writer, IoResult};
+use kinds::Send;
+use result::{Ok, Err};
 use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, LocalIo};
 
 /// A User Datagram Protocol socket.
@@ -53,7 +54,7 @@ use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, LocalIo};
 /// drop(socket); // close the socket
 /// ```
 pub struct UdpSocket {
-    priv obj: ~RtioUdpSocket
+    priv obj: ~RtioUdpSocket:Send
 }
 
 impl UdpSocket {
diff --git a/src/libstd/io/net/unix.rs b/src/libstd/io/net/unix.rs
index 9f04317a5c8..1a020f9a820 100644
--- a/src/libstd/io/net/unix.rs
+++ b/src/libstd/io/net/unix.rs
@@ -28,10 +28,11 @@ use prelude::*;
 
 use c_str::ToCStr;
 use clone::Clone;
-use rt::rtio::{IoFactory, LocalIo, RtioUnixListener};
-use rt::rtio::{RtioUnixAcceptor, RtioPipe};
 use io::pipe::PipeStream;
 use io::{Listener, Acceptor, Reader, Writer, IoResult};
+use kinds::Send;
+use rt::rtio::{IoFactory, LocalIo, RtioUnixListener};
+use rt::rtio::{RtioUnixAcceptor, RtioPipe};
 
 /// A stream which communicates over a named pipe.
 pub struct UnixStream {
@@ -39,7 +40,7 @@ pub struct UnixStream {
 }
 
 impl UnixStream {
-    fn new(obj: ~RtioPipe) -> UnixStream {
+    fn new(obj: ~RtioPipe:Send) -> UnixStream {
         UnixStream { obj: PipeStream::new(obj) }
     }
 
@@ -82,7 +83,7 @@ impl Writer for UnixStream {
 /// A value that can listen for incoming named pipe connection requests.
 pub struct UnixListener {
     /// The internal, opaque runtime Unix listener.
-    priv obj: ~RtioUnixListener,
+    priv obj: ~RtioUnixListener:Send,
 }
 
 impl UnixListener {
@@ -124,7 +125,7 @@ impl Listener<UnixStream, UnixAcceptor> for UnixListener {
 /// A value that can accept named pipe connections, returned from `listen()`.
 pub struct UnixAcceptor {
     /// The internal, opaque runtime Unix acceptor.
-    priv obj: ~RtioUnixAcceptor,
+    priv obj: ~RtioUnixAcceptor:Send,
 }
 
 impl Acceptor<UnixStream> for UnixAcceptor {
@@ -140,7 +141,7 @@ mod tests {
     use io::*;
     use io::test::*;
 
-    pub fn smalltest(server: proc(UnixStream), client: proc(UnixStream)) {
+    pub fn smalltest(server: proc:Send(UnixStream), client: proc:Send(UnixStream)) {
         let path1 = next_test_unix();
         let path2 = path1.clone();
 
diff --git a/src/libstd/io/pipe.rs b/src/libstd/io/pipe.rs
index 9984a3e5cdf..fbf79b19445 100644
--- a/src/libstd/io/pipe.rs
+++ b/src/libstd/io/pipe.rs
@@ -23,7 +23,7 @@ use rt::rtio::{RtioPipe, LocalIo};
 /// A synchronous, in-memory pipe.
 pub struct PipeStream {
     /// The internal, opaque runtime pipe object.
-    priv obj: ~RtioPipe,
+    priv obj: ~RtioPipe:Send,
 }
 
 impl PipeStream {
@@ -51,7 +51,7 @@ impl PipeStream {
     }
 
     #[doc(hidden)]
-    pub fn new(inner: ~RtioPipe) -> PipeStream {
+    pub fn new(inner: ~RtioPipe:Send) -> PipeStream {
         PipeStream { obj: inner }
     }
 }
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index de7b26d5ff4..2da79eba7bc 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -53,7 +53,7 @@ use rt::rtio::{RtioProcess, IoFactory, LocalIo};
 /// assert!(child.wait().success());
 /// ```
 pub struct Process {
-    priv handle: ~RtioProcess,
+    priv handle: ~RtioProcess:Send,
 
     /// Handle to the child's stdin, if the `stdin` field of this process's
     /// `ProcessConfig` was `CreatePipe`. By default, this handle is `Some`.
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 2f6cdcb5825..e52df042561 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -32,6 +32,7 @@ use fmt;
 use io::{Reader, Writer, IoResult, IoError, OtherIoError,
          standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
 use libc;
+use kinds::Send;
 use mem::replace;
 use option::{Option, Some, None};
 use prelude::drop;
@@ -71,8 +72,8 @@ use slice::ImmutableVector;
 // tl;dr; TTY works on everything but when windows stdout is redirected, in that
 //        case pipe also doesn't work, but magically file does!
 enum StdSource {
-    TTY(~RtioTTY),
-    File(~RtioFileStream),
+    TTY(~RtioTTY:Send),
+    File(~RtioFileStream:Send),
 }
 
 fn src<T>(fd: libc::c_int, readable: bool, f: |StdSource| -> T) -> T {
@@ -145,8 +146,10 @@ pub fn stderr_raw() -> StdWriter {
     src(libc::STDERR_FILENO, false, |src| StdWriter { inner: src })
 }
 
-fn reset_helper(w: ~Writer,
-                f: |&mut Task, ~Writer| -> Option<~Writer>) -> Option<~Writer> {
+fn reset_helper(w: ~Writer:Send,
+                f: |&mut Task, ~Writer:Send| -> Option<~Writer:Send>)
+    -> Option<~Writer:Send>
+{
     let mut t = Local::borrow(None::<Task>);
     // Be sure to flush any pending output from the writer
     match f(t.get(), w) {
@@ -168,7 +171,7 @@ fn reset_helper(w: ~Writer,
 ///
 /// Note that this does not need to be called for all new tasks; the default
 /// output handle is to the process's stdout stream.
-pub fn set_stdout(stdout: ~Writer) -> Option<~Writer> {
+pub fn set_stdout(stdout: ~Writer:Send) -> Option<~Writer:Send> {
     reset_helper(stdout, |t, w| replace(&mut t.stdout, Some(w)))
 }
 
@@ -180,7 +183,7 @@ pub fn set_stdout(stdout: ~Writer) -> Option<~Writer> {
 ///
 /// Note that this does not need to be called for all new tasks; the default
 /// output handle is to the process's stderr stream.
-pub fn set_stderr(stderr: ~Writer) -> Option<~Writer> {
+pub fn set_stderr(stderr: ~Writer:Send) -> Option<~Writer:Send> {
     reset_helper(stderr, |t, w| replace(&mut t.stderr, Some(w)))
 }
 
@@ -206,7 +209,7 @@ fn with_task_stdout(f: |&mut Writer| -> IoResult<()> ) {
             Local::put(task);
 
             if my_stdout.is_none() {
-                my_stdout = Some(~stdout() as ~Writer);
+                my_stdout = Some(~stdout() as ~Writer:Send);
             }
             let ret = f(*my_stdout.get_mut_ref());
 
@@ -399,7 +402,7 @@ mod tests {
         let (tx, rx) = channel();
         let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
         spawn(proc() {
-            set_stdout(~w as ~Writer);
+            set_stdout(~w);
             println!("hello!");
         });
         assert_eq!(r.read_to_str().unwrap(), ~"hello!\n");
@@ -411,7 +414,7 @@ mod tests {
         let (tx, rx) = channel();
         let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
         spawn(proc() {
-            set_stderr(~w as ~Writer);
+            set_stderr(~w);
             fail!("my special message");
         });
         let s = r.read_to_str().unwrap();
diff --git a/src/libstd/io/timer.rs b/src/libstd/io/timer.rs
index f64c36c611c..6840c418a9b 100644
--- a/src/libstd/io/timer.rs
+++ b/src/libstd/io/timer.rs
@@ -18,8 +18,9 @@ and create receivers which will receive notifications after a period of time.
 */
 
 use comm::Receiver;
-use rt::rtio::{IoFactory, LocalIo, RtioTimer};
 use io::IoResult;
+use kinds::Send;
+use rt::rtio::{IoFactory, LocalIo, RtioTimer};
 
 /// A synchronous timer object
 ///
@@ -62,7 +63,7 @@ use io::IoResult;
 /// # }
 /// ```
 pub struct Timer {
-    priv obj: ~RtioTimer
+    priv obj: ~RtioTimer:Send,
 }
 
 /// Sleep the current task for `msecs` milliseconds.
diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs
index f1f1977462f..c555fb58db8 100644
--- a/src/libstd/local_data.rs
+++ b/src/libstd/local_data.rs
@@ -41,11 +41,12 @@ local_data::get(key_vector, |opt| assert_eq!(*opt.unwrap(), ~[4]));
 // magic.
 
 use cast;
-use option::{None, Option, Some};
-use slice::{ImmutableVector, MutableVector, OwnedVector};
 use iter::{Iterator};
-use rt::task::{Task, LocalStorage};
+use kinds::Send;
 use mem::replace;
+use option::{None, Option, Some};
+use rt::task::{Task, LocalStorage};
+use slice::{ImmutableVector, MutableVector, OwnedVector};
 
 /**
  * Indexes a task-local data slot. This pointer is used for comparison to
@@ -89,7 +90,7 @@ impl<T: 'static> LocalData for T {}
 //      a proper map.
 #[doc(hidden)]
 pub type Map = ~[Option<(*u8, TLSValue, LoanState)>];
-type TLSValue = ~LocalData;
+type TLSValue = ~LocalData:Send;
 
 // Gets the map from the runtime. Lazily initialises if not done so already.
 unsafe fn get_local_map() -> &mut Map {
@@ -328,7 +329,7 @@ pub fn set<T: 'static>(key: Key<T>, data: T) {
     // transmute here to add the Send bound back on. This doesn't actually
     // matter because TLS will always own the data (until its moved out) and
     // we're not actually sending it to other schedulers or anything.
-    let data: ~LocalData = unsafe { cast::transmute(data) };
+    let data: ~LocalData:Send = unsafe { cast::transmute(data) };
     match insertion_position(map, keyval) {
         Some(i) => { map[i] = Some((keyval, data, NoLoan)); }
         None => { map.push(Some((keyval, data, NoLoan))); }
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index f623dd472fd..675250a2710 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -686,7 +686,7 @@ fn test_repr() {
     exact_test(&println, "fn(&str)");
     exact_test(&swap::<int>, "fn(&mut int, &mut int)");
     exact_test(&is_alphabetic, "fn(char) -> bool");
-    exact_test(&(~5 as ~ToStr), "~to_str::ToStr:Send");
+    exact_test(&(~5 as ~ToStr), "~to_str::ToStr<no-bounds>");
 
     struct Foo;
     exact_test(&(~[Foo, Foo]), "~[repr::test_repr::Foo, repr::test_repr::Foo]");
diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs
index 96dcc5244c0..a5bfaf190d9 100644
--- a/src/libstd/rt/at_exit_imp.rs
+++ b/src/libstd/rt/at_exit_imp.rs
@@ -14,13 +14,14 @@
 
 use cast;
 use iter::Iterator;
+use kinds::Send;
 use mem;
 use option::{Some, None};
 use ptr::RawPtr;
 use unstable::sync::Exclusive;
 use slice::OwnedVector;
 
-type Queue = Exclusive<~[proc()]>;
+type Queue = Exclusive<~[proc:Send()]>;
 
 // You'll note that these variables are *not* atomic, and this is done on
 // purpose. This module is designed to have init() called *once* in a
@@ -39,7 +40,7 @@ pub fn init() {
     }
 }
 
-pub fn push(f: proc()) {
+pub fn push(f: proc:Send()) {
     unsafe {
         rtassert!(!RUNNING);
         rtassert!(!QUEUE.is_null());
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 795281026a4..28f11f44054 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -55,6 +55,7 @@ Several modules in `core` are clients of `rt`:
 #[allow(missing_doc)];
 
 use any::Any;
+use kinds::Send;
 use option::Option;
 use result::Result;
 use task::TaskOpts;
@@ -156,7 +157,7 @@ pub trait Runtime {
 
     // Miscellaneous calls which are very different depending on what context
     // you're in.
-    fn spawn_sibling(~self, cur_task: ~Task, opts: TaskOpts, f: proc());
+    fn spawn_sibling(~self, cur_task: ~Task, opts: TaskOpts, f: proc:Send());
     fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>>;
     /// The (low, high) edges of the current stack.
     fn stack_bounds(&self) -> (uint, uint); // (lo, hi)
@@ -195,7 +196,7 @@ pub fn init(argc: int, argv: **u8) {
 ///
 /// 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: proc()) {
+pub fn at_exit(f: proc:Send()) {
     at_exit_imp::push(f);
 }
 
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
index 60933aeb38b..5f0f0afd185 100644
--- a/src/libstd/rt/rtio.rs
+++ b/src/libstd/rt/rtio.rs
@@ -13,16 +13,17 @@ use cast;
 use comm::{Sender, Receiver};
 use libc::c_int;
 use libc;
+use kinds::Send;
 use ops::Drop;
 use option::{Option, Some, None};
 use path::Path;
-use result::{Result, Err};
-use rt::task::Task;
+use result::Err;
 use rt::local::Local;
+use rt::task::Task;
 
 use ai = io::net::addrinfo;
 use io;
-use io::{IoError, IoResult};
+use io::IoResult;
 use io::net::ip::{IpAddr, SocketAddr};
 use io::process::{ProcessConfig, ProcessExit};
 use io::signal::Signum;
@@ -35,9 +36,10 @@ pub trait Callback {
 
 pub trait EventLoop {
     fn run(&mut self);
-    fn callback(&mut self, proc());
-    fn pausable_idle_callback(&mut self, ~Callback) -> ~PausableIdleCallback;
-    fn remote_callback(&mut self, ~Callback) -> ~RemoteCallback;
+    fn callback(&mut self, arg: proc:Send());
+    fn pausable_idle_callback(&mut self,
+                              ~Callback:Send) -> ~PausableIdleCallback:Send;
+    fn remote_callback(&mut self, ~Callback:Send) -> ~RemoteCallback:Send;
 
     /// The asynchronous I/O services. Not all event loops may provide one.
     fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory>;
@@ -143,93 +145,94 @@ impl<'a> LocalIo<'a> {
 
 pub trait IoFactory {
     // networking
-    fn tcp_connect(&mut self, addr: SocketAddr) -> Result<~RtioTcpStream, IoError>;
-    fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~RtioTcpListener, IoError>;
-    fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocket, IoError>;
-    fn unix_bind(&mut self, path: &CString) ->
-        Result<~RtioUnixListener, IoError>;
-    fn unix_connect(&mut self, path: &CString) -> Result<~RtioPipe, IoError>;
+    fn tcp_connect(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpStream:Send>;
+    fn tcp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpListener:Send>;
+    fn udp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioUdpSocket:Send>;
+    fn unix_bind(&mut self, path: &CString)
+        -> IoResult<~RtioUnixListener:Send>;
+    fn unix_connect(&mut self, path: &CString) -> IoResult<~RtioPipe:Send>;
     fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
-                          hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError>;
+                          hint: Option<ai::Hint>) -> IoResult<~[ai::Info]>;
 
     // filesystem operations
-    fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior) -> ~RtioFileStream;
+    fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior)
+        -> ~RtioFileStream:Send;
     fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
-        -> Result<~RtioFileStream, IoError>;
-    fn fs_unlink(&mut self, path: &CString) -> Result<(), IoError>;
-    fn fs_stat(&mut self, path: &CString) -> Result<FileStat, IoError>;
+        -> IoResult<~RtioFileStream:Send>;
+    fn fs_unlink(&mut self, path: &CString) -> IoResult<()>;
+    fn fs_stat(&mut self, path: &CString) -> IoResult<FileStat>;
     fn fs_mkdir(&mut self, path: &CString,
-                mode: FilePermission) -> Result<(), IoError>;
+                mode: FilePermission) -> IoResult<()>;
     fn fs_chmod(&mut self, path: &CString,
-                mode: FilePermission) -> Result<(), IoError>;
-    fn fs_rmdir(&mut self, path: &CString) -> Result<(), IoError>;
-    fn fs_rename(&mut self, path: &CString, to: &CString) -> Result<(), IoError>;
+                mode: FilePermission) -> IoResult<()>;
+    fn fs_rmdir(&mut self, path: &CString) -> IoResult<()>;
+    fn fs_rename(&mut self, path: &CString, to: &CString) -> IoResult<()>;
     fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
-        Result<~[Path], IoError>;
-    fn fs_lstat(&mut self, path: &CString) -> Result<FileStat, IoError>;
+        IoResult<~[Path]>;
+    fn fs_lstat(&mut self, path: &CString) -> IoResult<FileStat>;
     fn fs_chown(&mut self, path: &CString, uid: int, gid: int) ->
-        Result<(), IoError>;
-    fn fs_readlink(&mut self, path: &CString) -> Result<Path, IoError>;
-    fn fs_symlink(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
-    fn fs_link(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
+        IoResult<()>;
+    fn fs_readlink(&mut self, path: &CString) -> IoResult<Path>;
+    fn fs_symlink(&mut self, src: &CString, dst: &CString) -> IoResult<()>;
+    fn fs_link(&mut self, src: &CString, dst: &CString) -> IoResult<()>;
     fn fs_utime(&mut self, src: &CString, atime: u64, mtime: u64) ->
-        Result<(), IoError>;
+        IoResult<()>;
 
     // misc
-    fn timer_init(&mut self) -> Result<~RtioTimer, IoError>;
+    fn timer_init(&mut self) -> IoResult<~RtioTimer:Send>;
     fn spawn(&mut self, config: ProcessConfig)
-            -> Result<(~RtioProcess, ~[Option<~RtioPipe>]), IoError>;
-    fn kill(&mut self, pid: libc::pid_t, signal: int) -> Result<(), IoError>;
-    fn pipe_open(&mut self, fd: c_int) -> Result<~RtioPipe, IoError>;
+            -> IoResult<(~RtioProcess:Send, ~[Option<~RtioPipe:Send>])>;
+    fn kill(&mut self, pid: libc::pid_t, signal: int) -> IoResult<()>;
+    fn pipe_open(&mut self, fd: c_int) -> IoResult<~RtioPipe:Send>;
     fn tty_open(&mut self, fd: c_int, readable: bool)
-            -> Result<~RtioTTY, IoError>;
+            -> IoResult<~RtioTTY:Send>;
     fn signal(&mut self, signal: Signum, channel: Sender<Signum>)
-        -> Result<~RtioSignal, IoError>;
+        -> IoResult<~RtioSignal:Send>;
 }
 
 pub trait RtioTcpListener : RtioSocket {
-    fn listen(~self) -> Result<~RtioTcpAcceptor, IoError>;
+    fn listen(~self) -> IoResult<~RtioTcpAcceptor:Send>;
 }
 
 pub trait RtioTcpAcceptor : RtioSocket {
-    fn accept(&mut self) -> Result<~RtioTcpStream, IoError>;
-    fn accept_simultaneously(&mut self) -> Result<(), IoError>;
-    fn dont_accept_simultaneously(&mut self) -> Result<(), IoError>;
+    fn accept(&mut self) -> IoResult<~RtioTcpStream:Send>;
+    fn accept_simultaneously(&mut self) -> IoResult<()>;
+    fn dont_accept_simultaneously(&mut self) -> IoResult<()>;
 }
 
 pub trait RtioTcpStream : RtioSocket {
-    fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
-    fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
-    fn peer_name(&mut self) -> Result<SocketAddr, IoError>;
-    fn control_congestion(&mut self) -> Result<(), IoError>;
-    fn nodelay(&mut self) -> Result<(), IoError>;
-    fn keepalive(&mut self, delay_in_seconds: uint) -> Result<(), IoError>;
-    fn letdie(&mut self) -> Result<(), IoError>;
-    fn clone(&self) -> ~RtioTcpStream;
-    fn close_write(&mut self) -> Result<(), IoError>;
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
+    fn write(&mut self, buf: &[u8]) -> IoResult<()>;
+    fn peer_name(&mut self) -> IoResult<SocketAddr>;
+    fn control_congestion(&mut self) -> IoResult<()>;
+    fn nodelay(&mut self) -> IoResult<()>;
+    fn keepalive(&mut self, delay_in_seconds: uint) -> IoResult<()>;
+    fn letdie(&mut self) -> IoResult<()>;
+    fn clone(&self) -> ~RtioTcpStream:Send;
+    fn close_write(&mut self) -> IoResult<()>;
 }
 
 pub trait RtioSocket {
-    fn socket_name(&mut self) -> Result<SocketAddr, IoError>;
+    fn socket_name(&mut self) -> IoResult<SocketAddr>;
 }
 
 pub trait RtioUdpSocket : RtioSocket {
-    fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, SocketAddr), IoError>;
-    fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError>;
+    fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)>;
+    fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()>;
 
-    fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
-    fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
+    fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
+    fn leave_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
 
-    fn loop_multicast_locally(&mut self) -> Result<(), IoError>;
-    fn dont_loop_multicast_locally(&mut self) -> Result<(), IoError>;
+    fn loop_multicast_locally(&mut self) -> IoResult<()>;
+    fn dont_loop_multicast_locally(&mut self) -> IoResult<()>;
 
-    fn multicast_time_to_live(&mut self, ttl: int) -> Result<(), IoError>;
-    fn time_to_live(&mut self, ttl: int) -> Result<(), IoError>;
+    fn multicast_time_to_live(&mut self, ttl: int) -> IoResult<()>;
+    fn time_to_live(&mut self, ttl: int) -> IoResult<()>;
 
-    fn hear_broadcasts(&mut self) -> Result<(), IoError>;
-    fn ignore_broadcasts(&mut self) -> Result<(), IoError>;
+    fn hear_broadcasts(&mut self) -> IoResult<()>;
+    fn ignore_broadcasts(&mut self) -> IoResult<()>;
 
-    fn clone(&self) -> ~RtioUdpSocket;
+    fn clone(&self) -> ~RtioUdpSocket:Send;
 }
 
 pub trait RtioTimer {
@@ -239,42 +242,42 @@ pub trait RtioTimer {
 }
 
 pub trait RtioFileStream {
-    fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError>;
-    fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
-    fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError>;
-    fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError>;
-    fn seek(&mut self, pos: i64, whence: SeekStyle) -> Result<u64, IoError>;
-    fn tell(&self) -> Result<u64, IoError>;
-    fn fsync(&mut self) -> Result<(), IoError>;
-    fn datasync(&mut self) -> Result<(), IoError>;
-    fn truncate(&mut self, offset: i64) -> Result<(), IoError>;
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<int>;
+    fn write(&mut self, buf: &[u8]) -> IoResult<()>;
+    fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult<int>;
+    fn pwrite(&mut self, buf: &[u8], offset: u64) -> IoResult<()>;
+    fn seek(&mut self, pos: i64, whence: SeekStyle) -> IoResult<u64>;
+    fn tell(&self) -> IoResult<u64>;
+    fn fsync(&mut self) -> IoResult<()>;
+    fn datasync(&mut self) -> IoResult<()>;
+    fn truncate(&mut self, offset: i64) -> IoResult<()>;
 }
 
 pub trait RtioProcess {
     fn id(&self) -> libc::pid_t;
-    fn kill(&mut self, signal: int) -> Result<(), IoError>;
+    fn kill(&mut self, signal: int) -> IoResult<()>;
     fn wait(&mut self) -> ProcessExit;
 }
 
 pub trait RtioPipe {
-    fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
-    fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
-    fn clone(&self) -> ~RtioPipe;
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
+    fn write(&mut self, buf: &[u8]) -> IoResult<()>;
+    fn clone(&self) -> ~RtioPipe:Send;
 }
 
 pub trait RtioUnixListener {
-    fn listen(~self) -> Result<~RtioUnixAcceptor, IoError>;
+    fn listen(~self) -> IoResult<~RtioUnixAcceptor:Send>;
 }
 
 pub trait RtioUnixAcceptor {
-    fn accept(&mut self) -> Result<~RtioPipe, IoError>;
+    fn accept(&mut self) -> IoResult<~RtioPipe:Send>;
 }
 
 pub trait RtioTTY {
-    fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
-    fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
-    fn set_raw(&mut self, raw: bool) -> Result<(), IoError>;
-    fn get_winsize(&mut self) -> Result<(int, int), IoError>;
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
+    fn write(&mut self, buf: &[u8]) -> IoResult<()>;
+    fn set_raw(&mut self, raw: bool) -> IoResult<()>;
+    fn get_winsize(&mut self) -> IoResult<(int, int)>;
     fn isatty(&self) -> bool;
 }
 
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index ededc69c5a1..211c09977d4 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -20,6 +20,7 @@ use clone::Clone;
 use comm::Sender;
 use io::Writer;
 use iter::{Iterator, Take};
+use kinds::Send;
 use local_data;
 use ops::Drop;
 use option::{Option, Some, None};
@@ -50,10 +51,10 @@ pub struct Task {
     destroyed: bool,
     name: Option<SendStr>,
 
-    stdout: Option<~Writer>,
-    stderr: Option<~Writer>,
+    stdout: Option<~Writer:Send>,
+    stderr: Option<~Writer:Send>,
 
-    priv imp: Option<~Runtime>,
+    priv imp: Option<~Runtime:Send>,
 }
 
 pub struct GarbageCollector;
@@ -69,7 +70,7 @@ pub enum BlockedTask {
 pub enum DeathAction {
     /// Action to be done with the exit code. If set, also makes the task wait
     /// until all its watched children exit before collecting the status.
-    Execute(proc(TaskResult)),
+    Execute(proc:Send(TaskResult)),
     /// A channel to send the result of the task on when the task exits
     SendMessage(Sender<TaskResult>),
 }
@@ -195,7 +196,7 @@ impl Task {
     /// Inserts a runtime object into this task, transferring ownership to the
     /// task. It is illegal to replace a previous runtime object in this task
     /// with this argument.
-    pub fn put_runtime(&mut self, ops: ~Runtime) {
+    pub fn put_runtime(&mut self, ops: ~Runtime:Send) {
         assert!(self.imp.is_none());
         self.imp = Some(ops);
     }
@@ -225,7 +226,7 @@ impl Task {
                 Ok(t) => Some(t),
                 Err(t) => {
                     let (_, obj): (uint, uint) = cast::transmute(t);
-                    let obj: ~Runtime = cast::transmute((vtable, obj));
+                    let obj: ~Runtime:Send = cast::transmute((vtable, obj));
                     self.put_runtime(obj);
                     None
                 }
@@ -235,7 +236,7 @@ impl Task {
 
     /// Spawns a sibling to this task. The newly spawned task is configured with
     /// the `opts` structure and will run `f` as the body of its code.
-    pub fn spawn_sibling(mut ~self, opts: TaskOpts, f: proc()) {
+    pub fn spawn_sibling(mut ~self, opts: TaskOpts, f: proc:Send()) {
         let ops = self.imp.take_unwrap();
         ops.spawn_sibling(self, opts, f)
     }
diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs
index 0cbd67557de..7c4bd895469 100644
--- a/src/libstd/rt/thread.rs
+++ b/src/libstd/rt/thread.rs
@@ -68,13 +68,13 @@ impl Thread<()> {
     /// to finish executing. This means that even if `join` is not explicitly
     /// called, when the `Thread` falls out of scope its destructor will block
     /// waiting for the OS thread.
-    pub fn start<T: Send>(main: proc() -> T) -> Thread<T> {
+    pub fn start<T: Send>(main: proc:Send() -> T) -> Thread<T> {
         Thread::start_stack(DEFAULT_STACK_SIZE, main)
     }
 
     /// Performs the same functionality as `start`, but specifies an explicit
     /// stack size for the new thread.
-    pub fn start_stack<T: Send>(stack: uint, main: proc() -> T) -> Thread<T> {
+    pub fn start_stack<T: Send>(stack: uint, main: proc:Send() -> T) -> Thread<T> {
 
         // We need the address of the packet to fill in to be stable so when
         // `main` fills it in it's still valid, so allocate an extra ~ box to do
@@ -83,7 +83,7 @@ impl Thread<()> {
         let packet2: *mut Option<T> = unsafe {
             *cast::transmute::<&~Option<T>, **mut Option<T>>(&packet)
         };
-        let main: proc() = proc() unsafe { *packet2 = Some(main()); };
+        let main = proc() unsafe { *packet2 = Some(main()); };
         let native = unsafe { imp::create(stack, ~main) };
 
         Thread {
@@ -99,13 +99,13 @@ impl Thread<()> {
     /// This corresponds to creating threads in the 'detached' state on unix
     /// systems. Note that platforms may not keep the main program alive even if
     /// there are detached thread still running around.
-    pub fn spawn(main: proc()) {
+    pub fn spawn(main: proc:Send()) {
         Thread::spawn_stack(DEFAULT_STACK_SIZE, main)
     }
 
     /// Performs the same functionality as `spawn`, but explicitly specifies a
     /// stack size for the new thread.
-    pub fn spawn_stack(stack: uint, main: proc()) {
+    pub fn spawn_stack(stack: uint, main: proc:Send()) {
         unsafe {
             let handle = imp::create(stack, ~main);
             imp::detach(handle);
@@ -146,6 +146,7 @@ impl<T: Send> Drop for Thread<T> {
 mod imp {
     use cast;
     use cmp;
+    use kinds::Send;
     use libc;
     use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, SIZE_T, BOOL,
                                        LPVOID, DWORD, LPDWORD, HANDLE};
@@ -155,7 +156,7 @@ mod imp {
     pub type rust_thread = HANDLE;
     pub type rust_thread_return = DWORD;
 
-    pub unsafe fn create(stack: uint, p: ~proc()) -> rust_thread {
+    pub unsafe fn create(stack: uint, p: ~proc:Send()) -> rust_thread {
         let arg: *mut libc::c_void = cast::transmute(p);
         // FIXME On UNIX, we guard against stack sizes that are too small but
         // that's because pthreads enforces that stacks are at least
@@ -203,6 +204,7 @@ mod imp {
 mod imp {
     use cast;
     use cmp;
+    use kinds::Send;
     use libc::consts::os::posix01::{PTHREAD_CREATE_JOINABLE, PTHREAD_STACK_MIN};
     use libc;
     use mem;
@@ -213,7 +215,7 @@ mod imp {
     pub type rust_thread = libc::pthread_t;
     pub type rust_thread_return = *u8;
 
-    pub unsafe fn create(stack: uint, p: ~proc()) -> rust_thread {
+    pub unsafe fn create(stack: uint, p: ~proc:Send()) -> rust_thread {
         let mut native: libc::pthread_t = mem::uninit();
         let mut attr: libc::pthread_attr_t = mem::uninit();
         assert_eq!(pthread_attr_init(&mut attr), 0);
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 7f54b8b3320..930e0858da1 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -76,7 +76,7 @@ use uw = rt::libunwind;
 
 pub struct Unwinder {
     priv unwinding: bool,
-    priv cause: Option<~Any>
+    priv cause: Option<~Any:Send>
 }
 
 impl Unwinder {
@@ -126,7 +126,7 @@ impl Unwinder {
         }
     }
 
-    pub fn begin_unwind(&mut self, cause: ~Any) -> ! {
+    pub fn begin_unwind(&mut self, cause: ~Any:Send) -> ! {
         rtdebug!("begin_unwind()");
 
         self.unwinding = true;
@@ -372,7 +372,7 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> !
 /// Do this split took the LLVM IR line counts of `fn main() { fail!()
 /// }` from ~1900/3700 (-O/no opts) to 180/590.
 #[inline(never)] #[cold] // this is the slow path, please never inline this
-fn begin_unwind_inner(msg: ~Any, file: &'static str, line: uint) -> ! {
+fn begin_unwind_inner(msg: ~Any:Send, file: &'static str, line: uint) -> ! {
     let mut task;
     {
         let msg_s = match msg.as_ref::<&'static str>() {
diff --git a/src/libstd/task.rs b/src/libstd/task.rs
index 9c88db6beb5..c158ddf0d83 100644
--- a/src/libstd/task.rs
+++ b/src/libstd/task.rs
@@ -55,7 +55,7 @@ use str::{Str, SendStr, IntoMaybeOwned};
 ///
 /// If you wish for this result's delivery to block until all
 /// children tasks complete, recommend using a result future.
-pub type TaskResult = Result<(), ~Any>;
+pub type TaskResult = Result<(), ~Any:Send>;
 
 /// Task configuration options
 pub struct TaskOpts {
@@ -66,9 +66,9 @@ pub struct TaskOpts {
     /// The size of the stack for the spawned task
     stack_size: Option<uint>,
     /// Task-local stdout
-    stdout: Option<~Writer>,
+    stdout: Option<~Writer:Send>,
     /// Task-local stderr
-    stderr: Option<~Writer>,
+    stderr: Option<~Writer:Send>,
 }
 
 /**
@@ -86,7 +86,7 @@ pub struct TaskOpts {
 pub struct TaskBuilder {
     /// Options to spawn the new task with
     opts: TaskOpts,
-    priv gen_body: Option<proc(v: proc()) -> proc()>,
+    priv gen_body: Option<proc:Send(v: proc:Send()) -> proc:Send()>,
     priv nopod: Option<marker::NoPod>,
 }
 
@@ -150,22 +150,14 @@ impl TaskBuilder {
      * generator by applying the task body which results from the
      * existing body generator to the new body generator.
      */
-    pub fn with_wrapper(mut self, wrapper: proc(v: proc()) -> proc()) -> TaskBuilder {
-        let prev_gen_body = self.gen_body.take();
-        let prev_gen_body = match prev_gen_body {
-            Some(gen) => gen,
-            None => {
-                let f: proc(proc()) -> proc() = proc(body) body;
-                f
-            }
-        };
-        let next_gen_body = {
-            let f: proc(proc()) -> proc() = proc(body) {
-                wrapper(prev_gen_body(body))
-            };
-            f
+    pub fn with_wrapper(mut self,
+                        wrapper: proc:Send(v: proc:Send()) -> proc:Send())
+        -> TaskBuilder
+    {
+        self.gen_body = match self.gen_body.take() {
+            Some(prev) => Some(proc(body) { wrapper(prev(body)) }),
+            None => Some(wrapper)
         };
-        self.gen_body = Some(next_gen_body);
         self
     }
 
@@ -176,7 +168,7 @@ impl TaskBuilder {
      * the provided unique closure. The task has the properties and behavior
      * specified by the task_builder.
      */
-    pub fn spawn(mut self, f: proc()) {
+    pub fn spawn(mut self, f: proc:Send()) {
         let gen_body = self.gen_body.take();
         let f = match gen_body {
             Some(gen) => gen(f),
@@ -199,7 +191,7 @@ impl TaskBuilder {
      * # Failure
      * Fails if a future_result was already set for this task.
      */
-    pub fn try<T:Send>(mut self, f: proc() -> T) -> Result<T, ~Any> {
+    pub fn try<T:Send>(mut self, f: proc:Send() -> T) -> Result<T, ~Any:Send> {
         let (tx, rx) = channel();
 
         let result = self.future_result();
@@ -241,12 +233,12 @@ impl TaskOpts {
 /// the provided unique closure.
 ///
 /// This function is equivalent to `task().spawn(f)`.
-pub fn spawn(f: proc()) {
+pub fn spawn(f: proc:Send()) {
     let task = task();
     task.spawn(f)
 }
 
-pub fn try<T:Send>(f: proc() -> T) -> Result<T, ~Any> {
+pub fn try<T:Send>(f: proc:Send() -> T) -> Result<T, ~Any:Send> {
     /*!
      * Execute a function in another task and return either the return value
      * of the function or result::err.
@@ -346,7 +338,7 @@ fn test_run_basic() {
 fn test_with_wrapper() {
     let (tx, rx) = channel();
     task().with_wrapper(proc(body) {
-        let result: proc() = proc() {
+        let result: proc:Send() = proc() {
             body();
             tx.send(());
         };
@@ -432,7 +424,7 @@ fn test_spawn_sched_childs_on_default_sched() {
 }
 
 #[cfg(test)]
-fn avoid_copying_the_body(spawnfn: |v: proc()|) {
+fn avoid_copying_the_body(spawnfn: |v: proc:Send()|) {
     let (tx, rx) = channel::<uint>();
 
     let x = ~1;
@@ -478,7 +470,7 @@ fn test_child_doesnt_ref_parent() {
     // (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) -> proc() {
+    fn child_no(x: uint) -> proc:Send() {
         return proc() {
             if x < generations {
                 task().spawn(child_no(x+1));
@@ -524,10 +516,10 @@ fn test_try_fail_message_owned_str() {
 #[test]
 fn test_try_fail_message_any() {
     match try(proc() {
-        fail!(~413u16 as ~Any);
+        fail!(~413u16 as ~Any:Send);
     }) {
         Err(e) => {
-            type T = ~Any;
+            type T = ~Any:Send;
             assert!(e.is::<T>());
             let any = e.move::<T>().unwrap();
             assert!(any.is::<u16>());
diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs
index 7bee0cf48ee..720bf011fa0 100644
--- a/src/libstd/unstable/mod.rs
+++ b/src/libstd/unstable/mod.rs
@@ -28,7 +28,7 @@ for it to terminate.
 The executing thread has no access to a task pointer and will be using
 a normal large stack.
 */
-pub fn run_in_bare_thread(f: proc()) {
+pub fn run_in_bare_thread(f: proc:Send()) {
     use rt::thread::Thread;
     Thread::start(f).join()
 }