about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-02-17 17:32:16 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-02-17 17:32:16 -0800
commitba8ce4c2c27643cccfbbc481a19bcf4b7747cc89 (patch)
tree158a22ef66d1d80f0e9e5d01dffb13496af236c2
parent6ac3799b75780f8c18bc38331403e1e517b89bab (diff)
parent7a14f4994eb4527a38d02c61fa83822df02f7b5d (diff)
downloadrust-ba8ce4c2c27643cccfbbc481a19bcf4b7747cc89.tar.gz
rust-ba8ce4c2c27643cccfbbc481a19bcf4b7747cc89.zip
rollup merge of #22319: huonw/send-is-not-static
Conflicts:
	src/libstd/sync/task_pool.rs
	src/libstd/thread.rs
	src/libtest/lib.rs
	src/test/bench/shootout-reverse-complement.rs
	src/test/bench/shootout-spectralnorm.rs
-rw-r--r--src/libcore/marker.rs18
-rw-r--r--src/librustc/middle/traits/select.rs32
-rw-r--r--src/librustc/util/ppaux.rs5
-rw-r--r--src/libstd/old_io/net/pipe.rs2
-rw-r--r--src/libstd/process.rs2
-rw-r--r--src/libstd/rt/at_exit_imp.rs4
-rw-r--r--src/libstd/rt/mod.rs2
-rw-r--r--src/libstd/rt/unwind.rs4
-rw-r--r--src/libstd/sync/future.rs8
-rw-r--r--src/libstd/sync/mpsc/mod.rs30
-rw-r--r--src/libstd/sync/mpsc/mpsc_queue.rs6
-rw-r--r--src/libstd/sync/mpsc/oneshot.rs4
-rw-r--r--src/libstd/sync/mpsc/select.rs6
-rw-r--r--src/libstd/sync/mpsc/shared.rs4
-rw-r--r--src/libstd/sync/mpsc/spsc_queue.rs10
-rw-r--r--src/libstd/sync/mpsc/stream.rs4
-rw-r--r--src/libstd/sync/mpsc/sync.rs12
-rw-r--r--src/libstd/sync/mutex.rs8
-rw-r--r--src/libstd/sync/task_pool.rs10
-rw-r--r--src/libstd/sys/common/helper_thread.rs2
-rw-r--r--src/libstd/thread.rs16
-rw-r--r--src/libstd/thunk.rs19
-rw-r--r--src/libterm/terminfo/mod.rs7
-rw-r--r--src/libterm/win.rs6
-rw-r--r--src/libtest/lib.rs4
-rw-r--r--src/test/auxiliary/cci_capture_clause.rs2
-rw-r--r--src/test/bench/shootout-reverse-complement.rs21
-rw-r--r--src/test/bench/shootout-spectralnorm.rs20
-rw-r--r--src/test/compile-fail/builtin-superkinds-simple.rs4
-rw-r--r--src/test/compile-fail/coherence-impls-builtin.rs9
-rw-r--r--src/test/compile-fail/kindck-impl-type-params.rs2
-rw-r--r--src/test/compile-fail/kindck-send-object.rs4
-rw-r--r--src/test/compile-fail/kindck-send-object1.rs8
-rw-r--r--src/test/compile-fail/kindck-send-object2.rs4
-rw-r--r--src/test/compile-fail/kindck-send-owned.rs4
-rw-r--r--src/test/compile-fail/kindck-send-region-pointers.rs34
-rw-r--r--src/test/compile-fail/regions-bounded-by-send.rs83
-rw-r--r--src/test/compile-fail/regions-pattern-typing-issue-19552.rs4
-rwxr-xr-xsrc/test/compile-fail/send-is-not-static-ensures-scoping.rs25
-rw-r--r--src/test/compile-fail/trait-bounds-cant-coerce.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-capabilities-transitive.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-capabilities-xc.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-capabilities.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-self-type.rs4
-rw-r--r--src/test/run-pass/issue-18188.rs10
-rw-r--r--src/test/run-pass/issue-21058.rs4
-rw-r--r--src/test/run-pass/issue-2190-1.rs4
-rwxr-xr-xsrc/test/run-pass/send-is-not-static-par-for.rs47
-rw-r--r--src/test/run-pass/send-type-inference.rs2
49 files changed, 231 insertions, 297 deletions
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index da93d4f6ca4..7e8472b91dc 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -32,9 +32,19 @@ use clone::Clone;
            reason = "will be overhauled with new lifetime rules; see RFC 458")]
 #[lang="send"]
 #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
+#[cfg(stage0)] // SNAP ac134f7 remove after stage0
 pub unsafe trait Send: 'static {
     // empty.
 }
+/// Types able to be transferred across thread boundaries.
+#[unstable(feature = "core",
+           reason = "will be overhauled with new lifetime rules; see RFC 458")]
+#[lang="send"]
+#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
+#[cfg(not(stage0))]
+pub unsafe trait Send {
+    // empty.
+}
 
 /// Types with a constant size known at compile-time.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -424,3 +434,11 @@ pub struct NoCopy;
 #[lang="managed_bound"]
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Managed;
+
+#[cfg(not(stage0))] // SNAP ac134f7 remove this attribute after the next snapshot
+mod impls {
+    use super::{Send, Sync, Sized};
+
+    unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {}
+    unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {}
+}
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 6f58f4655fe..061557eb7dc 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -20,7 +20,7 @@ use self::EvaluationResult::*;
 use super::{DerivedObligationCause};
 use super::{project};
 use super::project::Normalized;
-use super::{PredicateObligation, Obligation, TraitObligation, ObligationCause};
+use super::{PredicateObligation, TraitObligation, ObligationCause};
 use super::{ObligationCauseCode, BuiltinDerivedObligation};
 use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
 use super::{Selection};
@@ -34,7 +34,7 @@ use super::{util};
 use middle::fast_reject;
 use middle::mem_categorization::Typer;
 use middle::subst::{Subst, Substs, TypeSpace, VecPerParamSpace};
-use middle::ty::{self, AsPredicate, RegionEscape, ToPolyTraitRef, Ty};
+use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
 use middle::infer;
 use middle::infer::{InferCtxt, TypeFreshener};
 use middle::ty_fold::TypeFoldable;
@@ -1459,22 +1459,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
                     ty::BoundSync |
                     ty::BoundSend => {
-                        // Note: technically, a region pointer is only
-                        // sendable if it has lifetime
-                        // `'static`. However, we don't take regions
-                        // into account when doing trait matching:
-                        // instead, when we decide that `T : Send`, we
-                        // will register a separate constraint with
-                        // the region inferencer that `T : 'static`
-                        // holds as well (because the trait `Send`
-                        // requires it). This will ensure that there
-                        // is no borrowed data in `T` (or else report
-                        // an inference error). The reason we do it
-                        // this way is that we do not yet *know* what
-                        // lifetime the borrowed reference has, since
-                        // we haven't finished running inference -- in
-                        // other words, there's a kind of
-                        // chicken-and-egg problem.
                         Ok(If(vec![referent_ty]))
                     }
                 }
@@ -1817,21 +1801,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
             })
         }).collect::<Result<_, _>>();
