about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-03-08 18:21:49 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-03-27 10:14:50 -0700
commitbb9172d7b512c36f34d34b024640f030d1fde2eb (patch)
tree0e4ea18ae30a12954db6b9fbe95f62222ade9301
parentbdd24b2a56e8bf6b952bd8880364fb0a57c2c540 (diff)
downloadrust-bb9172d7b512c36f34d34b024640f030d1fde2eb.tar.gz
rust-bb9172d7b512c36f34d34b024640f030d1fde2eb.zip
Fix fallout of removing default bounds
This is all purely fallout of getting the previous commit to compile.
-rw-r--r--src/libgreen/basic.rs24
-rw-r--r--src/libgreen/lib.rs9
-rw-r--r--src/libgreen/sched.rs19
-rw-r--r--src/libgreen/simple.rs6
-rw-r--r--src/libgreen/task.rs5
-rw-r--r--src/liblog/lib.rs6
-rw-r--r--src/libnative/io/file_unix.rs4
-rw-r--r--src/libnative/io/mod.rs50
-rw-r--r--src/libnative/io/net.rs16
-rw-r--r--src/libnative/io/pipe_unix.rs12
-rw-r--r--src/libnative/task.rs23
-rw-r--r--src/librustc/lib.rs6
-rw-r--r--src/librustdoc/test.rs2
-rw-r--r--src/librustuv/async.rs7
-rw-r--r--src/librustuv/idle.rs4
-rw-r--r--src/librustuv/lib.rs4
-rw-r--r--src/librustuv/net.rs20
-rw-r--r--src/librustuv/pipe.rs16
-rw-r--r--src/librustuv/uvio.rs63
-rw-r--r--src/libserialize/json.rs2
-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
-rw-r--r--src/libsync/future.rs6
-rw-r--r--src/libsync/raw.rs4
-rw-r--r--src/libsync/task_pool.rs12
-rw-r--r--src/libsyntax/diagnostic.rs8
-rw-r--r--src/libtest/lib.rs8
-rw-r--r--src/libworkcache/lib.rs4
-rw-r--r--src/test/auxiliary/macro_crate_outlive_expansion_phase.rs4
-rw-r--r--src/test/compile-fail/issue-7013.rs4
-rw-r--r--src/test/compile-fail/kindck-nonsendable-1.rs7
-rw-r--r--src/test/compile-fail/trait-bounds-sugar.rs2
-rw-r--r--src/test/run-fail/fail-macro-any.rs2
-rw-r--r--src/test/run-fail/unwind-box-fn-unique.rs2
-rw-r--r--src/test/run-pass/capturing-logging.rs2
-rw-r--r--src/test/run-pass/clone-with-exterior.rs2
-rw-r--r--src/test/run-pass/issue-2190-1.rs4
-rw-r--r--src/test/run-pass/issue-3609.rs2
-rw-r--r--src/test/run-pass/sendfn-spawn-with-fn-arg.rs2
-rw-r--r--src/test/run-pass/tempfile.rs6
-rw-r--r--src/test/run-pass/trait-bounds-basic.rs2
-rw-r--r--src/test/run-pass/trait-cast.rs6
-rw-r--r--src/test/run-pass/uniq-cc-generic.rs7
-rw-r--r--src/test/run-pass/uniq-cc.rs2
61 files changed, 377 insertions, 363 deletions
diff --git a/src/libgreen/basic.rs b/src/libgreen/basic.rs
index b2596e56815..d2599aab14c 100644
--- a/src/libgreen/basic.rs
+++ b/src/libgreen/basic.rs
@@ -22,14 +22,14 @@ use std::rt::rtio::{EventLoop, IoFactory, RemoteCallback, PausableIdleCallback,
 use std::unstable::sync::Exclusive;
 
 /// This is the only exported function from this module.
-pub fn event_loop() -> ~EventLoop {
-    ~BasicLoop::new() as ~EventLoop
+pub fn event_loop() -> ~EventLoop:Send {
+    ~BasicLoop::new() as ~EventLoop:Send
 }
 
 struct BasicLoop {
-    work: ~[proc()],                  // pending work
+    work: ~[proc:Send()],             // pending work
     idle: Option<*mut BasicPausable>, // only one is allowed
-    remotes: ~[(uint, ~Callback)],
+    remotes: ~[(uint, ~Callback:Send)],
     next_remote: uint,
     messages: Exclusive<~[Message]>,
 }
@@ -135,26 +135,28 @@ impl EventLoop for BasicLoop {
         }
     }
 
-    fn callback(&mut self, f: proc()) {
+    fn callback(&mut self, f: proc:Send()) {
         self.work.push(f);
     }
 
     // FIXME: Seems like a really weird requirement to have an event loop provide.
-    fn pausable_idle_callback(&mut self, cb: ~Callback) -> ~PausableIdleCallback {
+    fn pausable_idle_callback(&mut self, cb: ~Callback:Send)
+        -> ~PausableIdleCallback:Send
+    {
         let callback = ~BasicPausable::new(self, cb);
         rtassert!(self.idle.is_none());
         unsafe {
             let cb_ptr: &*mut BasicPausable = cast::transmute(&callback);
             self.idle = Some(*cb_ptr);
         }
-        return callback as ~PausableIdleCallback;
+        callback as ~PausableIdleCallback:Send
     }
 
-    fn remote_callback(&mut self, f: ~Callback) -> ~RemoteCallback {
+    fn remote_callback(&mut self, f: ~Callback:Send) -> ~RemoteCallback:Send {
         let id = self.next_remote;
         self.next_remote += 1;
         self.remotes.push((id, f));
-        ~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback
+        ~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback:Send
     }
 
     fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory> { None }
@@ -195,12 +197,12 @@ impl Drop for BasicRemote {
 
 struct BasicPausable {
     eloop: *mut BasicLoop,
-    work: ~Callback,
+    work: ~Callback:Send,
     active: bool,
 }
 
 impl BasicPausable {
-    fn new(eloop: &mut BasicLoop, cb: ~Callback) -> BasicPausable {
+    fn new(eloop: &mut BasicLoop, cb: ~Callback:Send) -> BasicPausable {
         BasicPausable {
             active: false,
             work: cb,
diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs
index 3f7685d6c20..12f2839f321 100644
--- a/src/libgreen/lib.rs
+++ b/src/libgreen/lib.rs
@@ -247,7 +247,7 @@ pub mod task;
 /// The return value is used as the process return code. 0 on success, 101 on
 /// error.
 pub fn start(argc: int, argv: **u8,
-             event_loop_factory: fn() -> ~rtio::EventLoop,
+             event_loop_factory: fn() -> ~rtio::EventLoop:Send,
              main: proc()) -> int {
     rt::init(argc, argv);
     let mut main = Some(main);
@@ -268,7 +268,8 @@ pub fn start(argc: int, argv: **u8,
 ///
 /// This function will not return until all schedulers in the associated pool
 /// have returned.
-pub fn run(event_loop_factory: fn() -> ~rtio::EventLoop, main: proc()) -> int {
+pub fn run(event_loop_factory: fn() -> ~rtio::EventLoop:Send,
+           main: proc()) -> int {
     // Create a scheduler pool and spawn the main task into this pool. We will
     // get notified over a channel when the main task exits.
     let mut cfg = PoolConfig::new();
@@ -298,7 +299,7 @@ pub struct PoolConfig {
     threads: uint,
     /// A factory function used to create new event loops. If this is not
     /// specified then the default event loop factory is used.
-    event_loop_factory: fn() -> ~rtio::EventLoop,
+    event_loop_factory: fn() -> ~rtio::EventLoop:Send,
 }
 
 impl PoolConfig {
@@ -323,7 +324,7 @@ pub struct SchedPool {
     priv stack_pool: StackPool,
     priv deque_pool: deque::BufferPool<~task::GreenTask>,
     priv sleepers: SleeperList,
-    priv factory: fn() -> ~rtio::EventLoop,
+    priv factory: fn() -> ~rtio::EventLoop:Send,
     priv task_state: TaskState,
     priv tasks_done: Receiver<()>,
 }
diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs
index 5571d4f4687..4308c05716c 100644
--- a/src/libgreen/sched.rs
+++ b/src/libgreen/sched.rs
@@ -79,7 +79,7 @@ pub struct Scheduler {
     /// A fast XorShift rng for scheduler use
     rng: XorShiftRng,
     /// A togglable idle callback
-    idle_callback: Option<~PausableIdleCallback>,
+    idle_callback: Option<~PausableIdleCallback:Send>,
     /// A countdown that starts at a random value and is decremented
     /// every time a yield check is performed. When it hits 0 a task
     /// will yield.
@@ -99,7 +99,7 @@ pub struct Scheduler {
     //      destroyed before it's actually destroyed.
 
     /// The event loop used to drive the scheduler and perform I/O
-    event_loop: ~EventLoop,
+    event_loop: ~EventLoop:Send,
 }
 
 /// An indication of how hard to work on a given operation, the difference
@@ -122,7 +122,7 @@ impl Scheduler {
     // * Initialization Functions
 
     pub fn new(pool_id: uint,
-               event_loop: ~EventLoop,
+               event_loop: ~EventLoop:Send,
                work_queue: deque::Worker<~GreenTask>,
                work_queues: ~[deque::Stealer<~GreenTask>],
                sleeper_list: SleeperList,
@@ -135,7 +135,7 @@ impl Scheduler {
     }
 
     pub fn new_special(pool_id: uint,
-                       event_loop: ~EventLoop,
+                       event_loop: ~EventLoop:Send,
                        work_queue: deque::Worker<~GreenTask>,
                        work_queues: ~[deque::Stealer<~GreenTask>],
                        sleeper_list: SleeperList,
@@ -182,7 +182,7 @@ impl Scheduler {
     pub fn bootstrap(mut ~self) {
 
         // Build an Idle callback.
-        let cb = ~SchedRunner as ~Callback;
+        let cb = ~SchedRunner as ~Callback:Send;
         self.idle_callback = Some(self.event_loop.pausable_idle_callback(cb));
 
         // Create a task for the scheduler with an empty context.
@@ -230,7 +230,7 @@ impl Scheduler {
         // mutable reference to the event_loop to give it the "run"
         // command.
         unsafe {
-            let event_loop: *mut ~EventLoop = &mut self.event_loop;
+            let event_loop: *mut ~EventLoop:Send = &mut self.event_loop;
             // Our scheduler must be in the task before the event loop
             // is started.
             stask.put_with_sched(self);
@@ -868,7 +868,7 @@ impl Scheduler {
     }
 
     pub fn make_handle(&mut self) -> SchedHandle {
-        let remote = self.event_loop.remote_callback(~SchedRunner as ~Callback);
+        let remote = self.event_loop.remote_callback(~SchedRunner);
 
         return SchedHandle {
             remote: remote,
@@ -893,7 +893,7 @@ pub enum SchedMessage {
 }
 
 pub struct SchedHandle {
-    priv remote: ~RemoteCallback,
+    priv remote: ~RemoteCallback:Send,
     priv queue: msgq::Producer<SchedMessage>,
     sched_id: uint
 }
@@ -1007,7 +1007,6 @@ mod test {
 
     use std::comm;
     use std::task::TaskOpts;
-    use std::rt::Runtime;
     use std::rt::task::Task;
     use std::rt::local::Local;
 
@@ -1034,7 +1033,7 @@ mod test {
         match task.get().maybe_take_runtime::<GreenTask>() {
             Some(green) => {
                 let ret = green.sched.get_ref().sched_id();
-                task.get().put_runtime(green as ~Runtime);
+                task.get().put_runtime(green);
                 return ret;
             }
             None => fail!()
diff --git a/src/libgreen/simple.rs b/src/libgreen/simple.rs
index 01e620df2d6..75a53b0bbd3 100644
--- a/src/libgreen/simple.rs
+++ b/src/libgreen/simple.rs
@@ -34,7 +34,7 @@ impl Runtime for SimpleTask {
 
         let me = &mut *self as *mut SimpleTask;
         let cur_dupe = &*cur_task as *Task;
-        cur_task.put_runtime(self as ~Runtime);
+        cur_task.put_runtime(self);
         let task = BlockedTask::block(cur_task);
 
         // See libnative/task.rs for what's going on here with the `awoken`
@@ -57,7 +57,7 @@ impl Runtime for SimpleTask {
     }
     fn reawaken(mut ~self, mut to_wake: ~Task) {
         let me = &mut *self as *mut SimpleTask;
-        to_wake.put_runtime(self as ~Runtime);
+        to_wake.put_runtime(self);
         unsafe {
             cast::forget(to_wake);
             let guard = (*me).lock.lock();
@@ -86,6 +86,6 @@ pub fn task() -> ~Task {
     task.put_runtime(~SimpleTask {
         lock: unsafe {NativeMutex::new()},
         awoken: false,
-    } as ~Runtime);
+    });
     return task;
 }
diff --git a/src/libgreen/task.rs b/src/libgreen/task.rs
index 25e868470bf..7be749791a2 100644
--- a/src/libgreen/task.rs
+++ b/src/libgreen/task.rs
@@ -287,7 +287,7 @@ impl GreenTask {
 
     pub fn swap(mut ~self) -> ~Task {
         let mut task = self.task.take_unwrap();
-        task.put_runtime(self as ~Runtime);
+        task.put_runtime(self);
         return task;
     }
 
@@ -482,7 +482,6 @@ impl Runtime for GreenTask {
 
 #[cfg(test)]
 mod tests {
-    use std::rt::Runtime;
     use std::rt::local::Local;
     use std::rt::task::Task;
     use std::task;
@@ -576,7 +575,7 @@ mod tests {
                 let mut task: ~Task = Local::take();
                 match task.maybe_take_runtime::<GreenTask>() {
                     Some(ops) => {
-                        task.put_runtime(ops as ~Runtime);
+                        task.put_runtime(ops);
                     }
                     None => fail!(),
                 }
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs
index 75a8eae6c08..765b3dabd7b 100644
--- a/src/liblog/lib.rs
+++ b/src/liblog/lib.rs
@@ -156,7 +156,7 @@ pub static WARN: u32 = 2;
 /// Error log level
 pub static ERROR: u32 = 1;
 
-local_data_key!(local_logger: ~Logger)
+local_data_key!(local_logger: ~Logger:Send)
 
 /// A trait used to represent an interface to a task-local logger. Each task
 /// can have its own custom logger which can respond to logging messages
@@ -203,7 +203,7 @@ pub fn log(level: u32, args: &fmt::Arguments) {
     // frob the slot while we're doing the logging. This will destroy any logger
     // set during logging.
     let mut logger = local_data::pop(local_logger).unwrap_or_else(|| {
-        ~DefaultLogger { handle: io::stderr() } as ~Logger
+        ~DefaultLogger { handle: io::stderr() } as ~Logger:Send
     });
     logger.log(level, args);
     local_data::set(local_logger, logger);
@@ -217,7 +217,7 @@ pub fn log_level() -> u32 { unsafe { LOG_LEVEL } }
 
 /// Replaces the task-local logger with the specified logger, returning the old
 /// logger.
-pub fn set_logger(logger: ~Logger) -> Option<~Logger> {
+pub fn set_logger(logger: ~Logger:Send) -> Option<~Logger:Send> {
     let prev = local_data::pop(local_logger);
     local_data::set(local_logger, logger);
     return prev;
diff --git a/src/libnative/io/file_unix.rs b/src/libnative/io/file_unix.rs
index b997aa4f11c..2e33110b700 100644
--- a/src/libnative/io/file_unix.rs
+++ b/src/libnative/io/file_unix.rs
@@ -176,8 +176,8 @@ impl rtio::RtioPipe for FileDesc {
     fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
         self.inner_write(buf)
     }
-    fn clone(&self) -> ~rtio::RtioPipe {
-        ~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe
+    fn clone(&self) -> ~rtio::RtioPipe:Send {
+        ~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe:Send
     }
 }
 
diff --git a/src/libnative/io/mod.rs b/src/libnative/io/mod.rs
index e802c8f0301..3536ec7dec6 100644
--- a/src/libnative/io/mod.rs
+++ b/src/libnative/io/mod.rs
@@ -227,20 +227,20 @@ impl IoFactory {
 
 impl rtio::IoFactory for IoFactory {
     // networking
-    fn tcp_connect(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpStream> {
-        net::TcpStream::connect(addr).map(|s| ~s as ~RtioTcpStream)
+    fn tcp_connect(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpStream:Send> {
+        net::TcpStream::connect(addr).map(|s| ~s as ~RtioTcpStream:Send)
     }
-    fn tcp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpListener> {
-        net::TcpListener::bind(addr).map(|s| ~s as ~RtioTcpListener)
+    fn tcp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpListener:Send> {
+        net::TcpListener::bind(addr).map(|s| ~s as ~RtioTcpListener:Send)
     }
-    fn udp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioUdpSocket> {
-        net::UdpSocket::bind(addr).map(|u| ~u as ~RtioUdpSocket)
+    fn udp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioUdpSocket:Send> {
+        net::UdpSocket::bind(addr).map(|u| ~u as ~RtioUdpSocket:Send)
     }
-    fn unix_bind(&mut self, path: &CString) -> IoResult<~RtioUnixListener> {
-        pipe::UnixListener::bind(path).map(|s| ~s as ~RtioUnixListener)
+    fn unix_bind(&mut self, path: &CString) -> IoResult<~RtioUnixListener:Send> {
+        pipe::UnixListener::bind(path).map(|s| ~s as ~RtioUnixListener:Send)
     }
-    fn unix_connect(&mut self, path: &CString) -> IoResult<~RtioPipe> {
-        pipe::UnixStream::connect(path).map(|s| ~s as ~RtioPipe)
+    fn unix_connect(&mut self, path: &CString) -> IoResult<~RtioPipe:Send> {
+        pipe::UnixStream::connect(path).map(|s| ~s as ~RtioPipe:Send)
     }
     fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
                           hint: Option<ai::Hint>) -> IoResult<~[ai::Info]> {
@@ -249,16 +249,16 @@ impl rtio::IoFactory for IoFactory {
 
     // filesystem operations
     fn fs_from_raw_fd(&mut self, fd: c_int,
-                      close: CloseBehavior) -> ~RtioFileStream {
+                      close: CloseBehavior) -> ~RtioFileStream:Send {
         let close = match close {
             rtio::CloseSynchronously | rtio::CloseAsynchronously => true,
             rtio::DontClose => false
         };
-        ~file::FileDesc::new(fd, close) as ~RtioFileStream
+        ~file::FileDesc::new(fd, close) as ~RtioFileStream:Send
     }
     fn fs_open(&mut self, path: &CString, fm: io::FileMode, fa: io::FileAccess)
-        -> IoResult<~RtioFileStream> {
-        file::open(path, fm, fa).map(|fd| ~fd as ~RtioFileStream)
+        -> IoResult<~RtioFileStream:Send> {
+        file::open(path, fm, fa).map(|fd| ~fd as ~RtioFileStream:Send)
     }
     fn fs_unlink(&mut self, path: &CString) -> IoResult<()> {
         file::unlink(path)
@@ -304,25 +304,27 @@ impl rtio::IoFactory for IoFactory {
     }
 
     // misc
-    fn timer_init(&mut self) -> IoResult<~RtioTimer> {
-        timer::Timer::new().map(|t| ~t as ~RtioTimer)
+    fn timer_init(&mut self) -> IoResult<~RtioTimer:Send> {
+        timer::Timer::new().map(|t| ~t as ~RtioTimer:Send)
     }
     fn spawn(&mut self, config: ProcessConfig)
-            -> IoResult<(~RtioProcess, ~[Option<~RtioPipe>])> {
+            -> IoResult<(~RtioProcess:Send, ~[Option<~RtioPipe:Send>])> {
         process::Process::spawn(config).map(|(p, io)| {
-            (~p as ~RtioProcess,
-             io.move_iter().map(|p| p.map(|p| ~p as ~RtioPipe)).collect())
+            (~p as ~RtioProcess:Send,
+             io.move_iter().map(|p| p.map(|p| ~p as ~RtioPipe:Send)).collect())
         })
     }
     fn kill(&mut self, pid: libc::pid_t, signum: int) -> IoResult<()> {
         process::Process::kill(pid, signum)
     }
-    fn pipe_open(&mut self, fd: c_int) -> IoResult<~RtioPipe> {
-        Ok(~file::FileDesc::new(fd, true) as ~RtioPipe)
+    fn pipe_open(&mut self, fd: c_int) -> IoResult<~RtioPipe:Send> {
+        Ok(~file::FileDesc::new(fd, true) as ~RtioPipe:Send)
     }
-    fn tty_open(&mut self, fd: c_int, _readable: bool) -> IoResult<~RtioTTY> {
+    fn tty_open(&mut self, fd: c_int, _readable: bool)
+        -> IoResult<~RtioTTY:Send>
+    {
         if unsafe { libc::isatty(fd) } != 0 {
-            Ok(~file::FileDesc::new(fd, true) as ~RtioTTY)
+            Ok(~file::FileDesc::new(fd, true) as ~RtioTTY:Send)
         } else {
             Err(IoError {
                 kind: io::MismatchedFileTypeForOperation,
@@ -332,7 +334,7 @@ impl rtio::IoFactory for IoFactory {
         }
     }
     fn signal(&mut self, _signal: Signum, _channel: Sender<Signum>)
-        -> IoResult<~RtioSignal> {
+        -> IoResult<~RtioSignal:Send> {
         Err(unimpl())
     }
 }
diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs
index 6a711072942..6f6ddeec86b 100644
--- a/src/libnative/io/net.rs
+++ b/src/libnative/io/net.rs
@@ -348,8 +348,8 @@ impl rtio::RtioTcpStream for TcpStream {
         self.set_keepalive(None)
     }
 
-    fn clone(&self) -> ~rtio::RtioTcpStream {
-        ~TcpStream { inner: self.inner.clone() } as ~rtio::RtioTcpStream
+    fn clone(&self) -> ~rtio::RtioTcpStream:Send {
+        ~TcpStream { inner: self.inner.clone() } as ~rtio::RtioTcpStream:Send
     }
     fn close_write(&mut self) -> IoResult<()> {
         super::mkerr_libc(unsafe {
@@ -418,8 +418,8 @@ impl TcpListener {
 }
 
 impl rtio::RtioTcpListener for TcpListener {
-    fn listen(~self) -> IoResult<~rtio::RtioTcpAcceptor> {
-        self.native_listen(128).map(|a| ~a as ~rtio::RtioTcpAcceptor)
+    fn listen(~self) -> IoResult<~rtio::RtioTcpAcceptor:Send> {
+        self.native_listen(128).map(|a| ~a as ~rtio::RtioTcpAcceptor:Send)
     }
 }
 
@@ -461,8 +461,8 @@ impl rtio::RtioSocket for TcpAcceptor {
 }
 
 impl rtio::RtioTcpAcceptor for TcpAcceptor {
-    fn accept(&mut self) -> IoResult<~rtio::RtioTcpStream> {
-        self.native_accept().map(|s| ~s as ~rtio::RtioTcpStream)
+    fn accept(&mut self) -> IoResult<~rtio::RtioTcpStream:Send> {
+        self.native_accept().map(|s| ~s as ~rtio::RtioTcpStream:Send)
     }
 
     fn accept_simultaneously(&mut self) -> IoResult<()> { Ok(()) }
@@ -630,7 +630,7 @@ impl rtio::RtioUdpSocket for UdpSocket {
         self.set_broadcast(false)
     }
 
-    fn clone(&self) -> ~rtio::RtioUdpSocket {
-        ~UdpSocket { inner: self.inner.clone() } as ~rtio::RtioUdpSocket
+    fn clone(&self) -> ~rtio::RtioUdpSocket:Send {
+        ~UdpSocket { inner: self.inner.clone() } as ~rtio::RtioUdpSocket:Send
     }
 }
diff --git a/src/libnative/io/pipe_unix.rs b/src/libnative/io/pipe_unix.rs
index 9e81dc02cc5..e25571d02c9 100644
--- a/src/libnative/io/pipe_unix.rs
+++ b/src/libnative/io/pipe_unix.rs
@@ -150,8 +150,8 @@ impl rtio::RtioPipe for UnixStream {
         }
     }
 
-    fn clone(&self) -> ~rtio::RtioPipe {
-        ~UnixStream { inner: self.inner.clone() } as ~rtio::RtioPipe
+    fn clone(&self) -> ~rtio::RtioPipe:Send {
+        ~UnixStream { inner: self.inner.clone() } as ~rtio::RtioPipe:Send
     }
 }
 
@@ -250,8 +250,8 @@ impl UnixListener {
 }
 
 impl rtio::RtioUnixListener for UnixListener {
-    fn listen(~self) -> IoResult<~rtio::RtioUnixAcceptor> {
-        self.native_listen(128).map(|a| ~a as ~rtio::RtioUnixAcceptor)
+    fn listen(~self) -> IoResult<~rtio::RtioUnixAcceptor:Send> {
+        self.native_listen(128).map(|a| ~a as ~rtio::RtioUnixAcceptor:Send)
     }
 }
 
@@ -279,7 +279,7 @@ impl UnixAcceptor {
 }
 
 impl rtio::RtioUnixAcceptor for UnixAcceptor {
-    fn accept(&mut self) -> IoResult<~rtio::RtioPipe> {
-        self.native_accept().map(|s| ~s as ~rtio::RtioPipe)
+    fn accept(&mut self) -> IoResult<~rtio::RtioPipe:Send> {
+        self.native_accept().map(|s| ~s as ~rtio::RtioPipe:Send)
     }
 }
diff --git a/src/libnative/task.rs b/src/libnative/task.rs
index 659e417b8ad..662c6417ca8 100644
--- a/src/libnative/task.rs
+++ b/src/libnative/task.rs
@@ -35,7 +35,7 @@ pub fn new(stack_bounds: (uint, uint)) -> ~Task {
     let mut task = ~Task::new();
     let mut ops = ops();
     ops.stack_bounds = stack_bounds;
-    task.put_runtime(ops as ~rt::Runtime);
+    task.put_runtime(ops);
     return task;
 }
 
@@ -50,13 +50,13 @@ fn ops() -> ~Ops {
 }
 
 /// Spawns a function with the default configuration
-pub fn spawn(f: proc()) {
+pub fn spawn(f: proc:Send()) {
     spawn_opts(TaskOpts::new(), f)
 }
 
 /// Spawns a new task given the configuration options and a procedure to run
 /// inside the task.
-pub fn spawn_opts(opts: TaskOpts, f: proc()) {
+pub fn spawn_opts(opts: TaskOpts, f: proc:Send()) {
     let TaskOpts {
         notify_chan, name, stack_size,
         stderr, stdout,
@@ -98,7 +98,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
 
         let mut f = Some(f);
         let mut task = task;
-        task.put_runtime(ops as ~rt::Runtime);
+        task.put_runtime(ops);
         let t = task.run(|| { f.take_unwrap()() });
         drop(t);
         bookkeeping::decrement();
@@ -121,7 +121,7 @@ struct Ops {
 impl rt::Runtime for Ops {
     fn yield_now(~self, mut cur_task: ~Task) {
         // put the task back in TLS and then invoke the OS thread yield
-        cur_task.put_runtime(self as ~rt::Runtime);
+        cur_task.put_runtime(self);
         Local::put(cur_task);
         Thread::yield_now();
     }
@@ -129,7 +129,7 @@ impl rt::Runtime for Ops {
     fn maybe_yield(~self, mut cur_task: ~Task) {
         // just put the task back in TLS, on OS threads we never need to
         // opportunistically yield b/c the OS will do that for us (preemption)
-        cur_task.put_runtime(self as ~rt::Runtime);
+        cur_task.put_runtime(self);
         Local::put(cur_task);
     }
 
@@ -183,7 +183,7 @@ impl rt::Runtime for Ops {
     fn deschedule(mut ~self, times: uint, mut cur_task: ~Task,
                   f: |BlockedTask| -> Result<(), BlockedTask>) {
         let me = &mut *self as *mut Ops;
-        cur_task.put_runtime(self as ~rt::Runtime);
+        cur_task.put_runtime(self);
 
         unsafe {
             let cur_task_dupe = &*cur_task as *Task;
@@ -230,7 +230,7 @@ impl rt::Runtime for Ops {
     fn reawaken(mut ~self, mut to_wake: ~Task) {
         unsafe {
             let me = &mut *self as *mut Ops;
-            to_wake.put_runtime(self as ~rt::Runtime);
+            to_wake.put_runtime(self);
             cast::forget(to_wake);
             let guard = (*me).lock.lock();
             (*me).awoken = true;
@@ -238,8 +238,8 @@ impl rt::Runtime for Ops {
         }
     }
 
-    fn spawn_sibling(~self, mut cur_task: ~Task, opts: TaskOpts, f: proc()) {
-        cur_task.put_runtime(self as ~rt::Runtime);
+    fn spawn_sibling(~self, mut cur_task: ~Task, opts: TaskOpts, f: proc:Send()) {
+        cur_task.put_runtime(self);
         Local::put(cur_task);
 
         task::spawn_opts(opts, f);
@@ -252,7 +252,6 @@ impl rt::Runtime for Ops {
 
 #[cfg(test)]
 mod tests {
-    use std::rt::Runtime;
     use std::rt::local::Local;
     use std::rt::task::Task;
     use std::task;
@@ -335,7 +334,7 @@ mod tests {
                 let mut task: ~Task = Local::take();
                 match task.maybe_take_runtime::<Ops>() {
                     Some(ops) => {
-                        task.put_runtime(ops as ~Runtime);
+                        task.put_runtime(ops);
                     }
                     None => fail!(),
                 }
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 6aff1530104..ea7db3db67f 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -365,7 +365,7 @@ fn parse_crate_attrs(sess: &session::Session, input: &d::Input) ->
 ///
 /// The diagnostic emitter yielded to the procedure should be used for reporting
 /// errors of the compiler.
-pub fn monitor(f: proc()) {
+pub fn monitor(f: proc:Send()) {
     // FIXME: This is a hack for newsched since it doesn't support split stacks.
     // rustc needs a lot of stack! When optimizations are disabled, it needs
     // even *more* stack than usual as well.
@@ -387,7 +387,7 @@ pub fn monitor(f: proc()) {
     let mut r = io::ChanReader::new(rx);
 
     match task_builder.try(proc() {
-        io::stdio::set_stderr(~w as ~io::Writer);
+        io::stdio::set_stderr(~w);
         f()
     }) {
         Ok(()) => { /* fallthrough */ }
@@ -425,7 +425,7 @@ pub fn monitor(f: proc()) {
             // Fail so the process returns a failure code, but don't pollute the
             // output with some unnecessary failure messages, we've already
             // printed everything that we needed to.
-            io::stdio::set_stderr(~io::util::NullWriter as ~io::Writer);
+            io::stdio::set_stderr(~io::util::NullWriter);
             fail!();
         }
     }
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 09a1b1fc81a..64203db83b7 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -118,7 +118,7 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
     let old = io::stdio::set_stderr(~w1);
     spawn(proc() {
         let mut p = io::ChanReader::new(rx);
-        let mut err = old.unwrap_or(~io::stderr() as ~Writer);
+        let mut err = old.unwrap_or(~io::stderr() as ~Writer:Send);
         io::util::copy(&mut p, &mut err).unwrap();
     });
     let emitter = diagnostic::EmitterWriter::new(~w2);
diff --git a/src/librustuv/async.rs b/src/librustuv/async.rs
index bda859afc0b..5caccb348cc 100644
--- a/src/librustuv/async.rs
+++ b/src/librustuv/async.rs
@@ -27,12 +27,12 @@ pub struct AsyncWatcher {
 }
 
 struct Payload {
-    callback: ~Callback,
+    callback: ~Callback:Send,
     exit_flag: Exclusive<bool>,
 }
 
 impl AsyncWatcher {
-    pub fn new(loop_: &mut Loop, cb: ~Callback) -> AsyncWatcher {
+    pub fn new(loop_: &mut Loop, cb: ~Callback:Send) -> AsyncWatcher {
         let handle = UvHandle::alloc(None::<AsyncWatcher>, uvll::UV_ASYNC);
         assert_eq!(unsafe {
             uvll::uv_async_init(loop_.handle, handle, async_cb)
@@ -149,8 +149,7 @@ mod test_remote {
 
         let (tx, rx) = channel();
         let cb = ~MyCallback(Some(tx));
-        let watcher = AsyncWatcher::new(&mut local_loop().loop_,
-                                        cb as ~Callback);
+        let watcher = AsyncWatcher::new(&mut local_loop().loop_, cb);
 
         let thread = Thread::start(proc() {
             let mut watcher = watcher;
diff --git a/src/librustuv/idle.rs b/src/librustuv/idle.rs
index 1f059ca9fb9..bbfacf87096 100644
--- a/src/librustuv/idle.rs
+++ b/src/librustuv/idle.rs
@@ -19,11 +19,11 @@ pub struct IdleWatcher {
     handle: *uvll::uv_idle_t,
     idle_flag: bool,
     closed: bool,
-    callback: ~Callback,
+    callback: ~Callback:Send,
 }
 
 impl IdleWatcher {
-    pub fn new(loop_: &mut Loop, cb: ~Callback) -> ~IdleWatcher {
+    pub fn new(loop_: &mut Loop, cb: ~Callback:Send) -> ~IdleWatcher {
         let handle = UvHandle::alloc(None::<IdleWatcher>, uvll::UV_IDLE);
         assert_eq!(unsafe {
             uvll::uv_idle_init(loop_.handle, handle)
diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs
index cf1d95588bb..41a6651cc1c 100644
--- a/src/librustuv/lib.rs
+++ b/src/librustuv/lib.rs
@@ -126,8 +126,8 @@ pub mod stream;
 ///     // this code is running inside of a green task powered by libuv
 /// }
 /// ```
-pub fn event_loop() -> ~rtio::EventLoop {
-    ~uvio::UvEventLoop::new() as ~rtio::EventLoop
+pub fn event_loop() -> ~rtio::EventLoop:Send {
+    ~uvio::UvEventLoop::new() as ~rtio::EventLoop:Send
 }
 
 /// A type that wraps a uv handle
diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs
index 08d66e72703..cfecdd929f3 100644
--- a/src/librustuv/net.rs
+++ b/src/librustuv/net.rs
@@ -167,8 +167,8 @@ pub struct TcpListener {
     home: HomeHandle,
     handle: *uvll::uv_pipe_t,
     priv closing_task: Option<BlockedTask>,
-    priv outgoing: Sender<Result<~rtio::RtioTcpStream, IoError>>,
-    priv incoming: Receiver<Result<~rtio::RtioTcpStream, IoError>>,
+    priv outgoing: Sender<Result<~rtio::RtioTcpStream:Send, IoError>>,
+    priv incoming: Receiver<Result<~rtio::RtioTcpStream:Send, IoError>>,
 }
 
 pub struct TcpAcceptor {
@@ -295,7 +295,7 @@ impl rtio::RtioTcpStream for TcpWatcher {
         })
     }
 
-    fn clone(&self) -> ~rtio::RtioTcpStream {
+    fn clone(&self) -> ~rtio::RtioTcpStream:Send {
         ~TcpWatcher {
             handle: self.handle,
             stream: StreamWatcher::new(self.handle),
@@ -303,7 +303,7 @@ impl rtio::RtioTcpStream for TcpWatcher {
             refcount: self.refcount.clone(),
             write_access: self.write_access.clone(),
             read_access: self.read_access.clone(),
-        } as ~rtio::RtioTcpStream
+        } as ~rtio::RtioTcpStream:Send
     }
 
     fn close_write(&mut self) -> Result<(), IoError> {
@@ -397,14 +397,14 @@ impl rtio::RtioSocket for TcpListener {
 }
 
 impl rtio::RtioTcpListener for TcpListener {
-    fn listen(~self) -> Result<~rtio::RtioTcpAcceptor, IoError> {
+    fn listen(~self) -> Result<~rtio::RtioTcpAcceptor:Send, IoError> {
         // create the acceptor object from ourselves
         let mut acceptor = ~TcpAcceptor { listener: self };
 
         let _m = acceptor.fire_homing_missile();
         // FIXME: the 128 backlog should be configurable
         match unsafe { uvll::uv_listen(acceptor.listener.handle, 128, listen_cb) } {
-            0 => Ok(acceptor as ~rtio::RtioTcpAcceptor),
+            0 => Ok(acceptor as ~rtio::RtioTcpAcceptor:Send),
             n => Err(uv_error_to_io_error(UvError(n))),
         }
     }
@@ -420,7 +420,7 @@ extern fn listen_cb(server: *uvll::uv_stream_t, status: c_int) {
             });
             let client = TcpWatcher::new_home(&loop_, tcp.home().clone());
             assert_eq!(unsafe { uvll::uv_accept(server, client.handle) }, 0);
-            Ok(~client as ~rtio::RtioTcpStream)
+            Ok(~client as ~rtio::RtioTcpStream:Send)
         }
         n => Err(uv_error_to_io_error(UvError(n)))
     };
@@ -448,7 +448,7 @@ impl rtio::RtioSocket for TcpAcceptor {
 }
 
 impl rtio::RtioTcpAcceptor for TcpAcceptor {
-    fn accept(&mut self) -> Result<~rtio::RtioTcpStream, IoError> {
+    fn accept(&mut self) -> Result<~rtio::RtioTcpStream:Send, IoError> {
         self.listener.incoming.recv()
     }
 
@@ -709,14 +709,14 @@ impl rtio::RtioUdpSocket for UdpWatcher {
         })
     }
 
-    fn clone(&self) -> ~rtio::RtioUdpSocket {
+    fn clone(&self) -> ~rtio::RtioUdpSocket:Send {
         ~UdpWatcher {
             handle: self.handle,
             home: self.home.clone(),
             refcount: self.refcount.clone(),
             write_access: self.write_access.clone(),
             read_access: self.read_access.clone(),
-        } as ~rtio::RtioUdpSocket
+        } as ~rtio::RtioUdpSocket:Send
     }
 }
 
diff --git a/src/librustuv/pipe.rs b/src/librustuv/pipe.rs
index 8d5e7c6f522..e1226f0b3a9 100644
--- a/src/librustuv/pipe.rs
+++ b/src/librustuv/pipe.rs
@@ -37,8 +37,8 @@ pub struct PipeWatcher {
 pub struct PipeListener {
     home: HomeHandle,
     pipe: *uvll::uv_pipe_t,
-    priv outgoing: Sender<Result<~RtioPipe, IoError>>,
-    priv incoming: Receiver<Result<~RtioPipe, IoError>>,
+    priv outgoing: Sender<Result<~RtioPipe:Send, IoError>>,
+    priv incoming: Receiver<Result<~RtioPipe:Send, IoError>>,
 }
 
 pub struct PipeAcceptor {
@@ -139,7 +139,7 @@ impl RtioPipe for PipeWatcher {
         self.stream.write(buf).map_err(uv_error_to_io_error)
     }
 
-    fn clone(&self) -> ~RtioPipe {
+    fn clone(&self) -> ~RtioPipe:Send {
         ~PipeWatcher {
             stream: StreamWatcher::new(self.stream.handle),
             defused: false,
@@ -147,7 +147,7 @@ impl RtioPipe for PipeWatcher {
             refcount: self.refcount.clone(),
             read_access: self.read_access.clone(),
             write_access: self.write_access.clone(),
-        } as ~RtioPipe
+        } as ~RtioPipe:Send
     }
 }
 
@@ -197,14 +197,14 @@ impl PipeListener {
 }
 
 impl RtioUnixListener for PipeListener {
-    fn listen(~self) -> Result<~RtioUnixAcceptor, IoError> {
+    fn listen(~self) -> Result<~RtioUnixAcceptor:Send, IoError> {
         // create the acceptor object from ourselves
         let mut acceptor = ~PipeAcceptor { listener: self };
 
         let _m = acceptor.fire_homing_missile();
         // FIXME: the 128 backlog should be configurable
         match unsafe { uvll::uv_listen(acceptor.listener.pipe, 128, listen_cb) } {
-            0 => Ok(acceptor as ~RtioUnixAcceptor),
+            0 => Ok(acceptor as ~RtioUnixAcceptor:Send),
             n => Err(uv_error_to_io_error(UvError(n))),
         }
     }
@@ -229,7 +229,7 @@ extern fn listen_cb(server: *uvll::uv_stream_t, status: libc::c_int) {
             });
             let client = PipeWatcher::new_home(&loop_, pipe.home().clone(), false);
             assert_eq!(unsafe { uvll::uv_accept(server, client.handle()) }, 0);
-            Ok(~client as ~RtioPipe)
+            Ok(~client as ~RtioPipe:Send)
         }
         n => Err(uv_error_to_io_error(UvError(n)))
     };
@@ -246,7 +246,7 @@ impl Drop for PipeListener {
 // PipeAcceptor implementation and traits
 
 impl RtioUnixAcceptor for PipeAcceptor {
-    fn accept(&mut self) -> Result<~RtioPipe, IoError> {
+    fn accept(&mut self) -> Result<~RtioPipe:Send, IoError> {
         self.listener.incoming.recv()
     }
 }
diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs
index 15de0408795..1621ccfbf45 100644
--- a/src/librustuv/uvio.rs
+++ b/src/librustuv/uvio.rs
@@ -85,14 +85,17 @@ impl rtio::EventLoop for UvEventLoop {
         IdleWatcher::onetime(&mut self.uvio.loop_, f);
     }
 
-    fn pausable_idle_callback(&mut self, cb: ~rtio::Callback)
-        -> ~rtio::PausableIdleCallback
+    fn pausable_idle_callback(&mut self, cb: ~rtio::Callback:Send)
+        -> ~rtio::PausableIdleCallback:Send
     {
-        IdleWatcher::new(&mut self.uvio.loop_, cb) as ~rtio::PausableIdleCallback
+        IdleWatcher::new(&mut self.uvio.loop_,
+                         cb) as ~rtio::PausableIdleCallback:Send
     }
 
-    fn remote_callback(&mut self, f: ~rtio::Callback) -> ~rtio::RemoteCallback {
-        ~AsyncWatcher::new(&mut self.uvio.loop_, f) as ~rtio::RemoteCallback
+    fn remote_callback(&mut self, f: ~rtio::Callback:Send)
+        -> ~rtio::RemoteCallback:Send
+    {
+        ~AsyncWatcher::new(&mut self.uvio.loop_, f) as ~rtio::RemoteCallback:Send
     }
 
     fn io<'a>(&'a mut self) -> Option<&'a mut rtio::IoFactory> {
@@ -141,30 +144,30 @@ impl IoFactory for UvIoFactory {
     // NB: This blocks the task waiting on the connection.
     // It would probably be better to return a future
     fn tcp_connect(&mut self, addr: SocketAddr)
-        -> Result<~rtio::RtioTcpStream, IoError>
+        -> Result<~rtio::RtioTcpStream:Send, IoError>
     {
         match TcpWatcher::connect(self, addr) {
-            Ok(t) => Ok(~t as ~rtio::RtioTcpStream),
+            Ok(t) => Ok(~t as ~rtio::RtioTcpStream:Send),
             Err(e) => Err(uv_error_to_io_error(e)),
         }
     }
 
-    fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~rtio::RtioTcpListener, IoError> {
+    fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~rtio::RtioTcpListener:Send, IoError> {
         match TcpListener::bind(self, addr) {
-            Ok(t) => Ok(t as ~rtio::RtioTcpListener),
+            Ok(t) => Ok(t as ~rtio::RtioTcpListener:Send),
             Err(e) => Err(uv_error_to_io_error(e)),
         }
     }
 
-    fn udp_bind(&mut self, addr: SocketAddr) -> Result<~rtio::RtioUdpSocket, IoError> {
+    fn udp_bind(&mut self, addr: SocketAddr) -> Result<~rtio::RtioUdpSocket:Send, IoError> {
         match UdpWatcher::bind(self, addr) {
-            Ok(u) => Ok(~u as ~rtio::RtioUdpSocket),
+            Ok(u) => Ok(~u as ~rtio::RtioUdpSocket:Send),
             Err(e) => Err(uv_error_to_io_error(e)),
         }
     }
 
-    fn timer_init(&mut self) -> Result<~rtio::RtioTimer, IoError> {
-        Ok(TimerWatcher::new(self) as ~rtio::RtioTimer)
+    fn timer_init(&mut self) -> Result<~rtio::RtioTimer:Send, IoError> {
+        Ok(TimerWatcher::new(self) as ~rtio::RtioTimer:Send)
     }
 
     fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
@@ -174,12 +177,12 @@ impl IoFactory for UvIoFactory {
     }
 
     fn fs_from_raw_fd(&mut self, fd: c_int,
-                      close: rtio::CloseBehavior) -> ~rtio::RtioFileStream {
-        ~FileWatcher::new(self, fd, close) as ~rtio::RtioFileStream
+                      close: rtio::CloseBehavior) -> ~rtio::RtioFileStream:Send {
+        ~FileWatcher::new(self, fd, close) as ~rtio::RtioFileStream:Send
     }
 
     fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
-        -> Result<~rtio::RtioFileStream, IoError> {
+        -> Result<~rtio::RtioFileStream:Send, IoError> {
         let flags = match fm {
             io::Open => 0,
             io::Append => libc::O_APPEND,
@@ -195,7 +198,7 @@ impl IoFactory for UvIoFactory {
         };
 
         match FsRequest::open(self, path, flags as int, mode as int) {
-            Ok(fs) => Ok(~fs as ~rtio::RtioFileStream),
+            Ok(fs) => Ok(~fs as ~rtio::RtioFileStream:Send),
             Err(e) => Err(uv_error_to_io_error(e))
         }
     }
@@ -260,12 +263,12 @@ impl IoFactory for UvIoFactory {
     }
 
     fn spawn(&mut self, config: ProcessConfig)
-            -> Result<(~rtio::RtioProcess, ~[Option<~rtio::RtioPipe>]), IoError>
+            -> Result<(~rtio::RtioProcess:Send, ~[Option<~rtio::RtioPipe:Send>]), IoError>
     {
         match Process::spawn(self, config) {
             Ok((p, io)) => {
-                Ok((p as ~rtio::RtioProcess,
-                    io.move_iter().map(|i| i.map(|p| ~p as ~rtio::RtioPipe)).collect()))
+                Ok((p as ~rtio::RtioProcess:Send,
+                    io.move_iter().map(|i| i.map(|p| ~p as ~rtio::RtioPipe:Send)).collect()))
             }
             Err(e) => Err(uv_error_to_io_error(e)),
         }
@@ -275,40 +278,40 @@ impl IoFactory for UvIoFactory {
         Process::kill(pid, signum).map_err(uv_error_to_io_error)
     }
 
-    fn unix_bind(&mut self, path: &CString) -> Result<~rtio::RtioUnixListener, IoError>
+    fn unix_bind(&mut self, path: &CString) -> Result<~rtio::RtioUnixListener:Send, IoError>
     {
         match PipeListener::bind(self, path) {
-            Ok(p) => Ok(p as ~rtio::RtioUnixListener),
+            Ok(p) => Ok(p as ~rtio::RtioUnixListener:Send),
             Err(e) => Err(uv_error_to_io_error(e)),
         }
     }
 
-    fn unix_connect(&mut self, path: &CString) -> Result<~rtio::RtioPipe, IoError> {
+    fn unix_connect(&mut self, path: &CString) -> Result<~rtio::RtioPipe:Send, IoError> {
         match PipeWatcher::connect(self, path) {
-            Ok(p) => Ok(~p as ~rtio::RtioPipe),
+            Ok(p) => Ok(~p as ~rtio::RtioPipe:Send),
             Err(e) => Err(uv_error_to_io_error(e)),
         }
     }
 
     fn tty_open(&mut self, fd: c_int, readable: bool)
-            -> Result<~rtio::RtioTTY, IoError> {
+            -> Result<~rtio::RtioTTY:Send, IoError> {
         match TtyWatcher::new(self, fd, readable) {
-            Ok(tty) => Ok(~tty as ~rtio::RtioTTY),
+            Ok(tty) => Ok(~tty as ~rtio::RtioTTY:Send),
             Err(e) => Err(uv_error_to_io_error(e))
         }
     }
 
-    fn pipe_open(&mut self, fd: c_int) -> Result<~rtio::RtioPipe, IoError> {
+    fn pipe_open(&mut self, fd: c_int) -> Result<~rtio::RtioPipe:Send, IoError> {
         match PipeWatcher::open(self, fd) {
-            Ok(s) => Ok(~s as ~rtio::RtioPipe),
+            Ok(s) => Ok(~s as ~rtio::RtioPipe:Send),
             Err(e) => Err(uv_error_to_io_error(e))
         }
     }
 
     fn signal(&mut self, signum: Signum, channel: Sender<Signum>)
-        -> Result<~rtio::RtioSignal, IoError> {
+        -> Result<~rtio::RtioSignal:Send, IoError> {
         match SignalWatcher::new(self, signum, channel) {
-            Ok(s) => Ok(s as ~rtio::RtioSignal),
+            Ok(s) => Ok(s as ~rtio::RtioSignal:Send),
             Err(e) => Err(uv_error_to_io_error(e)),
         }
     }
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 9b93a62304c..c52cfb1e35d 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -2600,6 +2600,6 @@ mod tests {
             Ok(o) => o
         };
         let mut decoder = Decoder::new(json_obj);
-        let hm: HashMap<uint, bool> = Decodable::decode(&mut decoder);
+        let _hm: HashMap<uint, bool> = Decodable::decode(&mut decoder);
     }
 }
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()
 }
diff --git a/src/libsync/future.rs b/src/libsync/future.rs
index 74a15dc9f0e..8fc3dd3a460 100644
--- a/src/libsync/future.rs
+++ b/src/libsync/future.rs
@@ -34,7 +34,7 @@ pub struct Future<A> {
 }
 
 enum FutureState<A> {
-    Pending(proc() -> A),
+    Pending(proc:Send() -> A),
     Evaluating,
     Forced(A)
 }
@@ -90,7 +90,7 @@ impl<A> Future<A> {
         Future {state: Forced(val)}
     }
 
-    pub fn from_fn(f: proc() -> A) -> Future<A> {
+    pub fn from_fn(f: proc:Send() -> A) -> Future<A> {
         /*!
          * Create a future from a function.
          *
@@ -117,7 +117,7 @@ impl<A:Send> Future<A> {
         })
     }
 
-    pub fn spawn(blk: proc() -> A) -> Future<A> {
+    pub fn spawn(blk: proc:Send() -> A) -> Future<A> {
         /*!
          * Create a future from a unique closure.
          *
diff --git a/src/libsync/raw.rs b/src/libsync/raw.rs
index 36f0748fe71..0cb9bf77ac9 100644
--- a/src/libsync/raw.rs
+++ b/src/libsync/raw.rs
@@ -836,7 +836,7 @@ mod tests {
         let m = Arc::new(Mutex::new());
         let m2 = m.clone();
 
-        let result: result::Result<(), ~Any> = task::try(proc() {
+        let result: result::Result<(), ~Any:Send> = task::try(proc() {
             let _lock = m2.lock();
             fail!();
         });
@@ -1076,7 +1076,7 @@ mod tests {
         let x = Arc::new(RWLock::new());
         let x2 = x.clone();
 
-        let result: result::Result<(), ~Any> = task::try(proc() {
+        let result: result::Result<(), ~Any:Send> = task::try(proc() {
             lock_rwlock_in_mode(&x2, mode1, || {
                 fail!();
             })
diff --git a/src/libsync/task_pool.rs b/src/libsync/task_pool.rs
index 709dafd5b93..e1764f970c7 100644
--- a/src/libsync/task_pool.rs
+++ b/src/libsync/task_pool.rs
@@ -16,7 +16,7 @@
 use std::task;
 
 enum Msg<T> {
-    Execute(proc(&T)),
+    Execute(proc:Send(&T)),
     Quit
 }
 
@@ -41,7 +41,7 @@ impl<T> TaskPool<T> {
     /// returns a function which, given the index of the task, should return
     /// local data to be kept around in that task.
     pub fn new(n_tasks: uint,
-               init_fn_factory: || -> proc(uint) -> T)
+               init_fn_factory: || -> proc:Send(uint) -> T)
                -> TaskPool<T> {
         assert!(n_tasks >= 1);
 
@@ -49,7 +49,7 @@ impl<T> TaskPool<T> {
             let (tx, rx) = channel::<Msg<T>>();
             let init_fn = init_fn_factory();
 
-            let task_body: proc() = proc() {
+            let task_body = proc() {
                 let local_data = init_fn(i);
                 loop {
                     match rx.recv() {
@@ -73,7 +73,7 @@ impl<T> TaskPool<T> {
 
     /// Executes the function `f` on a task in the pool. The function
     /// receives a reference to the local data returned by the `init_fn`.
-    pub fn execute(&mut self, f: proc(&T)) {
+    pub fn execute(&mut self, f: proc:Send(&T)) {
         self.channels.get(self.next_index).send(Execute(f));
         self.next_index += 1;
         if self.next_index == self.channels.len() { self.next_index = 0; }
@@ -82,8 +82,8 @@ impl<T> TaskPool<T> {
 
 #[test]
 fn test_task_pool() {
-    let f: || -> proc(uint) -> uint = || {
-        let g: proc(uint) -> uint = proc(i) i;
+    let f: || -> proc:Send(uint) -> uint = || {
+        let g: proc:Send(uint) -> uint = proc(i) i;
         g
     };
     let mut pool = TaskPool::new(4, f);
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index e19c4c3026a..faeb7b4e0f2 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -79,7 +79,7 @@ impl SpanHandler {
 // others log errors for later reporting.
 pub struct Handler {
     err_count: Cell<uint>,
-    emit: RefCell<~Emitter>,
+    emit: RefCell<~Emitter:Send>,
 }
 
 impl Handler {
@@ -148,7 +148,7 @@ pub fn default_handler() -> Handler {
     mk_handler(~EmitterWriter::stderr())
 }
 
-pub fn mk_handler(e: ~Emitter) -> Handler {
+pub fn mk_handler(e: ~Emitter:Send) -> Handler {
     Handler {
         err_count: Cell::new(0),
         emit: RefCell::new(e),
@@ -221,7 +221,7 @@ pub struct EmitterWriter {
 
 enum Destination {
     Terminal(term::Terminal<io::stdio::StdWriter>),
-    Raw(~Writer),
+    Raw(~Writer:Send),
 }
 
 impl EmitterWriter {
@@ -238,7 +238,7 @@ impl EmitterWriter {
         }
     }
 
-    pub fn new(dst: ~Writer) -> EmitterWriter {
+    pub fn new(dst: ~Writer:Send) -> EmitterWriter {
         EmitterWriter { dst: Raw(dst) }
     }
 }
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 96313c26f1f..039b118b327 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -123,7 +123,7 @@ pub enum TestFn {
     StaticTestFn(fn()),
     StaticBenchFn(fn(&mut BenchHarness)),
     StaticMetricFn(proc(&mut MetricMap)),
-    DynTestFn(proc()),
+    DynTestFn(proc:Send()),
     DynMetricFn(proc(&mut MetricMap)),
     DynBenchFn(~TDynBenchFn)
 }
@@ -948,7 +948,7 @@ pub fn run_test(force_ignore: bool,
     #[allow(deprecated_owned_vector)]
     fn run_test_inner(desc: TestDesc,
                       monitor_ch: Sender<MonitorMsg>,
-                      testfn: proc()) {
+                      testfn: proc:Send()) {
         spawn(proc() {
             let (tx, rx) = channel();
             let mut reader = ChanReader::new(rx);
@@ -958,8 +958,8 @@ pub fn run_test(force_ignore: bool,
                 DynTestName(ref name) => name.clone().into_maybe_owned(),
                 StaticTestName(name) => name.into_maybe_owned(),
             });
-            task.opts.stdout = Some(~stdout as ~Writer);
-            task.opts.stderr = Some(~stderr as ~Writer);
+            task.opts.stdout = Some(~stdout as ~Writer:Send);
+            task.opts.stderr = Some(~stderr as ~Writer:Send);
             let result_future = task.future_result();
             task.spawn(testfn);
 
diff --git a/src/libworkcache/lib.rs b/src/libworkcache/lib.rs
index 9c0328d4b11..3e513472027 100644
--- a/src/libworkcache/lib.rs
+++ b/src/libworkcache/lib.rs
@@ -394,14 +394,14 @@ impl<'a> Prep<'a> {
     pub fn exec<'a, T:Send +
         Encodable<json::Encoder<'a>> +
         Decodable<json::Decoder>>(
-            &'a self, blk: proc(&mut Exec) -> T) -> T {
+            &'a self, blk: proc:Send(&mut Exec) -> T) -> T {
         self.exec_work(blk).unwrap()
     }
 
     fn exec_work<'a, T:Send +
         Encodable<json::Encoder<'a>> +
         Decodable<json::Decoder>>( // FIXME(#5121)
-            &'a self, blk: proc(&mut Exec) -> T) -> Work<'a, T> {
+            &'a self, blk: proc:Send(&mut Exec) -> T) -> Work<'a, T> {
         let mut bo = Some(blk);
 
         debug!("exec_work: looking up {} and {:?}", self.fn_name,
diff --git a/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs b/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs
index 1a0fb8fe629..6dc62932de2 100644
--- a/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs
+++ b/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs
@@ -29,7 +29,7 @@ impl Drop for Foo {
 
 #[macro_registrar]
 pub fn registrar(_: |Name, SyntaxExtension|) {
-    local_data_key!(foo: ~Any);
-    local_data::set(foo, ~Foo { foo: 10 } as ~Any);
+    local_data_key!(foo: ~Any:Send);
+    local_data::set(foo, ~Foo { foo: 10 } as ~Any:Send);
 }
 
diff --git a/src/test/compile-fail/issue-7013.rs b/src/test/compile-fail/issue-7013.rs
index 5c84cbe00a9..6a7f01e6767 100644
--- a/src/test/compile-fail/issue-7013.rs
+++ b/src/test/compile-fail/issue-7013.rs
@@ -31,12 +31,12 @@ impl Foo for B
 
 struct A
 {
-    v: ~Foo,
+    v: ~Foo:Send,
 }
 
 fn main()
 {
-    let a = A {v: ~B{v: None} as ~Foo};
+    let a = A {v: ~B{v: None} as ~Foo:Send};
     //~^ ERROR cannot pack type `~B`, which does not fulfill `Send`
     let v = Rc::new(RefCell::new(a));
     let w = v.clone();
diff --git a/src/test/compile-fail/kindck-nonsendable-1.rs b/src/test/compile-fail/kindck-nonsendable-1.rs
index 02c58ba5ee3..5de2b6b4bb5 100644
--- a/src/test/compile-fail/kindck-nonsendable-1.rs
+++ b/src/test/compile-fail/kindck-nonsendable-1.rs
@@ -14,7 +14,8 @@ fn foo(_x: @uint) {}
 
 fn main() {
     let x = @3u;
-    let _: proc() = proc() foo(x); //~ ERROR does not fulfill `Send`
-    let _: proc() = proc() foo(x); //~ ERROR does not fulfill `Send`
-    let _: proc() = proc() foo(x); //~ ERROR does not fulfill `Send`
+    let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send`
+    let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send`
+    let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send`
+    let _: proc() = proc() foo(x);
 }
diff --git a/src/test/compile-fail/trait-bounds-sugar.rs b/src/test/compile-fail/trait-bounds-sugar.rs
index 988057bc7b1..32c23a3efdd 100644
--- a/src/test/compile-fail/trait-bounds-sugar.rs
+++ b/src/test/compile-fail/trait-bounds-sugar.rs
@@ -12,7 +12,7 @@
 
 trait Foo {}
 
-fn a(_x: ~Foo) { // should be same as ~Foo:Send
+fn a(_x: ~Foo:Send) {
 }
 
 fn b(_x: &'static Foo) { // should be same as &'static Foo:'static
diff --git a/src/test/run-fail/fail-macro-any.rs b/src/test/run-fail/fail-macro-any.rs
index 9bedd8c8cc8..d812e19e1c8 100644
--- a/src/test/run-fail/fail-macro-any.rs
+++ b/src/test/run-fail/fail-macro-any.rs
@@ -11,5 +11,5 @@
 // error-pattern:failed at '~Any'
 
 fn main() {
-    fail!(~413 as ~::std::any::Any);
+    fail!(~413 as ~::std::any::Any:Send);
 }
diff --git a/src/test/run-fail/unwind-box-fn-unique.rs b/src/test/run-fail/unwind-box-fn-unique.rs
index a49760f3c58..4a6f37c91b7 100644
--- a/src/test/run-fail/unwind-box-fn-unique.rs
+++ b/src/test/run-fail/unwind-box-fn-unique.rs
@@ -18,7 +18,7 @@ fn failfn() {
 
 fn main() {
     let y = ~0;
-    let x: @proc() = @(proc() {
+    let x: @proc:Send() = @(proc() {
         println!("{:?}", y.clone());
     });
     failfn();
diff --git a/src/test/run-pass/capturing-logging.rs b/src/test/run-pass/capturing-logging.rs
index 97dfbb0d8e2..6c1b2f4653a 100644
--- a/src/test/run-pass/capturing-logging.rs
+++ b/src/test/run-pass/capturing-logging.rs
@@ -42,7 +42,7 @@ fn main() {
     let (tx, rx) = channel();
     let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
     spawn(proc() {
-        set_logger(~MyWriter(w) as ~Logger);
+        set_logger(~MyWriter(w) as ~Logger:Send);
         debug!("debug");
         info!("info");
     });
diff --git a/src/test/run-pass/clone-with-exterior.rs b/src/test/run-pass/clone-with-exterior.rs
index 6db42c1e2ee..4f3db3a5f77 100644
--- a/src/test/run-pass/clone-with-exterior.rs
+++ b/src/test/run-pass/clone-with-exterior.rs
@@ -18,7 +18,7 @@ struct Pair {
 pub fn main() {
     let z = ~Pair { a : 10, b : 12};
 
-    let f: proc() = proc() {
+    let f: proc:Send() = proc() {
         assert_eq!(z.a, 10);
         assert_eq!(z.b, 12);
     };
diff --git a/src/test/run-pass/issue-2190-1.rs b/src/test/run-pass/issue-2190-1.rs
index 0580dd89a30..d04717e380b 100644
--- a/src/test/run-pass/issue-2190-1.rs
+++ b/src/test/run-pass/issue-2190-1.rs
@@ -12,13 +12,13 @@ use std::task;
 
 static generations: uint = 1024+256+128+49;
 
-fn spawn(f: proc()) {
+fn spawn(f: proc:Send()) {
     let mut t = task::task();
     t.opts.stack_size = Some(32 * 1024);
     t.spawn(f);
 }
 
-fn child_no(x: uint) -> proc() {
+fn child_no(x: uint) -> proc:Send() {
     proc() {
         if x < generations {
             spawn(child_no(x+1));
diff --git a/src/test/run-pass/issue-3609.rs b/src/test/run-pass/issue-3609.rs
index da620ffeb0d..1f1de9ddb9b 100644
--- a/src/test/run-pass/issue-3609.rs
+++ b/src/test/run-pass/issue-3609.rs
@@ -11,7 +11,7 @@
 use std::task;
 
 type RingBuffer = Vec<f64> ;
-type SamplesFn = proc(samples: &RingBuffer);
+type SamplesFn = proc:Send(samples: &RingBuffer);
 
 enum Msg
 {
diff --git a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs
index 835b5990ac2..ac3dd80c383 100644
--- a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs
+++ b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs
@@ -18,7 +18,7 @@ fn test05_start(f: proc(int)) {
 
 fn test05() {
     let three = ~3;
-    let fn_to_send: proc(int) = proc(n) {
+    let fn_to_send: proc:Send(int) = proc(n) {
         println!("{}", *three + n); // will copy x into the closure
         assert_eq!(*three, 3);
     };
diff --git a/src/test/run-pass/tempfile.rs b/src/test/run-pass/tempfile.rs
index 873269190c5..e2806421518 100644
--- a/src/test/run-pass/tempfile.rs
+++ b/src/test/run-pass/tempfile.rs
@@ -36,7 +36,7 @@ fn test_tempdir() {
 
 fn test_rm_tempdir() {
     let (tx, rx) = channel();
-    let f: proc() = proc() {
+    let f: proc:Send() = proc() {
         let tmp = TempDir::new("test_rm_tempdir").unwrap();
         tx.send(tmp.path().clone());
         fail!("fail to unwind past `tmp`");
@@ -47,7 +47,7 @@ fn test_rm_tempdir() {
 
     let tmp = TempDir::new("test_rm_tempdir").unwrap();
     let path = tmp.path().clone();
-    let f: proc() = proc() {
+    let f: proc:Send() = proc() {
         let _tmp = tmp;
         fail!("fail to unwind past `tmp`");
     };
@@ -56,7 +56,7 @@ fn test_rm_tempdir() {
 
     let path;
     {
-        let f: proc() -> TempDir = proc() {
+        let f = proc() {
             TempDir::new("test_rm_tempdir").unwrap()
         };
         let tmp = task::try(f).ok().expect("test_rm_tmdir");
diff --git a/src/test/run-pass/trait-bounds-basic.rs b/src/test/run-pass/trait-bounds-basic.rs
index acc3ca508b2..6059e5e95ee 100644
--- a/src/test/run-pass/trait-bounds-basic.rs
+++ b/src/test/run-pass/trait-bounds-basic.rs
@@ -26,7 +26,7 @@ fn d(x: ~Foo:Send) {
 }
 
 fn e(x: ~Foo) { // sugar for ~Foo:Owned
-    b(x);
+    a(x);
 }
 
 pub fn main() { }
diff --git a/src/test/run-pass/trait-cast.rs b/src/test/run-pass/trait-cast.rs
index 490c77d98cd..7a53df8737c 100644
--- a/src/test/run-pass/trait-cast.rs
+++ b/src/test/run-pass/trait-cast.rs
@@ -18,7 +18,7 @@ struct Tree(@RefCell<TreeR>);
 struct TreeR {
     left: Option<Tree>,
     right: Option<Tree>,
-    val: ~to_str
+    val: ~to_str:Send
 }
 
 trait to_str {
@@ -53,10 +53,10 @@ fn foo<T:to_str>(x: T) -> ~str { x.to_str_() }
 pub fn main() {
     let t1 = Tree(@RefCell::new(TreeR{left: None,
                                       right: None,
-                                      val: ~1 as ~to_str}));
+                                      val: ~1 as ~to_str:Send}));
     let t2 = Tree(@RefCell::new(TreeR{left: Some(t1),
                                       right: Some(t1),
-                                      val: ~2 as ~to_str}));
+                                      val: ~2 as ~to_str:Send}));
     let expected = ~"[2, some([1, none, none]), some([1, none, none])]";
     assert!(t2.to_str_() == expected);
     assert!(foo(t2) == expected);
diff --git a/src/test/run-pass/uniq-cc-generic.rs b/src/test/run-pass/uniq-cc-generic.rs
index 41e921ff6e4..78fa7520f33 100644
--- a/src/test/run-pass/uniq-cc-generic.rs
+++ b/src/test/run-pass/uniq-cc-generic.rs
@@ -19,12 +19,11 @@ enum maybe_pointy {
 
 struct Pointy {
     a : maybe_pointy,
-    d : proc() -> uint,
+    d : proc:Send() -> uint,
 }
 
-fn make_uniq_closure<A:Send>(a: A) -> proc() -> uint {
-    let result: proc() -> uint = proc() &a as *A as uint;
-    result
+fn make_uniq_closure<A:Send>(a: A) -> proc:Send() -> uint {
+    proc() { &a as *A as uint }
 }
 
 fn empty_pointy() -> @RefCell<Pointy> {
diff --git a/src/test/run-pass/uniq-cc.rs b/src/test/run-pass/uniq-cc.rs
index 57fc9ac6773..aa048a239db 100644
--- a/src/test/run-pass/uniq-cc.rs
+++ b/src/test/run-pass/uniq-cc.rs
@@ -20,7 +20,7 @@ enum maybe_pointy {
 struct Pointy {
     a : maybe_pointy,
     c : ~int,
-    d : proc()->(),
+    d : proc:Send()->(),
 }
 
 fn empty_pointy() -> @RefCell<Pointy> {