-        let mut obligations = match obligations {
+        let obligations = match obligations {
             Ok(o) => o,
             Err(ErrorReported) => Vec::new()
         };
 
-        // as a special case, `Send` requires `'static`
-        if bound == ty::BoundSend {
-            obligations.push(Obligation {
-                cause: obligation.cause.clone(),
-                recursion_depth: obligation.recursion_depth+1,
-                predicate: ty::Binder(ty::OutlivesPredicate(obligation.self_ty(),
-                                                            ty::ReStatic)).as_predicate(),
-            });
-        }
-
         let obligations = VecPerParamSpace::new(obligations, Vec::new(), Vec::new());
 
         debug!("vtable_builtin_data: obligations={}",
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 0363978bada..426101e858a 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -697,9 +697,8 @@ impl<'tcx> UserString<'tcx> for ty::TyTrait<'tcx> {
         }
 
         // Region, if not obviously implied by builtin bounds.
-        if bounds.region_bound != ty::ReStatic ||
-            !bounds.builtin_bounds.contains(&ty::BoundSend)
-        { // Region bound is implied by builtin bounds:
+        if bounds.region_bound != ty::ReStatic {
+            // Region bound is implied by builtin bounds:
             components.push(bounds.region_bound.user_string(tcx));
         }
 
diff --git a/src/libstd/old_io/net/pipe.rs b/src/libstd/old_io/net/pipe.rs
index 8e0126d5ec8..6b32d936c05 100644
--- a/src/libstd/old_io/net/pipe.rs
+++ b/src/libstd/old_io/net/pipe.rs
@@ -287,7 +287,7 @@ mod tests {
 
     pub fn smalltest<F,G>(server: F, client: G)
         where F : FnOnce(UnixStream), F : Send,
-              G : FnOnce(UnixStream), G : Send
+              G : FnOnce(UnixStream), G : Send + 'static
     {
         let path1 = next_test_unix();
         let path2 = path1.clone();
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 0152bc1148b..5baa095d359 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -458,7 +458,7 @@ impl Child {
     /// the parent waits for the child to exit.
     pub fn wait_with_output(mut self) -> io::Result<Output> {
         drop(self.stdin.take());
-        fn read<T: Read + Send>(stream: Option<T>) -> Receiver<io::Result<Vec<u8>>> {
+        fn read<T: Read + Send + 'static>(stream: Option<T>) -> Receiver<io::Result<Vec<u8>>> {
             let (tx, rx) = channel();
             match stream {
                 Some(stream) => {
diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs
index 3f15cf71ec3..72486fc55d4 100644
--- a/src/libstd/rt/at_exit_imp.rs
+++ b/src/libstd/rt/at_exit_imp.rs
@@ -20,7 +20,7 @@ use mem;
 use thunk::Thunk;
 use sys_common::mutex::{Mutex, MUTEX_INIT};
 
-type Queue = Vec<Thunk>;
+type Queue = Vec<Thunk<'static>>;
 
 // NB these are specifically not types from `std::sync` as they currently rely
 // on poisoning and this module needs to operate at a lower level than requiring
@@ -65,7 +65,7 @@ pub fn cleanup() {
     }
 }
 
-pub fn push(f: Thunk) {
+pub fn push(f: Thunk<'static>) {
     unsafe {
         LOCK.lock();
         init();
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 00088d6d99a..42cca73e5e2 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -148,7 +148,7 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
 ///
 /// It is forbidden for procedures to register more `at_exit` handlers when they
 /// are running, and doing so will lead to a process abort.
-pub fn at_exit<F:FnOnce()+Send>(f: F) {
+pub fn at_exit<F:FnOnce()+Send+'static>(f: F) {
     at_exit_imp::push(Thunk::new(f));
 }
 
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index c9bbea27e4a..1f5eb3af695 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -74,7 +74,7 @@ use rt::libunwind as uw;
 
 struct Exception {
     uwe: uw::_Unwind_Exception,
-    cause: Option<Box<Any + Send>>,
+    cause: Option<Box<Any + Send + 'static>>,
 }
 
 pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: uint);
@@ -161,7 +161,7 @@ pub fn panicking() -> bool {
 #[inline(never)]
 #[no_mangle]
 #[allow(private_no_mangle_fns)]
-fn rust_panic(cause: Box<Any + Send>) -> ! {
+fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
     rtdebug!("begin_unwind()");
 
     unsafe {
diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs
index ae5c1e1b4a5..d60e2738808 100644
--- a/src/libstd/sync/future.rs
+++ b/src/libstd/sync/future.rs
@@ -46,7 +46,7 @@ pub struct Future<A> {
 }
 
 enum FutureState<A> {
-    Pending(Thunk<(),A>),
+    Pending(Thunk<'static,(),A>),
     Evaluating,
     Forced(A)
 }
@@ -103,7 +103,7 @@ impl<A> Future<A> {
     }
 
     pub fn from_fn<F>(f: F) -> Future<A>
-        where F : FnOnce() -> A, F : Send
+        where F : FnOnce() -> A, F : Send + 'static
     {
         /*!
          * Create a future from a function.
@@ -117,7 +117,7 @@ impl<A> Future<A> {
     }
 }
 
-impl<A:Send> Future<A> {
+impl<A:Send+'static> Future<A> {
     pub fn from_receiver(rx: Receiver<A>) -> Future<A> {
         /*!
          * Create a future from a port
@@ -132,7 +132,7 @@ impl<A:Send> Future<A> {
     }
 
     pub fn spawn<F>(blk: F) -> Future<A>
-        where F : FnOnce() -> A, F : Send
+        where F : FnOnce() -> A, F : Send + 'static
     {
         /*!
          * Create a future from a unique closure.
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index 862745a05eb..410d3c0ecd5 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -345,7 +345,7 @@ pub struct Receiver<T> {
 
 // The receiver port can be sent from place to place, so long as it
 // is not used to receive non-sendable things.
-unsafe impl<T:Send> Send for Receiver<T> { }
+unsafe impl<T: Send + 'static> Send for Receiver<T> { }
 
 /// An iterator over messages on a receiver, this iterator will block
 /// whenever `next` is called, waiting for a new message, and `None` will be
@@ -364,7 +364,7 @@ pub struct Sender<T> {
 
 // The send port can be sent from place to place, so long as it
 // is not used to send non-sendable things.
-unsafe impl<T:Send> Send for Sender<T> { }
+unsafe impl<T: Send + 'static> Send for Sender<T> { }
 
 /// The sending-half of Rust's synchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
@@ -373,7 +373,7 @@ pub struct SyncSender<T> {
     inner: Arc<UnsafeCell<sync::Packet<T>>>,
 }
 
-unsafe impl<T:Send> Send for SyncSender<T> {}
+unsafe impl<T: Send + 'static> Send for SyncSender<T> {}
 
 impl<T> !Sync for SyncSender<T> {}
 
@@ -485,7 +485,7 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
 /// println!("{:?}", rx.recv().unwrap());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
+pub fn channel<T: Send + 'static>() -> (Sender<T>, Receiver<T>) {
     let a = Arc::new(UnsafeCell::new(oneshot::Packet::new()));
     (Sender::new(Flavor::Oneshot(a.clone())), Receiver::new(Flavor::Oneshot(a)))
 }
@@ -525,7 +525,7 @@ pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
 /// assert_eq!(rx.recv().unwrap(), 2);
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
+pub fn sync_channel<T: Send + 'static>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
     let a = Arc::new(UnsafeCell::new(sync::Packet::new(bound)));
     (SyncSender::new(a.clone()), Receiver::new(Flavor::Sync(a)))
 }
@@ -534,7 +534,7 @@ pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
 // Sender
 ////////////////////////////////////////////////////////////////////////////////
 
-impl<T: Send> Sender<T> {
+impl<T: Send + 'static> Sender<T> {
     fn new(inner: Flavor<T>) -> Sender<T> {
         Sender {
             inner: UnsafeCell::new(inner),
@@ -616,7 +616,7 @@ impl<T: Send> Sender<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Clone for Sender<T> {
+impl<T: Send + 'static> Clone for Sender<T> {
     fn clone(&self) -> Sender<T> {
         let (packet, sleeper, guard) = match *unsafe { self.inner() } {
             Flavor::Oneshot(ref p) => {
@@ -662,7 +662,7 @@ impl<T: Send> Clone for Sender<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Drop for Sender<T> {
+impl<T: Send + 'static> Drop for Sender<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
             Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_chan(); },
@@ -677,7 +677,7 @@ impl<T: Send> Drop for Sender<T> {
 // SyncSender
 ////////////////////////////////////////////////////////////////////////////////
 
-impl<T: Send> SyncSender<T> {
+impl<T: Send + 'static> SyncSender<T> {
     fn new(inner: Arc<UnsafeCell<sync::Packet<T>>>) -> SyncSender<T> {
         SyncSender { inner: inner }
     }
@@ -717,7 +717,7 @@ impl<T: Send> SyncSender<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Clone for SyncSender<T> {
+impl<T: Send + 'static> Clone for SyncSender<T> {
     fn clone(&self) -> SyncSender<T> {
         unsafe { (*self.inner.get()).clone_chan(); }
         return SyncSender::new(self.inner.clone());
@@ -726,7 +726,7 @@ impl<T: Send> Clone for SyncSender<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Drop for SyncSender<T> {
+impl<T: Send + 'static> Drop for SyncSender<T> {
     fn drop(&mut self) {
         unsafe { (*self.inner.get()).drop_chan(); }
     }
@@ -736,7 +736,7 @@ impl<T: Send> Drop for SyncSender<T> {
 // Receiver
 ////////////////////////////////////////////////////////////////////////////////
 
-impl<T: Send> Receiver<T> {
+impl<T: Send + 'static> Receiver<T> {
     fn new(inner: Flavor<T>) -> Receiver<T> {
         Receiver { inner: UnsafeCell::new(inner) }
     }
@@ -855,7 +855,7 @@ impl<T: Send> Receiver<T> {
     }
 }
 
-impl<T: Send> select::Packet for Receiver<T> {
+impl<T: Send + 'static> select::Packet for Receiver<T> {
     fn can_recv(&self) -> bool {
         loop {
             let new_port = match *unsafe { self.inner() } {
@@ -942,7 +942,7 @@ impl<T: Send> select::Packet for Receiver<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: Send> Iterator for Iter<'a, T> {
+impl<'a, T: Send + 'static> Iterator for Iter<'a, T> {
     type Item = T;
 
     fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
@@ -950,7 +950,7 @@ impl<'a, T: Send> Iterator for Iter<'a, T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Drop for Receiver<T> {
+impl<T: Send + 'static> Drop for Receiver<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
             Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_port(); },
diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs
index c374f8bbcee..0a4ff8769ab 100644
--- a/src/libstd/sync/mpsc/mpsc_queue.rs
+++ b/src/libstd/sync/mpsc/mpsc_queue.rs
@@ -78,7 +78,7 @@ pub struct Queue<T> {
 }
 
 unsafe impl<T:Send> Send for Queue<T> { }
-unsafe impl<T:Send> Sync for Queue<T> { }
+unsafe impl<T: Send + 'static> Sync for Queue<T> { }
 
 impl<T> Node<T> {
     unsafe fn new(v: Option<T>) -> *mut Node<T> {
@@ -89,7 +89,7 @@ impl<T> Node<T> {
     }
 }
 
-impl<T: Send> Queue<T> {
+impl<T: Send + 'static> Queue<T> {
     /// Creates a new queue that is safe to share among multiple producers and
     /// one consumer.
     pub fn new() -> Queue<T> {
@@ -140,7 +140,7 @@ impl<T: Send> Queue<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Drop for Queue<T> {
+impl<T: Send + 'static> Drop for Queue<T> {
     fn drop(&mut self) {
         unsafe {
             let mut cur = *self.tail.get();
diff --git a/src/libstd/sync/mpsc/oneshot.rs b/src/libstd/sync/mpsc/oneshot.rs
index eb45681fa62..55b2caf7c6d 100644
--- a/src/libstd/sync/mpsc/oneshot.rs
+++ b/src/libstd/sync/mpsc/oneshot.rs
@@ -88,7 +88,7 @@ enum MyUpgrade<T> {
     GoUp(Receiver<T>),
 }
 
-impl<T: Send> Packet<T> {
+impl<T: Send + 'static> Packet<T> {
     pub fn new() -> Packet<T> {
         Packet {
             data: None,
@@ -368,7 +368,7 @@ impl<T: Send> Packet<T> {
 }
 
 #[unsafe_destructor]
-impl<T: Send> Drop for Packet<T> {
+impl<T: Send + 'static> Drop for Packet<T> {
     fn drop(&mut self) {
         assert_eq!(self.state.load(Ordering::SeqCst), DISCONNECTED);
     }
diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs
index 652a9ebb020..4756ef612f9 100644
--- a/src/libstd/sync/mpsc/select.rs
+++ b/src/libstd/sync/mpsc/select.rs
@@ -134,7 +134,7 @@ impl Select {
     /// Creates a new handle into this receiver set for a new receiver. Note
     /// that this does *not* add the receiver to the receiver set, for that you
     /// must call the `add` method on the handle itself.
-    pub fn handle<'a, T: Send>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> {
+    pub fn handle<'a, T: Send + 'static>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> {
         let id = self.next_id.get();
         self.next_id.set(id + 1);
         Handle {
@@ -251,7 +251,7 @@ impl Select {
     fn iter(&self) -> Packets { Packets { cur: self.head } }
 }
 
-impl<'rx, T: Send> Handle<'rx, T> {
+impl<'rx, T: Send + 'static> Handle<'rx, T> {
     /// Retrieve the id of this handle.
     #[inline]
     pub fn id(&self) -> uint { self.id }
@@ -322,7 +322,7 @@ impl Drop for Select {
 }
 
 #[unsafe_destructor]
-impl<'rx, T: Send> Drop for Handle<'rx, T> {
+impl<'rx, T: Send + 'static> Drop for Handle<'rx, T> {
     fn drop(&mut self) {
         unsafe { self.remove() }
     }
diff --git a/src/libstd/sync/mpsc/shared.rs b/src/libstd/sync/mpsc/shared.rs
index 729e7991f97..bc9c73585c2 100644
--- a/src/libstd/sync/mpsc/shared.rs
+++ b/src/libstd/sync/mpsc/shared.rs
@@ -64,7 +64,7 @@ pub enum Failure {
     Disconnected,
 }
 
-impl<T: Send> Packet<T> {
+impl<T: Send + 'static> Packet<T> {
     // Creation of a packet *must* be followed by a call to postinit_lock
     // and later by inherit_blocker
     pub fn new() -> Packet<T> {
@@ -474,7 +474,7 @@ impl<T: Send> Packet<T> {
 }
 
 #[unsafe_destructor]
-impl<T: Send> Drop for Packet<T> {
+impl<T: Send + 'static> Drop for Packet<T> {
     fn drop(&mut self) {
         // Note that this load is not only an assert for correctness about
         // disconnection, but also a proper fence before the read of
diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs
index c03bf024818..b8f835bde51 100644
--- a/src/libstd/sync/mpsc/spsc_queue.rs
+++ b/src/libstd/sync/mpsc/spsc_queue.rs
@@ -74,11 +74,11 @@ pub struct Queue<T> {
     cache_subtractions: AtomicUsize,
 }
 
-unsafe impl<T: Send> Send for Queue<T> { }
+unsafe impl<T: Send + 'static> Send for Queue<T> { }
 
-unsafe impl<T: Send> Sync for Queue<T> { }
+unsafe impl<T: Send + 'static> Sync for Queue<T> { }
 
-impl<T: Send> Node<T> {
+impl<T: Send + 'static> Node<T> {
     fn new() -> *mut Node<T> {
         unsafe {
             mem::transmute(box Node {
@@ -89,7 +89,7 @@ impl<T: Send> Node<T> {
     }
 }
 
-impl<T: Send> Queue<T> {
+impl<T: Send + 'static> Queue<T> {
     /// Creates a new queue.
     ///
     /// This is unsafe as the type system doesn't enforce a single
@@ -227,7 +227,7 @@ impl<T: Send> Queue<T> {
 }
 
 #[unsafe_destructor]
-impl<T: Send> Drop for Queue<T> {
+impl<T: Send + 'static> Drop for Queue<T> {
     fn drop(&mut self) {
         unsafe {
             let mut cur = *self.first.get();
diff --git a/src/libstd/sync/mpsc/stream.rs b/src/libstd/sync/mpsc/stream.rs
index 2d528662f64..a194c996692 100644
--- a/src/libstd/sync/mpsc/stream.rs
+++ b/src/libstd/sync/mpsc/stream.rs
@@ -74,7 +74,7 @@ enum Message<T> {
     GoUp(Receiver<T>),
 }
 
-impl<T: Send> Packet<T> {
+impl<T: Send + 'static> Packet<T> {
     pub fn new() -> Packet<T> {
         Packet {
             queue: unsafe { spsc::Queue::new(128) },
@@ -472,7 +472,7 @@ impl<T: Send> Packet<T> {
 }
 
 #[unsafe_destructor]
-impl<T: Send> Drop for Packet<T> {
+impl<T: Send + 'static> Drop for Packet<T> {
     fn drop(&mut self) {
         // Note that this load is not only an assert for correctness about
         // disconnection, but also a proper fence before the read of
diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs
index da3ce51a652..ae96a2491dc 100644
--- a/src/libstd/sync/mpsc/sync.rs
+++ b/src/libstd/sync/mpsc/sync.rs
@@ -55,9 +55,9 @@ pub struct Packet<T> {
     lock: Mutex<State<T>>,
 }
 
-unsafe impl<T:Send> Send for Packet<T> { }
+unsafe impl<T: Send + 'static> Send for Packet<T> { }
 
-unsafe impl<T:Send> Sync for Packet<T> { }
+unsafe impl<T: Send + 'static> Sync for Packet<T> { }
 
 struct State<T> {
     disconnected: bool, // Is the channel disconnected yet?
@@ -75,7 +75,7 @@ struct State<T> {
     canceled: Option<&'static mut bool>,
 }
 
-unsafe impl<T: Send> Send for State<T> {}
+unsafe impl<T: Send + 'static> Send for State<T> {}
 
 /// Possible flavors of threads who can be blocked on this channel.
 enum Blocker {
@@ -113,7 +113,7 @@ pub enum Failure {
 
 /// Atomically blocks the current thread, placing it into `slot`, unlocking `lock`
 /// in the meantime. This re-locks the mutex upon returning.
-fn wait<'a, 'b, T: Send>(lock: &'a Mutex<State<T>>,
+fn wait<'a, 'b, T: Send + 'static>(lock: &'a Mutex<State<T>>,
                          mut guard: MutexGuard<'b, State<T>>,
                          f: fn(SignalToken) -> Blocker)
                          -> MutexGuard<'a, State<T>>
@@ -136,7 +136,7 @@ fn wakeup<T>(token: SignalToken, guard: MutexGuard<State<T>>) {
     token.signal();
 }
 
-impl<T: Send> Packet<T> {
+impl<T: Send + 'static> Packet<T> {
     pub fn new(cap: uint) -> Packet<T> {
         Packet {
             channels: AtomicUsize::new(1),
@@ -412,7 +412,7 @@ impl<T: Send> Packet<T> {
 }
 
 #[unsafe_destructor]
-impl<T: Send> Drop for Packet<T> {
+impl<T: Send + 'static> Drop for Packet<T> {
     fn drop(&mut self) {
         assert_eq!(self.channels.load(Ordering::SeqCst), 0);
         let mut guard = self.lock.lock().unwrap();
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index d7e8419f19f..65cae90857e 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -120,9 +120,9 @@ pub struct Mutex<T> {
     data: UnsafeCell<T>,
 }
 
-unsafe impl<T:Send> Send for Mutex<T> { }
+unsafe impl<T: Send + 'static> Send for Mutex<T> { }
 
-unsafe impl<T:Send> Sync for Mutex<T> { }
+unsafe impl<T: Send + 'static> Sync for Mutex<T> { }
 
 /// The static mutex type is provided to allow for static allocation of mutexes.
 ///
@@ -180,7 +180,7 @@ pub const MUTEX_INIT: StaticMutex = StaticMutex {
     poison: poison::FLAG_INIT,
 };
 
-impl<T: Send> Mutex<T> {
+impl<T: Send + 'static> Mutex<T> {
     /// Creates a new mutex in an unlocked state ready for use.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> Mutex<T> {
@@ -243,7 +243,7 @@ impl<T: Send> Mutex<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Drop for Mutex<T> {
+impl<T: Send + 'static> Drop for Mutex<T> {
     fn drop(&mut self) {
         // This is actually safe b/c we know that there is no further usage of
         // this mutex (it's up to the user to arrange for a mutex to get
diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs
index 06c0c84c418..f4274dd91cc 100644
--- a/src/libstd/sync/task_pool.rs
+++ b/src/libstd/sync/task_pool.rs
@@ -24,12 +24,12 @@ use thread;
 use thunk::Thunk;
 
 struct Sentinel<'a> {
-    jobs: &'a Arc<Mutex<Receiver<Thunk>>>,
+    jobs: &'a Arc<Mutex<Receiver<Thunk<'static>>>>,
     active: bool
 }
 
 impl<'a> Sentinel<'a> {
-    fn new(jobs: &Arc<Mutex<Receiver<Thunk>>>) -> Sentinel {
+    fn new(jobs: &'a Arc<Mutex<Receiver<Thunk<'static>>>>) -> Sentinel<'a> {
         Sentinel {
             jobs: jobs,
             active: true
@@ -80,7 +80,7 @@ pub struct TaskPool {
     //
     // This is the only such Sender, so when it is dropped all subthreads will
     // quit.
-    jobs: Sender<Thunk>
+    jobs: Sender<Thunk<'static>>
 }
 
 impl TaskPool {
@@ -105,13 +105,13 @@ impl TaskPool {
 
     /// Executes the function `job` on a thread in the pool.
     pub fn execute<F>(&self, job: F)
-        where F : FnOnce(), F : Send
+        where F : FnOnce(), F : Send + 'static
     {
         self.jobs.send(Thunk::new(job)).unwrap();
     }
 }
 
-fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk>>>) {
+fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk<'static>>>>) {
     thread::spawn(move || {
         // Will spawn a new thread on panic unless it is cancelled.
         let sentinel = Sentinel::new(&jobs);
diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs
index d3273646b3f..dc1ae85efe0 100644
--- a/src/libstd/sys/common/helper_thread.rs
+++ b/src/libstd/sys/common/helper_thread.rs
@@ -81,7 +81,7 @@ impl<M: Send> Helper<M> {
     ///
     /// This function is safe to be called many times.
     pub fn boot<T, F>(&'static self, f: F, helper: fn(helper_signal::signal, Receiver<M>, T)) where
-        T: Send,
+        T: Send + 'static,
         F: FnOnce() -> T,
     {
         unsafe {
diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs
index a8355c34000..ea25ddc0fca 100644
--- a/src/libstd/thread.rs
+++ b/src/libstd/thread.rs
@@ -172,9 +172,9 @@ pub struct Builder {
     // The size of the stack for the spawned thread
     stack_size: Option<uint>,
     // Thread-local stdout
-    stdout: Option<Box<Writer + Send>>,
+    stdout: Option<Box<Writer + Send + 'static>>,
     // Thread-local stderr
-    stderr: Option<Box<Writer + Send>>,
+    stderr: Option<Box<Writer + Send + 'static>>,
 }
 
 impl Builder {
@@ -208,7 +208,7 @@ impl Builder {
     /// Redirect thread-local stdout.
     #[unstable(feature = "std_misc",
                reason = "Will likely go away after proc removal")]
-    pub fn stdout(mut self, stdout: Box<Writer + Send>) -> Builder {
+    pub fn stdout(mut self, stdout: Box<Writer + Send + 'static>) -> Builder {
         self.stdout = Some(stdout);
         self
     }
@@ -216,7 +216,7 @@ impl Builder {
     /// Redirect thread-local stderr.
     #[unstable(feature = "std_misc",
                reason = "Will likely go away after proc removal")]
-    pub fn stderr(mut self, stderr: Box<Writer + Send>) -> Builder {
+    pub fn stderr(mut self, stderr: Box<Writer + Send + 'static>) -> Builder {
         self.stderr = Some(stderr);
         self
     }
@@ -565,11 +565,11 @@ impl thread_info::NewThread for Thread {
 ///
 /// A thread that completes without panicking is considered to exit successfully.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub type Result<T> = ::result::Result<T, Box<Any + Send>>;
+pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>;
 
 struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>);
 
-unsafe impl<T:'static+Send> Send for Packet<T> {}
+unsafe impl<T:Send> Send for Packet<T> {}
 unsafe impl<T> Sync for Packet<T> {}
 
 /// Inner representation for JoinHandle and JoinGuard
@@ -804,7 +804,7 @@ mod test {
         rx.recv().unwrap();
     }
 
-    fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk) {
+    fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) {
         let (tx, rx) = channel::<uint>();
 
         let x = box 1;
@@ -851,7 +851,7 @@ mod test {
         // (well, it would if the constant were 8000+ - I lowered it to be more
         // valgrind-friendly. try this at home, instead..!)
         static GENERATIONS: uint = 16;
-        fn child_no(x: uint) -> Thunk {
+        fn child_no(x: uint) -> Thunk<'static> {
             return Thunk::new(move|| {
                 if x < GENERATIONS {
                     thread::spawn(move|| child_no(x+1).invoke(()));
diff --git a/src/libstd/thunk.rs b/src/libstd/thunk.rs
index 0831242f954..1412dbd70b9 100644
--- a/src/libstd/thunk.rs
+++ b/src/libstd/thunk.rs
@@ -16,21 +16,24 @@ use alloc::boxed::Box;
 use core::marker::Send;
 use core::ops::FnOnce;
 
-pub struct Thunk<A=(),R=()> {
-    invoke: Box<Invoke<A,R>+Send>
+pub struct Thunk<'a, A=(),R=()> {
+    #[cfg(stage0)] // // SNAP ac134f7 remove after stage0
+    invoke: Box<Invoke<A,R>+Send>,
+    #[cfg(not(stage0))]
+    invoke: Box<Invoke<A,R>+Send + 'a>,
 }
 
-impl<R> Thunk<(),R> {
-    pub fn new<F>(func: F) -> Thunk<(),R>
-        where F : FnOnce() -> R, F : Send
+impl<'a, R> Thunk<'a,(),R> {
+    pub fn new<F>(func: F) -> Thunk<'a,(),R>
+        where F : FnOnce() -> R, F : Send + 'a
     {
         Thunk::with_arg(move|()| func())
     }
 }
 
-impl<A,R> Thunk<A,R> {
-    pub fn with_arg<F>(func: F) -> Thunk<A,R>
-        where F : FnOnce(A) -> R, F : Send
+impl<'a,A,R> Thunk<'a,A,R> {
+    pub fn with_arg<F>(func: F) -> Thunk<'a,A,R>
+        where F : FnOnce(A) -> R, F : Send + 'a
     {
         Thunk {
             invoke: box func
diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs
index 758191a6e11..b978d2d8054 100644
--- a/src/libterm/terminfo/mod.rs
+++ b/src/libterm/terminfo/mod.rs
@@ -72,7 +72,7 @@ pub struct TerminfoTerminal<T> {
     ti: Box<TermInfo>
 }
 
-impl<T: Writer+Send> Terminal<T> for TerminfoTerminal<T> {
+impl<T: Writer+Send+'static> Terminal<T> for TerminfoTerminal<T> {
     fn fg(&mut self, color: color::Color) -> IoResult<bool> {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
@@ -164,11 +164,11 @@ impl<T: Writer+Send> Terminal<T> for TerminfoTerminal<T> {
     fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.out }
 }
 
-impl<T: Writer+Send> UnwrappableTerminal<T> for TerminfoTerminal<T> {
+impl<T: Writer+Send+'static> UnwrappableTerminal<T> for TerminfoTerminal<T> {
     fn unwrap(self) -> T { self.out }
 }
 
-impl<T: Writer+Send> TerminfoTerminal<T> {
+impl<T: Writer+Send+'static> TerminfoTerminal<T> {
     /// Returns `None` whenever the terminal cannot be created for some
     /// reason.
     pub fn new(out: T) -> Option<Box<Terminal<T>+Send+'static>> {
@@ -229,4 +229,3 @@ impl<T: Writer> Writer for TerminfoTerminal<T> {
         self.out.flush()
     }
 }
-
diff --git a/src/libterm/win.rs b/src/libterm/win.rs
index a56613681c8..e93b956dc7c 100644
--- a/src/libterm/win.rs
+++ b/src/libterm/win.rs
@@ -86,7 +86,7 @@ fn bits_to_color(bits: u16) -> color::Color {
     color | (bits & 0x8) // copy the hi-intensity bit
 }
 
-impl<T: Writer+Send> WinConsole<T> {
+impl<T: Writer+Send+'static> WinConsole<T> {
     fn apply(&mut self) {
         let _unused = self.buf.flush();
         let mut accum: libc::WORD = 0;
@@ -139,7 +139,7 @@ impl<T: Writer> Writer for WinConsole<T> {
     }
 }
 
-impl<T: Writer+Send> Terminal<T> for WinConsole<T> {
+impl<T: Writer+Send+'static> Terminal<T> for WinConsole<T> {
     fn fg(&mut self, color: color::Color) -> IoResult<bool> {
         self.foreground = color;
         self.apply();
@@ -192,6 +192,6 @@ impl<T: Writer+Send> Terminal<T> for WinConsole<T> {
     fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.buf }
 }
 
-impl<T: Writer+Send> UnwrappableTerminal<T> for WinConsole<T> {
+impl<T: Writer+Send+'static> UnwrappableTerminal<T> for WinConsole<T> {
     fn unwrap(self) -> T { self.buf }
 }
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 62bf95d3b7b..2cb30ad9804 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -154,7 +154,7 @@ pub enum TestFn {
     StaticTestFn(fn()),
     StaticBenchFn(fn(&mut Bencher)),
     StaticMetricFn(fn(&mut MetricMap)),
-    DynTestFn(Thunk),
+    DynTestFn(Thunk<'static>),
     DynMetricFn(Box<for<'a> Invoke<&'a mut MetricMap>+'static>),
     DynBenchFn(Box<TDynBenchFn+'static>)
 }
@@ -878,7 +878,7 @@ pub fn run_test(opts: &TestOpts,
     fn run_test_inner(desc: TestDesc,
                       monitor_ch: Sender<MonitorMsg>,
                       nocapture: bool,
-                      testfn: Thunk) {
+                      testfn: Thunk<'static>) {
         thread::spawn(move || {
             let (tx, rx) = channel();
             let mut reader = ChanReader::new(rx);
diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/auxiliary/cci_capture_clause.rs
index 29a6ce59658..b38e955231e 100644
--- a/src/test/auxiliary/cci_capture_clause.rs
+++ b/src/test/auxiliary/cci_capture_clause.rs
@@ -11,7 +11,7 @@
 use std::thread;
 use std::sync::mpsc::{Receiver, channel};
 
-pub fn foo<T:Send + Clone>(x: T) -> Receiver<T> {
+pub fn foo<T:'static + Send + Clone>(x: T) -> Receiver<T> {
     let (tx, rx) = channel();
     thread::spawn(move|| {
         tx.send(x.clone());
diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs
index 3d8b6e82848..33d959dfe93 100644
--- a/src/test/bench/shootout-reverse-complement.rs
+++ b/src/test/bench/shootout-reverse-complement.rs
@@ -229,21 +229,12 @@ unsafe impl<T: 'static> Send for Racy<T> {}
 
 /// Executes a closure in parallel over the given iterator over mutable slice.
 /// The closure `f` is run in parallel with an element of `iter`.
-fn parallel<'a, I, T, F>(iter: I, f: F)
-        where T: 'a+Send + Sync,
-              I: Iterator<Item=&'a mut [T]>,
-              F: Fn(&mut [T]) + Sync {
-    use std::mem;
-    use std::raw::Repr;
-
-    iter.map(|chunk| {
-        // Need to convert `f` and `chunk` to something that can cross the task
-        // boundary.
-        let f = Racy(&f as *const F as *const uint);
-        let raw = Racy(chunk.repr());
-        thread::spawn(move|| {
-            let f = f.0 as *const F;
-            unsafe { (*f)(mem::transmute(raw.0)) }
+fn parallel<'a, I: Iterator, F>(iter: I, ref f: F)
+        where I::Item: Send + 'a,
+              F: Fn(I::Item) + Sync + 'a {
+    iter.map(|x| {
+        thread::scoped(move|| {
+            f(x)
         })
     }).collect::<Vec<_>>();
 }
diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs
index 4b59015f8aa..76ba5acb16c 100644
--- a/src/test/bench/shootout-spectralnorm.rs
+++ b/src/test/bench/shootout-spectralnorm.rs
@@ -112,26 +112,16 @@ fn dot(v: &[f64], u: &[f64]) -> f64 {
 }
 
 
-struct Racy<T>(T);
-
-unsafe impl<T: 'static> Send for Racy<T> {}
-
 // Executes a closure in parallel over the given mutable slice. The closure `f`
 // is run in parallel and yielded the starting index within `v` as well as a
 // sub-slice of `v`.
-fn parallel<T, F>(v: &mut [T], f: F)
-                  where T: Send + Sync,
-                        F: Fn(uint, &mut [T]) + Sync {
+fn parallel<'a,T, F>(v: &mut [T], ref f: F)
+                  where T: Send + Sync + 'a,
+                        F: Fn(uint, &mut [T]) + Sync + 'a {
     let size = v.len() / os::num_cpus() + 1;
-
     v.chunks_mut(size).enumerate().map(|(i, chunk)| {
-        // Need to convert `f` and `chunk` to something that can cross the task
-        // boundary.
-        let f = Racy(&f as *const _ as *const uint);
-        let raw = Racy(chunk.repr());
-        thread::spawn(move|| {
-            let f = f.0 as *const F;
-            unsafe { (*f)(i * size, mem::transmute(raw.0)) }
+        thread::scoped(move|| {
+            f(i * size, chunk)
         })
     }).collect::<Vec<_>>();
 }
diff --git a/src/test/compile-fail/builtin-superkinds-simple.rs b/src/test/compile-fail/builtin-superkinds-simple.rs
index c7b75ade555..c3fb6a1be87 100644
--- a/src/test/compile-fail/builtin-superkinds-simple.rs
+++ b/src/test/compile-fail/builtin-superkinds-simple.rs
@@ -13,7 +13,7 @@
 
 trait Foo : Send { }
 
-impl <'a> Foo for &'a mut () { }
-//~^ ERROR the type `&'a mut ()` does not fulfill the required lifetime
+impl Foo for std::rc::Rc<i8> { }
+//~^ ERROR the trait `core::marker::Send` is not implemented
 
 fn main() { }
diff --git a/src/test/compile-fail/coherence-impls-builtin.rs b/src/test/compile-fail/coherence-impls-builtin.rs
index 2ca288b60a3..38730d241f6 100644
--- a/src/test/compile-fail/coherence-impls-builtin.rs
+++ b/src/test/compile-fail/coherence-impls-builtin.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(optin_builtin_traits)]
+
 use std::marker::Send;
 
 enum TestE {
@@ -16,18 +18,21 @@ enum TestE {
 
 struct MyType;
 
+struct NotSync;
+impl !Sync for NotSync {}
+
 unsafe impl Send for TestE {}
 unsafe impl Send for MyType {}
 unsafe impl Send for (MyType, MyType) {}
 //~^ ERROR builtin traits can only be implemented on structs or enums
 
-unsafe impl Send for &'static MyType {}
+unsafe impl Send for &'static NotSync {}
 //~^ ERROR builtin traits can only be implemented on structs or enums
 
 unsafe impl Send for [MyType] {}
 //~^ ERROR builtin traits can only be implemented on structs or enums
 
-unsafe impl Send for &'static [MyType] {}
+unsafe impl Send for &'static [NotSync] {}
 //~^ ERROR builtin traits can only be implemented on structs or enums
 
 fn is_send<T: Send>() {}
diff --git a/src/test/compile-fail/kindck-impl-type-params.rs b/src/test/compile-fail/kindck-impl-type-params.rs
index de7639c6213..d5276efa8be 100644
--- a/src/test/compile-fail/kindck-impl-type-params.rs
+++ b/src/test/compile-fail/kindck-impl-type-params.rs
@@ -17,7 +17,7 @@ struct S<T>;
 
 trait Gettable<T> {}
 
-impl<T: Send + Copy> Gettable<T> for S<T> {}
+impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
 
 fn f<T>(val: T) {
     let t: S<T> = S;
diff --git a/src/test/compile-fail/kindck-send-object.rs b/src/test/compile-fail/kindck-send-object.rs
index 7984b3b32c2..570f7ad7fe3 100644
--- a/src/test/compile-fail/kindck-send-object.rs
+++ b/src/test/compile-fail/kindck-send-object.rs
@@ -20,7 +20,7 @@ trait Message : Send { }
 
 fn object_ref_with_static_bound_not_ok() {
     assert_send::<&'static (Dummy+'static)>();
-    //~^ ERROR the trait `core::marker::Send` is not implemented
+    //~^ ERROR the trait `core::marker::Sync` is not implemented
 }
 
 fn box_object_with_no_bound_not_ok<'a>() {
@@ -28,7 +28,7 @@ fn box_object_with_no_bound_not_ok<'a>() {
 }
 
 fn object_with_send_bound_ok() {
-    assert_send::<&'static (Dummy+Send)>();
+    assert_send::<&'static (Dummy+Sync)>();
     assert_send::<Box<Dummy+Send>>();
 }
 
diff --git a/src/test/compile-fail/kindck-send-object1.rs b/src/test/compile-fail/kindck-send-object1.rs
index 3d47d33d7c3..48d5215b708 100644
--- a/src/test/compile-fail/kindck-send-object1.rs
+++ b/src/test/compile-fail/kindck-send-object1.rs
@@ -12,22 +12,22 @@
 // is broken into two parts because some errors occur in distinct
 // phases in the compiler. See kindck-send-object2.rs as well!
 
-fn assert_send<T:Send>() { }
+fn assert_send<T:Send+'static>() { }
 trait Dummy { }
 
 // careful with object types, who knows what they close over...
 fn test51<'a>() {
     assert_send::<&'a Dummy>();
-    //~^ ERROR the trait `core::marker::Send` is not implemented
+    //~^ ERROR the trait `core::marker::Sync` is not implemented
 }
 fn test52<'a>() {
-    assert_send::<&'a (Dummy+Send)>();
+    assert_send::<&'a (Dummy+Sync)>();
     //~^ ERROR does not fulfill the required lifetime
 }
 
 // ...unless they are properly bounded
 fn test60() {
-    assert_send::<&'static (Dummy+Send)>();
+    assert_send::<&'static (Dummy+Sync)>();
 }
 fn test61() {
     assert_send::<Box<Dummy+Send>>();
diff --git a/src/test/compile-fail/kindck-send-object2.rs b/src/test/compile-fail/kindck-send-object2.rs
index 75bae09b37f..d3d166e2a69 100644
--- a/src/test/compile-fail/kindck-send-object2.rs
+++ b/src/test/compile-fail/kindck-send-object2.rs
@@ -14,7 +14,7 @@ fn assert_send<T:Send>() { }
 trait Dummy { }
 
 fn test50() {
-    assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Send` is not implemented
+    assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Sync` is not implemented
 }
 
 fn test53() {
@@ -23,7 +23,7 @@ fn test53() {
 
 // ...unless they are properly bounded
 fn test60() {
-    assert_send::<&'static (Dummy+Send)>();
+    assert_send::<&'static (Dummy+Sync)>();
 }
 fn test61() {
     assert_send::<Box<Dummy+Send>>();
diff --git a/src/test/compile-fail/kindck-send-owned.rs b/src/test/compile-fail/kindck-send-owned.rs
index 266b6156656..406711902a5 100644
--- a/src/test/compile-fail/kindck-send-owned.rs
+++ b/src/test/compile-fail/kindck-send-owned.rs
@@ -18,8 +18,8 @@ fn test31() { assert_send::<String>(); }
 fn test32() { assert_send::<Vec<isize> >(); }
 
 // but not if they own a bad thing
-fn test40<'a>(_: &'a isize) {
-    assert_send::<Box<&'a isize>>(); //~ ERROR does not fulfill the required lifetime
+fn test40() {
+    assert_send::<Box<*mut u8>>(); //~ ERROR `core::marker::Send` is not implemented
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/kindck-send-region-pointers.rs b/src/test/compile-fail/kindck-send-region-pointers.rs
deleted file mode 100644
index e2a5b0678a6..00000000000
--- a/src/test/compile-fail/kindck-send-region-pointers.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that borrowed pointers are not sendable unless 'static.
-
-fn assert_send<T:Send>() { }
-
-// lifetime pointers with 'static lifetime are ok
-fn test01() { assert_send::<&'static isize>(); }
-fn test02() { assert_send::<&'static str>(); }
-fn test03() { assert_send::<&'static [isize]>(); }
-
-// whether or not they are mutable
-fn test10() { assert_send::<&'static mut isize>(); }
-
-// otherwise lifetime pointers are not ok
-fn test20<'a>(_: &'a isize) {
-    assert_send::<&'a isize>(); //~ ERROR does not fulfill the required lifetime
-}
-fn test21<'a>(_: &'a isize) {
-    assert_send::<&'a str>(); //~ ERROR does not fulfill the required lifetime
-}
-fn test22<'a>(_: &'a isize) {
-    assert_send::<&'a [isize]>(); //~ ERROR does not fulfill the required lifetime
-}
-
-fn main() { }
diff --git a/src/test/compile-fail/regions-bounded-by-send.rs b/src/test/compile-fail/regions-bounded-by-send.rs
deleted file mode 100644
index 71254e15d32..00000000000
--- a/src/test/compile-fail/regions-bounded-by-send.rs
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test which of the builtin types are considered sendable. The tests
-// in this file all test region bound and lifetime violations that are
-// detected during type check.
-
-extern crate core;
-use core::ptr::Unique;
-
-fn assert_send<T:Send>() { }
-trait Dummy:Send { }
-
-// lifetime pointers with 'static lifetime are ok
-
-fn static_lifime_ok<'a,T,U:Send>(_: &'a isize) {
-    assert_send::<&'static isize>();
-    assert_send::<&'static str>();
-    assert_send::<&'static [isize]>();
-
-    // whether or not they are mutable
-    assert_send::<&'static mut isize>();
-}
-
-// otherwise lifetime pointers are not ok
-
-fn param_not_ok<'a>(x: &'a isize) {
-    assert_send::<&'a isize>(); //~ ERROR does not fulfill the required lifetime
-}
-
-fn param_not_ok1<'a>(_: &'a isize) {
-    assert_send::<&'a str>(); //~ ERROR does not fulfill the required lifetime
-}
-
-fn param_not_ok2<'a>(_: &'a isize) {
-    assert_send::<&'a [isize]>(); //~ ERROR does not fulfill the required lifetime
-}
-
-// boxes are ok
-
-fn box_ok() {
-    assert_send::<Box<isize>>();
-    assert_send::<String>();
-    assert_send::<Vec<isize>>();
-}
-
-// but not if they own a bad thing
-
-fn box_with_region_not_ok<'a>() {
-    assert_send::<Box<&'a isize>>(); //~ ERROR does not fulfill the required lifetime
-}
-
-// objects with insufficient bounds no ok
-
-fn object_with_random_bound_not_ok<'a>() {
-    assert_send::<&'a (Dummy+'a)>();
-    //~^ ERROR reference has a longer lifetime
-}
-
-fn object_with_send_bound_not_ok<'a>() {
-    assert_send::<&'a (Dummy+Send)>();
-    //~^ ERROR does not fulfill the required lifetime
-}
-
-// unsafe pointers are ok unless they point at unsendable things
-
-struct UniqueUnsafePtr(Unique<*const isize>);
-
-unsafe impl Send for UniqueUnsafePtr {}
-
-fn unsafe_ok1<'a>(_: &'a isize) {
-    assert_send::<UniqueUnsafePtr>();
-}
-
-fn main() {
-}
diff --git a/src/test/compile-fail/regions-pattern-typing-issue-19552.rs b/src/test/compile-fail/regions-pattern-typing-issue-19552.rs
index 57ea607cbf6..3401dd1becd 100644
--- a/src/test/compile-fail/regions-pattern-typing-issue-19552.rs
+++ b/src/test/compile-fail/regions-pattern-typing-issue-19552.rs
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn assert_send<T: Send>(_t: T) {}
+fn assert_static<T: 'static>(_t: T) {}
 
 fn main() {
     let line = String::new();
     match [&*line] { //~ ERROR `line` does not live long enough
-        [ word ] => { assert_send(word); }
+        [ word ] => { assert_static(word); }
     }
 }
diff --git a/src/test/compile-fail/send-is-not-static-ensures-scoping.rs b/src/test/compile-fail/send-is-not-static-ensures-scoping.rs
new file mode 100755
index 00000000000..0b74892d66c
--- /dev/null
+++ b/src/test/compile-fail/send-is-not-static-ensures-scoping.rs
@@ -0,0 +1,25 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(core, std_misc)]
+use std::thread::Thread;
+
+fn main() {
+    let bad = {
+        let x = 1;
+        let y = &x;
+
+        Thread::scoped(|| { //~ ERROR cannot infer an appropriate lifetime
+            let _z = y;
+        })
+    };
+
+    bad.join().ok().unwrap();
+}
diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs
index 89e89cf8246..79174552ae0 100644
--- a/src/test/compile-fail/trait-bounds-cant-coerce.rs
+++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs
@@ -22,7 +22,7 @@ fn c(x: Box<Foo+Sync+Send>) {
 fn d(x: Box<Foo>) {
     a(x); //~  ERROR mismatched types
           //~| expected `Box<Foo + Send>`
-          //~| found `Box<Foo + 'static>`
+          //~| found `Box<Foo>`
           //~| expected bounds `Send`
           //~| found no bounds
 }
diff --git a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
index 3df9dd25d86..379ac12a954 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
@@ -22,7 +22,7 @@ trait Foo : Bar { }
 impl <T: Send> Foo for T { }
 impl <T: Send> Bar for T { }
 
-fn foo<T: Foo>(val: T, chan: Sender<T>) {
+fn foo<T: Foo + 'static>(val: T, chan: Sender<T>) {
     chan.send(val).unwrap();
 }
 
diff --git a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
index 52b826393e9..cd019c21a3d 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
@@ -25,7 +25,7 @@ struct X<T>(T);
 impl <T: Sync> RequiresShare for X<T> { }
 impl <T: Sync+Send> RequiresRequiresShareAndSend for X<T> { }
 
-fn foo<T: RequiresRequiresShareAndSend>(val: T, chan: Sender<T>) {
+fn foo<T: RequiresRequiresShareAndSend + 'static>(val: T, chan: Sender<T>) {
     chan.send(val).unwrap();
 }
 
diff --git a/src/test/run-pass/builtin-superkinds-capabilities.rs b/src/test/run-pass/builtin-superkinds-capabilities.rs
index 034e5ff2d3a..dc61508eec4 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities.rs
@@ -18,7 +18,7 @@ trait Foo : Send { }
 
 impl <T: Send> Foo for T { }
 
-fn foo<T: Foo>(val: T, chan: Sender<T>) {
+fn foo<T: Foo + 'static>(val: T, chan: Sender<T>) {
     chan.send(val).unwrap();
 }
 
diff --git a/src/test/run-pass/builtin-superkinds-self-type.rs b/src/test/run-pass/builtin-superkinds-self-type.rs
index 1b3070ba3b0..1d05a7baa53 100644
--- a/src/test/run-pass/builtin-superkinds-self-type.rs
+++ b/src/test/run-pass/builtin-superkinds-self-type.rs
@@ -13,13 +13,13 @@
 
 use std::sync::mpsc::{Sender, channel};
 
-trait Foo : Send + Sized {
+trait Foo : Send + Sized + 'static {
     fn foo(self, tx: Sender<Self>) {
         tx.send(self).unwrap();
     }
 }
 
-impl <T: Send> Foo for T { }
+impl <T: Send + 'static> Foo for T { }
 
 pub fn main() {
     let (tx, rx) = channel();
diff --git a/src/test/run-pass/issue-18188.rs b/src/test/run-pass/issue-18188.rs
index 7a5a86822af..a4b09eb08e0 100644
--- a/src/test/run-pass/issue-18188.rs
+++ b/src/test/run-pass/issue-18188.rs
@@ -14,12 +14,12 @@ use std::thunk::Thunk;
 
 pub trait Promisable: Send + Sync {}
 impl<T: Send + Sync> Promisable for T {}
-pub fn propagate<T, E, F, G>(action: F) -> Thunk<Result<T, E>, Result<T, E>>
+pub fn propagate<'a, T, E, F, G>(action: F) -> Thunk<'a,Result<T, E>, Result<T, E>>
     where
-        T: Promisable + Clone,
-        E: Promisable + Clone,
-        F: FnOnce(&T) -> Result<T, E> + Send,
-        G: FnOnce(Result<T, E>) -> Result<T, E> {
+        T: Promisable + Clone + 'a,
+        E: Promisable + Clone + 'a,
+        F: FnOnce(&T) -> Result<T, E> + Send + 'a,
+        G: FnOnce(Result<T, E>) -> Result<T, E> + 'a {
     Thunk::with_arg(move |result: Result<T, E>| {
         match result {
             Ok(ref t) => action(t),
diff --git a/src/test/run-pass/issue-21058.rs b/src/test/run-pass/issue-21058.rs
index 044d43a57fa..3cdd57aed5a 100644
--- a/src/test/run-pass/issue-21058.rs
+++ b/src/test/run-pass/issue-21058.rs
@@ -14,7 +14,7 @@ struct DST { a: u32, b: str }
 
 fn main() {
     // get_tydesc should support unsized types
-    assert!(unsafe {(
+    assert_eq!(unsafe {(
         // Slice
         (*std::intrinsics::get_tydesc::<[u8]>()).name,
         // str
@@ -25,5 +25,5 @@ fn main() {
         (*std::intrinsics::get_tydesc::<NT>()).name,
         // DST
         (*std::intrinsics::get_tydesc::<DST>()).name
-    )} == ("[u8]", "str", "core::marker::Copy + 'static", "NT", "DST"));
+    )}, ("[u8]", "str", "core::marker::Copy", "NT", "DST"));
 }
diff --git a/src/test/run-pass/issue-2190-1.rs b/src/test/run-pass/issue-2190-1.rs
index 810bf385d7e..3025741694f 100644
--- a/src/test/run-pass/issue-2190-1.rs
+++ b/src/test/run-pass/issue-2190-1.rs
@@ -13,11 +13,11 @@ use std::thunk::Thunk;
 
 static generations: uint = 1024+256+128+49;
 
-fn spawn(f: Thunk) {
+fn spawn(f: Thunk<'static>) {
     Builder::new().stack_size(32 * 1024).spawn(move|| f.invoke(()));
 }
 
-fn child_no(x: uint) -> Thunk {
+fn child_no(x: uint) -> Thunk<'static> {
     Thunk::new(move|| {
         if x < generations {
             spawn(child_no(x+1));
diff --git a/src/test/run-pass/send-is-not-static-par-for.rs b/src/test/run-pass/send-is-not-static-par-for.rs
new file mode 100755
index 00000000000..c6b64d97fbd
--- /dev/null
+++ b/src/test/run-pass/send-is-not-static-par-for.rs
@@ -0,0 +1,47 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(core, std_misc)]
+use std::thread::Thread;
+use std::sync::Mutex;
+
+fn par_for<I, F>(iter: I, f: F)
+    where I: Iterator,
+          <I as Iterator>::Item: Send,
+          F: Fn(<I as Iterator>::Item) + Sync
+{
+    let f = &f;
+    let _guards: Vec<_> = iter.map(|elem| {
+        Thread::scoped(move || {
+            f(elem)
+        })
+    }).collect();
+
+}
+
+fn sum(x: &[i32]) {
+    let sum_lengths = Mutex::new(0);
+    par_for(x.windows(4), |x| {
+        *sum_lengths.lock().unwrap() += x.len()
+    });
+
+    assert_eq!(*sum_lengths.lock().unwrap(), (x.len() - 3) * 4);
+}
+
+fn main() {
+    let mut elements = [0; 20];
+
+    // iterators over references into this stack frame
+    par_for(elements.iter_mut().enumerate(), |(i, x)| {
+        *x = i as i32
+    });
+
+    sum(&elements)
+}
diff --git a/src/test/run-pass/send-type-inference.rs b/src/test/run-pass/send-type-inference.rs
index ae992a0a358..60093803f0b 100644
--- a/src/test/run-pass/send-type-inference.rs
+++ b/src/test/run-pass/send-type-inference.rs
@@ -16,7 +16,7 @@ struct Command<K, V> {
     val: V
 }
 
-fn cache_server<K:Send,V:Send>(mut tx: Sender<Sender<Command<K, V>>>) {
+fn cache_server<K:Send+'static,V:Send+'static>(mut tx: Sender<Sender<Command<K, V>>>) {
     let (tx1, _rx) = channel();
     tx.send(tx1);
 }