about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/error.rs70
-rw-r--r--src/libstd/fs.rs2
-rw-r--r--src/libstd/io/util.rs4
-rw-r--r--src/libstd/lib.rs12
-rw-r--r--src/libstd/net/ip.rs4
-rw-r--r--src/libstd/panic.rs5
-rw-r--r--src/libstd/primitive_docs.rs30
-rw-r--r--src/libstd/process.rs40
-rw-r--r--src/libstd/sync/condvar.rs368
-rw-r--r--src/libstd/sync/mod.rs14
-rw-r--r--src/libstd/sync/mpsc/mod.rs9
-rw-r--r--src/libstd/sync/mpsc/sync.rs2
-rw-r--r--src/libstd/sync/mutex.rs219
-rw-r--r--src/libstd/sync/once.rs3
-rw-r--r--src/libstd/sync/rwlock.rs249
-rw-r--r--src/libstd/sys/common/backtrace.rs4
-rw-r--r--src/libstd/sys/common/net.rs31
-rw-r--r--src/libstd/sys/common/poison.rs24
-rw-r--r--src/libstd/sys/common/wtf8.rs4
-rw-r--r--src/libstd/sys/unix/fs.rs10
-rw-r--r--src/libstd/sys/unix/os.rs47
-rw-r--r--src/libstd/sys/unix/pipe.rs5
-rw-r--r--src/libstd/sys/unix/process.rs10
-rw-r--r--src/libstd/sys/unix/thread.rs1
-rw-r--r--src/libstd/sys/unix/time.rs6
-rw-r--r--src/libstd/sys/windows/backtrace.rs92
-rw-r--r--src/libstd/sys/windows/fs.rs4
-rw-r--r--src/libstd/sys/windows/handle.rs4
-rw-r--r--src/libstd/sys/windows/pipe.rs5
29 files changed, 474 insertions, 804 deletions
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 2a2d41112ff..1459420cdc0 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -66,10 +66,80 @@ pub trait Error: Debug + Display + Reflect {
     /// The description should not contain newlines or sentence-ending
     /// punctuation, to facilitate embedding in larger user-facing
     /// strings.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::error::Error;
+    ///
+    /// match "xc".parse::<u32>() {
+    ///     Err(e) => {
+    ///         println!("Error: {}", e.description());
+    ///     }
+    ///     _ => println!("No error"),
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn description(&self) -> &str;
 
     /// The lower-level cause of this error, if any.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::error::Error;
+    /// use std::fmt;
+    ///
+    /// #[derive(Debug)]
+    /// struct SuperError {
+    ///     side: SuperErrorSideKick,
+    /// }
+    ///
+    /// impl fmt::Display for SuperError {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "SuperError is here!")
+    ///     }
+    /// }
+    ///
+    /// impl Error for SuperError {
+    ///     fn description(&self) -> &str {
+    ///         "I'm the superhero of errors!"
+    ///     }
+    ///
+    ///     fn cause(&self) -> Option<&Error> {
+    ///         Some(&self.side)
+    ///     }
+    /// }
+    ///
+    /// #[derive(Debug)]
+    /// struct SuperErrorSideKick;
+    ///
+    /// impl fmt::Display for SuperErrorSideKick {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "SuperErrorSideKick is here!")
+    ///     }
+    /// }
+    ///
+    /// impl Error for SuperErrorSideKick {
+    ///     fn description(&self) -> &str {
+    ///         "I'm SuperError side kick!"
+    ///     }
+    /// }
+    ///
+    /// fn get_super_error() -> Result<(), SuperError> {
+    ///     Err(SuperError { side: SuperErrorSideKick })
+    /// }
+    ///
+    /// fn main() {
+    ///     match get_super_error() {
+    ///         Err(e) => {
+    ///             println!("Error: {}", e.description());
+    ///             println!("Caused by: {}", e.cause().unwrap());
+    ///         }
+    ///         _ => println!("No error"),
+    ///     }
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn cause(&self) -> Option<&Error> { None }
 
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 668fa1fb303..83439b3f132 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -141,7 +141,7 @@ pub struct Permissions(fs_imp::FilePermissions);
 
 /// An structure representing a type of file with accessors for each file type.
 #[stable(feature = "file_type", since = "1.1.0")]
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct FileType(fs_imp::FileType);
 
 /// A builder used to create directories in various manners.
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index 07f43f72ff5..c8b52fc0467 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -152,8 +152,8 @@ pub struct Sink { _priv: () }
 /// ```rust
 /// use std::io::{self, Write};
 ///
-/// let mut buffer = vec![1, 2, 3, 5, 8];
-/// let num_bytes = io::sink().write(&mut buffer).unwrap();
+/// let buffer = vec![1, 2, 3, 5, 8];
+/// let num_bytes = io::sink().write(&buffer).unwrap();
 /// assert_eq!(num_bytes, 5);
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index a396c7be09a..d05a5a09614 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -468,15 +468,3 @@ pub mod __rand {
 // the rustdoc documentation for primitive types. Using `include!`
 // because rustdoc only looks for these modules at the crate level.
 include!("primitive_docs.rs");
-
-// FIXME(stage0): remove this after a snapshot
-// HACK: this is needed because the interpretation of slice
-// patterns changed between stage0 and now.
-#[cfg(stage0)]
-fn slice_pat<'a, 'b, T>(t: &'a &'b [T]) -> &'a &'b [T] {
-    t
-}
-#[cfg(not(stage0))]
-fn slice_pat<'a, 'b, T>(t: &'a &'b [T]) -> &'b [T] {
-    *t
-}
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index 57d75441bff..67410e87a8b 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -83,6 +83,10 @@ impl Ipv4Addr {
     }
 
     /// Returns true for the special 'unspecified' address (0.0.0.0).
+    ///
+    /// This property is defined in _UNIX Network Programming, Second Edition_,
+    /// W. Richard Stevens, p. 891; see also [ip7]
+    /// [ip7][http://man7.org/linux/man-pages/man7/ip.7.html]
     pub fn is_unspecified(&self) -> bool {
         self.inner.s_addr == 0
     }
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index d8cadf09cb2..ba18d15f5c4 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -227,6 +227,11 @@ impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
 
+#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
+impl<T: ?Sized> RefUnwindSafe for Mutex<T> {}
+#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
+impl<T: ?Sized> RefUnwindSafe for RwLock<T> {}
+
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T> Deref for AssertUnwindSafe<T> {
     type Target = T;
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index be9cd6a6888..de891ea8918 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -506,6 +506,9 @@ mod prim_f64 { }
 ///
 /// *[See also the `std::i8` module](i8/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `i64` in there.
+///
 mod prim_i8 { }
 
 #[doc(primitive = "i16")]
@@ -514,6 +517,9 @@ mod prim_i8 { }
 ///
 /// *[See also the `std::i16` module](i16/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `i32` in there.
+///
 mod prim_i16 { }
 
 #[doc(primitive = "i32")]
@@ -522,6 +528,9 @@ mod prim_i16 { }
 ///
 /// *[See also the `std::i32` module](i32/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `i16` in there.
+///
 mod prim_i32 { }
 
 #[doc(primitive = "i64")]
@@ -530,6 +539,9 @@ mod prim_i32 { }
 ///
 /// *[See also the `std::i64` module](i64/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `i8` in there.
+///
 mod prim_i64 { }
 
 #[doc(primitive = "u8")]
@@ -538,6 +550,9 @@ mod prim_i64 { }
 ///
 /// *[See also the `std::u8` module](u8/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `u64` in there.
+///
 mod prim_u8 { }
 
 #[doc(primitive = "u16")]
@@ -546,6 +561,9 @@ mod prim_u8 { }
 ///
 /// *[See also the `std::u16` module](u16/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `u32` in there.
+///
 mod prim_u16 { }
 
 #[doc(primitive = "u32")]
@@ -554,6 +572,9 @@ mod prim_u16 { }
 ///
 /// *[See also the `std::u32` module](u32/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `u16` in there.
+///
 mod prim_u32 { }
 
 #[doc(primitive = "u64")]
@@ -562,6 +583,9 @@ mod prim_u32 { }
 ///
 /// *[See also the `std::u64` module](u64/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `u8` in there.
+///
 mod prim_u64 { }
 
 #[doc(primitive = "isize")]
@@ -570,6 +594,9 @@ mod prim_u64 { }
 ///
 /// *[See also the `std::isize` module](isize/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `usize` in there.
+///
 mod prim_isize { }
 
 #[doc(primitive = "usize")]
@@ -578,4 +605,7 @@ mod prim_isize { }
 ///
 /// *[See also the `std::usize` module](usize/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `isize` in there.
+///
 mod prim_usize { }
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 2edd1a30638..16bc81de78e 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -27,8 +27,9 @@ use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 /// Representation of a running or exited child process.
 ///
 /// This structure is used to represent and manage child processes. A child
-/// process is created via the `Command` struct, which configures the spawning
-/// process and can itself be constructed using a builder-style interface.
+/// process is created via the [`Command`] struct, which configures the
+/// spawning process and can itself be constructed using a builder-style
+/// interface.
 ///
 /// # Examples
 ///
@@ -48,13 +49,18 @@ use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 ///
 /// # Note
 ///
-/// Take note that there is no implementation of
-/// [`Drop`](../../core/ops/trait.Drop.html) for child processes, so if you
-/// do not ensure the `Child` has exited then it will continue to run, even
-/// after the `Child` handle to the child process has gone out of scope.
+/// Take note that there is no implementation of [`Drop`] for child processes,
+/// so if you do not ensure the `Child` has exited then it will continue to
+/// run, even after the `Child` handle to the child process has gone out of
+/// scope.
 ///
-/// Calling `wait` (or other functions that wrap around it) will make the
-/// parent process wait until the child has actually exited before continuing.
+/// Calling [`wait`][`wait`] (or other functions that wrap around it) will make
+/// the parent process wait until the child has actually exited before
+/// continuing.
+///
+/// [`Command`]: struct.Command.html
+/// [`Drop`]: ../../core/ops/trait.Drop.html
+/// [`wait`]: #method.wait
 #[stable(feature = "process", since = "1.0.0")]
 pub struct Child {
     handle: imp::Process,
@@ -91,7 +97,11 @@ impl IntoInner<imp::Process> for Child {
     fn into_inner(self) -> imp::Process { self.handle }
 }
 
-/// A handle to a child process's stdin
+/// A handle to a child process's stdin. This struct is used in the [`stdin`]
+/// field on [`Child`].
+///
+/// [`Child`]: struct.Child.html
+/// [`stdin`]: struct.Child.html#structfield.stdin
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStdin {
     inner: AnonPipe
@@ -122,7 +132,11 @@ impl FromInner<AnonPipe> for ChildStdin {
     }
 }
 
-/// A handle to a child process's stdout
+/// A handle to a child process's stdout. This struct is used in the [`stdout`]
+/// field on [`Child`].
+///
+/// [`Child`]: struct.Child.html
+/// [`stdout`]: struct.Child.html#structfield.stdout
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStdout {
     inner: AnonPipe
@@ -152,7 +166,11 @@ impl FromInner<AnonPipe> for ChildStdout {
     }
 }
 
-/// A handle to a child process's stderr
+/// A handle to a child process's stderr. This struct is used in the [`stderr`]
+/// field on [`Child`].
+///
+/// [`Child`]: struct.Child.html
+/// [`stderr`]: struct.Child.html#structfield.stderr
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStderr {
     inner: AnonPipe
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index bf4b119a0b6..3c52ebc72f2 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -15,7 +15,7 @@ use sync::{mutex, MutexGuard, PoisonError};
 use sys_common::condvar as sys;
 use sys_common::mutex as sys_mutex;
 use sys_common::poison::{self, LockResult};
-use time::{Instant, Duration};
+use time::Duration;
 
 /// A type indicating whether a timed wait on a condition variable returned
 /// due to a time out or not.
@@ -72,59 +72,19 @@ impl WaitTimeoutResult {
 /// }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub struct Condvar { inner: Box<StaticCondvar> }
-
-/// Statically allocated condition variables.
-///
-/// This structure is identical to `Condvar` except that it is suitable for use
-/// in static initializers for other structures.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(static_condvar)]
-///
-/// use std::sync::{StaticCondvar, CONDVAR_INIT};
-///
-/// static CVAR: StaticCondvar = CONDVAR_INIT;
-/// ```
-#[unstable(feature = "static_condvar",
-           reason = "may be merged with Condvar in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Condvar::new` in a static should \
-                             suffice")]
-pub struct StaticCondvar {
-    inner: sys::Condvar,
+pub struct Condvar {
+    inner: Box<sys::Condvar>,
     mutex: AtomicUsize,
 }
 
-/// Constant initializer for a statically allocated condition variable.
-#[unstable(feature = "static_condvar",
-           reason = "may be merged with Condvar in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Condvar::new` in a static should \
-                             suffice")]
-#[allow(deprecated)]
-pub const CONDVAR_INIT: StaticCondvar = StaticCondvar::new();
-
-#[allow(deprecated)]
 impl Condvar {
     /// Creates a new condition variable which is ready to be waited on and
     /// notified.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new() -> Condvar {
         Condvar {
-            inner: box StaticCondvar {
-                inner: sys::Condvar::new(),
-                mutex: AtomicUsize::new(0),
-            }
+            inner: box sys::Condvar::new(),
+            mutex: AtomicUsize::new(0),
         }
     }
 
@@ -157,9 +117,16 @@ impl Condvar {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>)
                        -> LockResult<MutexGuard<'a, T>> {
-        unsafe {
-            let me: &'static Condvar = &*(self as *const _);
-            me.inner.wait(guard)
+        let poisoned = unsafe {
+            let lock = mutex::guard_lock(&guard);
+            self.verify(lock);
+            self.inner.wait(lock);
+            mutex::guard_poison(&guard).get()
+        };
+        if poisoned {
+            Err(PoisonError::new(guard))
+        } else {
+            Ok(guard)
         }
     }
 
@@ -206,9 +173,16 @@ impl Condvar {
     pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>,
                                dur: Duration)
                                -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
-        unsafe {
-            let me: &'static Condvar = &*(self as *const _);
-            me.inner.wait_timeout(guard, dur)
+        let (poisoned, result) = unsafe {
+            let lock = mutex::guard_lock(&guard);
+            self.verify(lock);
+            let success = self.inner.wait_timeout(lock, dur);
+            (mutex::guard_poison(&guard).get(), WaitTimeoutResult(!success))
+        };
+        if poisoned {
+            Err(PoisonError::new((guard, result)))
+        } else {
+            Ok((guard, result))
         }
     }
 
@@ -220,7 +194,9 @@ impl Condvar {
     ///
     /// To wake up all threads, see `notify_all()`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn notify_one(&self) { unsafe { self.inner.inner.notify_one() } }
+    pub fn notify_one(&self) {
+        unsafe { self.inner.notify_one() }
+    }
 
     /// Wakes up all blocked threads on this condvar.
     ///
@@ -230,169 +206,8 @@ impl Condvar {
     ///
     /// To wake up only one thread, see `notify_one()`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn notify_all(&self) { unsafe { self.inner.inner.notify_all() } }
-}
-
-#[stable(feature = "condvar_default", since = "1.9.0")]
-impl Default for Condvar {
-    fn default() -> Condvar {
-        Condvar::new()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-impl Drop for Condvar {
-    fn drop(&mut self) {
-        unsafe { self.inner.inner.destroy() }
-    }
-}
-
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Condvar::new` in a static should \
-                             suffice")]
-#[unstable(feature = "static_condvar",
-           reason = "may be merged with Condvar in the future",
-           issue = "27717")]
-#[allow(deprecated)]
-impl StaticCondvar {
-    /// Creates a new condition variable
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub const fn new() -> StaticCondvar {
-        StaticCondvar {
-            inner: sys::Condvar::new(),
-            mutex: AtomicUsize::new(0),
-        }
-    }
-
-    /// Blocks the current thread until this condition variable receives a
-    /// notification.
-    ///
-    /// See `Condvar::wait`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn wait<'a, T>(&'static self, guard: MutexGuard<'a, T>)
-                       -> LockResult<MutexGuard<'a, T>> {
-        let poisoned = unsafe {
-            let lock = mutex::guard_lock(&guard);
-            self.verify(lock);
-            self.inner.wait(lock);
-            mutex::guard_poison(&guard).get()
-        };
-        if poisoned {
-            Err(PoisonError::new(guard))
-        } else {
-            Ok(guard)
-        }
-    }
-
-    /// Waits on this condition variable for a notification, timing out after a
-    /// specified duration.
-    ///
-    /// See `Condvar::wait_timeout`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn wait_timeout<'a, T>(&'static self,
-                               guard: MutexGuard<'a, T>,
-                               timeout: Duration)
-                               -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
-        let (poisoned, result) = unsafe {
-            let lock = mutex::guard_lock(&guard);
-            self.verify(lock);
-            let success = self.inner.wait_timeout(lock, timeout);
-            (mutex::guard_poison(&guard).get(), WaitTimeoutResult(!success))
-        };
-        if poisoned {
-            Err(PoisonError::new((guard, result)))
-        } else {
-            Ok((guard, result))
-        }
-    }
-
-    /// Waits on this condition variable for a notification, timing out after a
-    /// specified duration.
-    ///
-    /// The implementation will repeatedly wait while the duration has not
-    /// passed and the function returns `false`.
-    ///
-    /// See `Condvar::wait_timeout_with`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn wait_timeout_with<'a, T, F>(&'static self,
-                                       guard: MutexGuard<'a, T>,
-                                       dur: Duration,
-                                       mut f: F)
-                                       -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)>
-            where F: FnMut(LockResult<&mut T>) -> bool {
-        // This could be made more efficient by pushing the implementation into
-        // sys::condvar
-        let start = Instant::now();
-        let mut guard_result: LockResult<MutexGuard<'a, T>> = Ok(guard);
-        while !f(guard_result
-                    .as_mut()
-                    .map(|g| &mut **g)
-                    .map_err(|e| PoisonError::new(&mut **e.get_mut()))) {
-            let consumed = start.elapsed();
-            let guard = guard_result.unwrap_or_else(|e| e.into_inner());
-            let (new_guard_result, timed_out) = if consumed > dur {
-                (Ok(guard), WaitTimeoutResult(true))
-            } else {
-                match self.wait_timeout(guard, dur - consumed) {
-                    Ok((new_guard, timed_out)) => (Ok(new_guard), timed_out),
-                    Err(err) => {
-                        let (new_guard, no_timeout) = err.into_inner();
-                        (Err(PoisonError::new(new_guard)), no_timeout)
-                    }
-                }
-            };
-            guard_result = new_guard_result;
-            if timed_out.timed_out() {
-                let result = f(guard_result
-                                    .as_mut()
-                                    .map(|g| &mut **g)
-                                    .map_err(|e| PoisonError::new(&mut **e.get_mut())));
-                let result = WaitTimeoutResult(!result);
-                return poison::map_result(guard_result, |g| (g, result));
-            }
-        }
-
-        poison::map_result(guard_result, |g| (g, WaitTimeoutResult(false)))
-    }
-
-    /// Wakes up one blocked thread on this condvar.
-    ///
-    /// See `Condvar::notify_one`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn notify_one(&'static self) { unsafe { self.inner.notify_one() } }
-
-    /// Wakes up all blocked threads on this condvar.
-    ///
-    /// See `Condvar::notify_all`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn notify_all(&'static self) { unsafe { self.inner.notify_all() } }
-
-    /// Deallocates all resources associated with this static condvar.
-    ///
-    /// This method is unsafe to call as there is no guarantee that there are no
-    /// active users of the condvar, and this also doesn't prevent any future
-    /// users of the condvar. This method is required to be called to not leak
-    /// memory on all platforms.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub unsafe fn destroy(&'static self) {
-        self.inner.destroy()
+    pub fn notify_all(&self) {
+        unsafe { self.inner.notify_all() }
     }
 
     fn verify(&self, mutex: &sys_mutex::Mutex) {
@@ -414,15 +229,26 @@ impl StaticCondvar {
     }
 }
 
+#[stable(feature = "condvar_default", since = "1.9.0")]
+impl Default for Condvar {
+    fn default() -> Condvar {
+        Condvar::new()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Drop for Condvar {
+    fn drop(&mut self) {
+        unsafe { self.inner.destroy() }
+    }
+}
+
 #[cfg(test)]
-#[allow(deprecated)]
 mod tests {
     use prelude::v1::*;
 
-    use super::StaticCondvar;
     use sync::mpsc::channel;
-    use sync::{StaticMutex, Condvar, Mutex, Arc};
-    use sync::atomic::{AtomicUsize, Ordering};
+    use sync::{Condvar, Mutex, Arc};
     use thread;
     use time::Duration;
     use u32;
@@ -435,26 +261,19 @@ mod tests {
     }
 
     #[test]
-    fn static_smoke() {
-        static C: StaticCondvar = StaticCondvar::new();
-        C.notify_one();
-        C.notify_all();
-        unsafe { C.destroy(); }
-    }
-
-    #[test]
     fn notify_one() {
-        static C: StaticCondvar = StaticCondvar::new();
-        static M: StaticMutex = StaticMutex::new();
+        let m = Arc::new(Mutex::new(()));
+        let m2 = m.clone();
+        let c = Arc::new(Condvar::new());
+        let c2 = c.clone();
 
-        let g = M.lock().unwrap();
+        let g = m.lock().unwrap();
         let _t = thread::spawn(move|| {
-            let _g = M.lock().unwrap();
-            C.notify_one();
+            let _g = m2.lock().unwrap();
+            c2.notify_one();
         });
-        let g = C.wait(g).unwrap();
+        let g = c.wait(g).unwrap();
         drop(g);
-        unsafe { C.destroy(); M.destroy(); }
     }
 
     #[test]
@@ -495,84 +314,41 @@ mod tests {
 
     #[test]
     fn wait_timeout_ms() {
-        static C: StaticCondvar = StaticCondvar::new();
-        static M: StaticMutex = StaticMutex::new();
+        let m = Arc::new(Mutex::new(()));
+        let m2 = m.clone();
+        let c = Arc::new(Condvar::new());
+        let c2 = c.clone();
 
-        let g = M.lock().unwrap();
-        let (g, _no_timeout) = C.wait_timeout(g, Duration::from_millis(1)).unwrap();
+        let g = m.lock().unwrap();
+        let (g, _no_timeout) = c.wait_timeout(g, Duration::from_millis(1)).unwrap();
         // spurious wakeups mean this isn't necessarily true
         // assert!(!no_timeout);
         let _t = thread::spawn(move || {
-            let _g = M.lock().unwrap();
-            C.notify_one();
+            let _g = m2.lock().unwrap();
+            c2.notify_one();
         });
-        let (g, timeout_res) = C.wait_timeout(g, Duration::from_millis(u32::MAX as u64)).unwrap();
+        let (g, timeout_res) = c.wait_timeout(g, Duration::from_millis(u32::MAX as u64)).unwrap();
         assert!(!timeout_res.timed_out());
         drop(g);
-        unsafe { C.destroy(); M.destroy(); }
-    }
-
-    #[test]
-    fn wait_timeout_with() {
-        static C: StaticCondvar = StaticCondvar::new();
-        static M: StaticMutex = StaticMutex::new();
-        static S: AtomicUsize = AtomicUsize::new(0);
-
-        let g = M.lock().unwrap();
-        let (g, timed_out) = C.wait_timeout_with(g, Duration::new(0, 1000), |_| {
-            false
-        }).unwrap();
-        assert!(timed_out.timed_out());
-
-        let (tx, rx) = channel();
-        let _t = thread::spawn(move || {
-            rx.recv().unwrap();
-            let g = M.lock().unwrap();
-            S.store(1, Ordering::SeqCst);
-            C.notify_one();
-            drop(g);
-
-            rx.recv().unwrap();
-            let g = M.lock().unwrap();
-            S.store(2, Ordering::SeqCst);
-            C.notify_one();
-            drop(g);
-
-            rx.recv().unwrap();
-            let _g = M.lock().unwrap();
-            S.store(3, Ordering::SeqCst);
-            C.notify_one();
-        });
-
-        let mut state = 0;
-        let day = 24 * 60 * 60;
-        let (_g, timed_out) = C.wait_timeout_with(g, Duration::new(day, 0), |_| {
-            assert_eq!(state, S.load(Ordering::SeqCst));
-            tx.send(()).unwrap();
-            state += 1;
-            match state {
-                1|2 => false,
-                _ => true,
-            }
-        }).unwrap();
-        assert!(!timed_out.timed_out());
     }
 
     #[test]
     #[should_panic]
     fn two_mutexes() {
-        static M1: StaticMutex = StaticMutex::new();
-        static M2: StaticMutex = StaticMutex::new();
-        static C: StaticCondvar = StaticCondvar::new();
+        let m = Arc::new(Mutex::new(()));
+        let m2 = m.clone();
+        let c = Arc::new(Condvar::new());
+        let c2 = c.clone();
 
-        let mut g = M1.lock().unwrap();
+        let mut g = m.lock().unwrap();
         let _t = thread::spawn(move|| {
-            let _g = M1.lock().unwrap();
-            C.notify_one();
+            let _g = m2.lock().unwrap();
+            c2.notify_one();
         });
-        g = C.wait(g).unwrap();
+        g = c.wait(g).unwrap();
         drop(g);
 
-        let _ = C.wait(M2.lock().unwrap()).unwrap();
+        let m = Mutex::new(());
+        let _ = c.wait(m.lock().unwrap()).unwrap();
     }
 }
diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs
index 56eb7340c89..289b47b3484 100644
--- a/src/libstd/sync/mod.rs
+++ b/src/libstd/sync/mod.rs
@@ -25,23 +25,15 @@ pub use core::sync::atomic;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::barrier::{Barrier, BarrierWaitResult};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub use self::condvar::{Condvar, StaticCondvar, WaitTimeoutResult, CONDVAR_INIT};
+pub use self::condvar::{Condvar, WaitTimeoutResult};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub use self::mutex::MUTEX_INIT;
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
+pub use self::mutex::{Mutex, MutexGuard};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::once::{Once, OnceState, ONCE_INIT};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};
+pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
 
 pub mod mpsc;
 
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index 34bc210b3c8..d96fd6228e6 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -2181,6 +2181,15 @@ mod sync_tests {
     }
 
     #[test]
+    fn oneshot_single_thread_try_recv_closed_with_data() {
+        let (tx, rx) = sync_channel::<i32>(1);
+        tx.send(10).unwrap();
+        drop(tx);
+        assert_eq!(rx.try_recv(), Ok(10));
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+    }
+
+    #[test]
     fn oneshot_single_thread_peek_data() {
         let (tx, rx) = sync_channel::<i32>(1);
         assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs
index f021689acad..9d13a71ff95 100644
--- a/src/libstd/sync/mpsc/sync.rs
+++ b/src/libstd/sync/mpsc/sync.rs
@@ -309,7 +309,7 @@ impl<T> Packet<T> {
         let mut guard = self.lock.lock().unwrap();
 
         // Easy cases first
-        if guard.disconnected { return Err(Disconnected) }
+        if guard.disconnected && guard.buf.size() == 0 { return Err(Disconnected) }
         if guard.buf.size() == 0 { return Err(Empty) }
 
         // Be sure to wake up neighbors
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index c75a5c09146..6bc458397f1 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -113,14 +113,14 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
 /// *guard += 1;
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 pub struct Mutex<T: ?Sized> {
-    // Note that this static mutex is in a *box*, not inlined into the struct
-    // itself. Once a native mutex has been used once, its address can never
-    // change (it can't be moved). This mutex type can be safely moved at any
-    // time, so to ensure that the native mutex is used correctly we box the
-    // inner lock to give it a constant address.
-    inner: Box<StaticMutex>,
+    // Note that this mutex is in a *box*, not inlined into the struct itself.
+    // Once a native mutex has been used once, its address can never change (it
+    // can't be moved). This mutex type can be safely moved at any time, so to
+    // ensure that the native mutex is used correctly we box the inner lock to
+    // give it a constant address.
+    inner: Box<sys::Mutex>,
+    poison: poison::Flag,
     data: UnsafeCell<T>,
 }
 
@@ -131,42 +131,6 @@ unsafe impl<T: ?Sized + Send> Send for Mutex<T> { }
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
 
-/// The static mutex type is provided to allow for static allocation of mutexes.
-///
-/// Note that this is a separate type because using a Mutex correctly means that
-/// it needs to have a destructor run. In Rust, statics are not allowed to have
-/// destructors. As a result, a `StaticMutex` has one extra method when compared
-/// to a `Mutex`, a `destroy` method. This method is unsafe to call, and
-/// documentation can be found directly on the method.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(static_mutex)]
-///
-/// use std::sync::{StaticMutex, MUTEX_INIT};
-///
-/// static LOCK: StaticMutex = MUTEX_INIT;
-///
-/// {
-///     let _g = LOCK.lock().unwrap();
-///     // do some productive work
-/// }
-/// // lock is unlocked here.
-/// ```
-#[unstable(feature = "static_mutex",
-           reason = "may be merged with Mutex in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Mutex::new` in a static should \
-                             suffice")]
-pub struct StaticMutex {
-    lock: sys::Mutex,
-    poison: poison::Flag,
-}
-
 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
 /// dropped (falls out of scope), the lock will be unlocked.
 ///
@@ -174,48 +138,32 @@ pub struct StaticMutex {
 /// `Deref` and `DerefMut` implementations
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 pub struct MutexGuard<'a, T: ?Sized + 'a> {
     // funny underscores due to how Deref/DerefMut currently work (they
     // disregard field privacy).
-    __lock: &'a StaticMutex,
-    __data: &'a mut T,
+    __lock: &'a Mutex<T>,
     __poison: poison::Guard,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized> !marker::Send for MutexGuard<'a, T> {}
 
-/// Static initialization of a mutex. This constant can be used to initialize
-/// other mutex constants.
-#[unstable(feature = "static_mutex",
-           reason = "may be merged with Mutex in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Mutex::new` in a static should \
-                             suffice")]
-#[allow(deprecated)]
-pub const MUTEX_INIT: StaticMutex = StaticMutex::new();
-
-#[allow(deprecated)]
 impl<T> 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> {
         let mut m = Mutex {
-            inner: box StaticMutex::new(),
+            inner: box sys::Mutex::new(),
+            poison: poison::Flag::new(),
             data: UnsafeCell::new(t),
         };
         unsafe {
-            m.inner.lock.init();
+            m.inner.init();
         }
         m
     }
 }
 
-#[allow(deprecated)]
 impl<T: ?Sized> Mutex<T> {
     /// Acquires a mutex, blocking the current thread until it is able to do so.
     ///
@@ -240,8 +188,8 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> LockResult<MutexGuard<T>> {
         unsafe {
-            self.inner.lock.lock();
-            MutexGuard::new(&*self.inner, &self.data)
+            self.inner.lock();
+            MutexGuard::new(self)
         }
     }
 
@@ -261,8 +209,8 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_lock(&self) -> TryLockResult<MutexGuard<T>> {
         unsafe {
-            if self.inner.lock.try_lock() {
-                Ok(MutexGuard::new(&*self.inner, &self.data)?)
+            if self.inner.try_lock() {
+                Ok(MutexGuard::new(self)?)
             } else {
                 Err(TryLockError::WouldBlock)
             }
@@ -277,7 +225,7 @@ impl<T: ?Sized> Mutex<T> {
     #[inline]
     #[stable(feature = "sync_poison", since = "1.2.0")]
     pub fn is_poisoned(&self) -> bool {
-        self.inner.poison.get()
+        self.poison.get()
     }
 
     /// Consumes this mutex, returning the underlying data.
@@ -289,21 +237,22 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "mutex_into_inner", since = "1.6.0")]
     pub fn into_inner(self) -> LockResult<T> where T: Sized {
         // We know statically that there are no outstanding references to
-        // `self` so there's no need to lock the inner StaticMutex.
+        // `self` so there's no need to lock the inner lock.
         //
         // To get the inner value, we'd like to call `data.into_inner()`,
         // but because `Mutex` impl-s `Drop`, we can't move out of it, so
         // we'll have to destructure it manually instead.
         unsafe {
-            // Like `let Mutex { inner, data } = self`.
-            let (inner, data) = {
-                let Mutex { ref inner, ref data } = self;
-                (ptr::read(inner), ptr::read(data))
+            // Like `let Mutex { inner, poison, data } = self`.
+            let (inner, poison, data) = {
+                let Mutex { ref inner, ref poison, ref data } = self;
+                (ptr::read(inner), ptr::read(poison), ptr::read(data))
             };
             mem::forget(self);
-            inner.lock.destroy();  // Keep in sync with the `Drop` impl.
+            inner.destroy();  // Keep in sync with the `Drop` impl.
+            drop(inner);
 
-            poison::map_result(inner.poison.borrow(), |_| data.into_inner())
+            poison::map_result(poison.borrow(), |_| data.into_inner())
         }
     }
 
@@ -319,14 +268,13 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "mutex_get_mut", since = "1.6.0")]
     pub fn get_mut(&mut self) -> LockResult<&mut T> {
         // We know statically that there are no other references to `self`, so
-        // there's no need to lock the inner StaticMutex.
+        // there's no need to lock the inner lock.
         let data = unsafe { &mut *self.data.get() };
-        poison::map_result(self.inner.poison.borrow(), |_| data )
+        poison::map_result(self.poison.borrow(), |_| data )
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 impl<T: ?Sized> Drop for Mutex<T> {
     #[unsafe_destructor_blind_to_params]
     fn drop(&mut self) {
@@ -335,7 +283,7 @@ impl<T: ?Sized> Drop for Mutex<T> {
         // dropped, that's not our job)
         //
         // IMPORTANT: This code must be kept in sync with `Mutex::into_inner`.
-        unsafe { self.inner.lock.destroy() }
+        unsafe { self.inner.destroy() }
     }
 }
 
@@ -359,72 +307,11 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
     }
 }
 
-struct Dummy(UnsafeCell<()>);
-unsafe impl Sync for Dummy {}
-static DUMMY: Dummy = Dummy(UnsafeCell::new(()));
-
-#[unstable(feature = "static_mutex",
-           reason = "may be merged with Mutex in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Mutex::new` in a static should \
-                             suffice")]
-#[allow(deprecated)]
-impl StaticMutex {
-    /// Creates a new mutex in an unlocked state ready for use.
-    pub const fn new() -> StaticMutex {
-        StaticMutex {
-            lock: sys::Mutex::new(),
-            poison: poison::Flag::new(),
-        }
-    }
-
-    /// Acquires this lock, see `Mutex::lock`
-    #[inline]
-    pub fn lock(&'static self) -> LockResult<MutexGuard<()>> {
-        unsafe {
-            self.lock.lock();
-            MutexGuard::new(self, &DUMMY.0)
-        }
-    }
-
-    /// Attempts to grab this lock, see `Mutex::try_lock`
-    #[inline]
-    pub fn try_lock(&'static self) -> TryLockResult<MutexGuard<()>> {
-        unsafe {
-            if self.lock.try_lock() {
-                Ok(MutexGuard::new(self, &DUMMY.0)?)
-            } else {
-                Err(TryLockError::WouldBlock)
-            }
-        }
-    }
-
-    /// Deallocates resources associated with this static mutex.
-    ///
-    /// This method is unsafe because it provides no guarantees that there are
-    /// no active users of this mutex, and safety is not guaranteed if there are
-    /// active users of this mutex.
-    ///
-    /// This method is required to ensure that there are no memory leaks on
-    /// *all* platforms. It may be the case that some platforms do not leak
-    /// memory if this method is not called, but this is not guaranteed to be
-    /// true on all platforms.
-    pub unsafe fn destroy(&'static self) {
-        self.lock.destroy()
-    }
-}
-
-#[allow(deprecated)]
 impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
-    unsafe fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>)
-           -> LockResult<MutexGuard<'mutex, T>> {
+    unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> {
         poison::map_result(lock.poison.borrow(), |guard| {
             MutexGuard {
                 __lock: lock,
-                __data: &mut *data.get(),
                 __poison: guard,
             }
         })
@@ -435,43 +322,43 @@ impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
 impl<'mutex, T: ?Sized> Deref for MutexGuard<'mutex, T> {
     type Target = T;
 
-    fn deref(&self) -> &T {self.__data }
+    fn deref(&self) -> &T {
+        unsafe { &*self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'mutex, T: ?Sized> DerefMut for MutexGuard<'mutex, T> {
-    fn deref_mut(&mut self) -> &mut T { self.__data }
+    fn deref_mut(&mut self) -> &mut T {
+        unsafe { &mut *self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
     #[inline]
     fn drop(&mut self) {
         unsafe {
             self.__lock.poison.done(&self.__poison);
-            self.__lock.lock.unlock();
+            self.__lock.inner.unlock();
         }
     }
 }
 
-#[allow(deprecated)]
 pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
-    &guard.__lock.lock
+    &guard.__lock.inner
 }
 
-#[allow(deprecated)]
 pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
     &guard.__lock.poison
 }
 
 #[cfg(test)]
-#[allow(deprecated)]
 mod tests {
     use prelude::v1::*;
 
     use sync::mpsc::channel;
-    use sync::{Arc, Mutex, StaticMutex, Condvar};
+    use sync::{Arc, Mutex, Condvar};
     use sync::atomic::{AtomicUsize, Ordering};
     use thread;
 
@@ -491,47 +378,33 @@ mod tests {
     }
 
     #[test]
-    fn smoke_static() {
-        static M: StaticMutex = StaticMutex::new();
-        unsafe {
-            drop(M.lock().unwrap());
-            drop(M.lock().unwrap());
-            M.destroy();
-        }
-    }
-
-    #[test]
     fn lots_and_lots() {
-        static M: StaticMutex = StaticMutex::new();
-        static mut CNT: u32 = 0;
         const J: u32 = 1000;
         const K: u32 = 3;
 
-        fn inc() {
+        let m = Arc::new(Mutex::new(0));
+
+        fn inc(m: &Mutex<u32>) {
             for _ in 0..J {
-                unsafe {
-                    let _g = M.lock().unwrap();
-                    CNT += 1;
-                }
+                *m.lock().unwrap() += 1;
             }
         }
 
         let (tx, rx) = channel();
         for _ in 0..K {
             let tx2 = tx.clone();
-            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
+            let m2 = m.clone();
+            thread::spawn(move|| { inc(&m2); tx2.send(()).unwrap(); });
             let tx2 = tx.clone();
-            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
+            let m2 = m.clone();
+            thread::spawn(move|| { inc(&m2); tx2.send(()).unwrap(); });
         }
 
         drop(tx);
         for _ in 0..2 * K {
             rx.recv().unwrap();
         }
-        assert_eq!(unsafe {CNT}, J * K * 2);
-        unsafe {
-            M.destroy();
-        }
+        assert_eq!(*m.lock().unwrap(), J * K * 2);
     }
 
     #[test]
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index e9ea465cc99..54c1fe6c564 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -65,6 +65,7 @@
 // it!
 
 use marker;
+use ptr;
 use sync::atomic::{AtomicUsize, AtomicBool, Ordering};
 use thread::{self, Thread};
 
@@ -297,7 +298,7 @@ impl Once {
                     let mut node = Waiter {
                         thread: Some(thread::current()),
                         signaled: AtomicBool::new(false),
-                        next: 0 as *mut Waiter,
+                        next: ptr::null_mut(),
                     };
                     let me = &mut node as *mut Waiter as usize;
                     assert!(me & STATE_MASK == 0);
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 03d3483902d..65b5686de86 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -66,9 +66,9 @@ use sys_common::rwlock as sys;
 /// } // write lock is dropped here
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 pub struct RwLock<T: ?Sized> {
-    inner: Box<StaticRwLock>,
+    inner: Box<sys::RWLock>,
+    poison: poison::Flag,
     data: UnsafeCell<T>,
 }
 
@@ -77,64 +77,12 @@ unsafe impl<T: ?Sized + Send + Sync> Send for RwLock<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
 
-/// Structure representing a statically allocated RwLock.
-///
-/// This structure is intended to be used inside of a `static` and will provide
-/// automatic global access as well as lazy initialization. The internal
-/// resources of this RwLock, however, must be manually deallocated.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(static_rwlock)]
-///
-/// use std::sync::{StaticRwLock, RW_LOCK_INIT};
-///
-/// static LOCK: StaticRwLock = RW_LOCK_INIT;
-///
-/// {
-///     let _g = LOCK.read().unwrap();
-///     // ... shared read access
-/// }
-/// {
-///     let _g = LOCK.write().unwrap();
-///     // ... exclusive write access
-/// }
-/// unsafe { LOCK.destroy() } // free all resources
-/// ```
-#[unstable(feature = "static_rwlock",
-           reason = "may be merged with RwLock in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `RwLock::new` in a static should \
-                             suffice")]
-pub struct StaticRwLock {
-    lock: sys::RWLock,
-    poison: poison::Flag,
-}
-
-/// Constant initialization for a statically-initialized rwlock.
-#[unstable(feature = "static_rwlock",
-           reason = "may be merged with RwLock in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `RwLock::new` in a static should \
-                             suffice")]
-#[allow(deprecated)]
-pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock::new();
-
 /// RAII structure used to release the shared read access of a lock when
 /// dropped.
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
-    __lock: &'a StaticRwLock,
-    __data: &'a T,
+    __lock: &'a RwLock<T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -144,17 +92,14 @@ impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {}
 /// dropped.
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
-    __lock: &'a StaticRwLock,
-    __data: &'a mut T,
+    __lock: &'a RwLock<T>,
     __poison: poison::Guard,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized> !marker::Send for RwLockWriteGuard<'a, T> {}
 
-#[allow(deprecated)]
 impl<T> RwLock<T> {
     /// Creates a new instance of an `RwLock<T>` which is unlocked.
     ///
@@ -167,11 +112,14 @@ impl<T> RwLock<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> RwLock<T> {
-        RwLock { inner: box StaticRwLock::new(), data: UnsafeCell::new(t) }
+        RwLock {
+            inner: box sys::RWLock::new(),
+            poison: poison::Flag::new(),
+            data: UnsafeCell::new(t),
+        }
     }
 }
 
-#[allow(deprecated)]
 impl<T: ?Sized> RwLock<T> {
     /// Locks this rwlock with shared read access, blocking the current thread
     /// until it can be acquired.
@@ -194,8 +142,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
         unsafe {
-            self.inner.lock.read();
-            RwLockReadGuard::new(&*self.inner, &self.data)
+            self.inner.read();
+            RwLockReadGuard::new(self)
         }
     }
 
@@ -220,8 +168,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<T>> {
         unsafe {
-            if self.inner.lock.try_read() {
-                Ok(RwLockReadGuard::new(&*self.inner, &self.data)?)
+            if self.inner.try_read() {
+                Ok(RwLockReadGuard::new(self)?)
             } else {
                 Err(TryLockError::WouldBlock)
             }
@@ -246,8 +194,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> {
         unsafe {
-            self.inner.lock.write();
-            RwLockWriteGuard::new(&*self.inner, &self.data)
+            self.inner.write();
+            RwLockWriteGuard::new(self)
         }
     }
 
@@ -272,8 +220,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> {
         unsafe {
-            if self.inner.lock.try_write() {
-                Ok(RwLockWriteGuard::new(&*self.inner, &self.data)?)
+            if self.inner.try_write() {
+                Ok(RwLockWriteGuard::new(self)?)
             } else {
                 Err(TryLockError::WouldBlock)
             }
@@ -288,7 +236,7 @@ impl<T: ?Sized> RwLock<T> {
     #[inline]
     #[stable(feature = "sync_poison", since = "1.2.0")]
     pub fn is_poisoned(&self) -> bool {
-        self.inner.poison.get()
+        self.poison.get()
     }
 
     /// Consumes this `RwLock`, returning the underlying data.
@@ -302,21 +250,22 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rwlock_into_inner", since = "1.6.0")]
     pub fn into_inner(self) -> LockResult<T> where T: Sized {
         // We know statically that there are no outstanding references to
-        // `self` so there's no need to lock the inner StaticRwLock.
+        // `self` so there's no need to lock the inner lock.
         //
         // To get the inner value, we'd like to call `data.into_inner()`,
         // but because `RwLock` impl-s `Drop`, we can't move out of it, so
         // we'll have to destructure it manually instead.
         unsafe {
-            // Like `let RwLock { inner, data } = self`.
-            let (inner, data) = {
-                let RwLock { ref inner, ref data } = self;
-                (ptr::read(inner), ptr::read(data))
+            // Like `let RwLock { inner, poison, data } = self`.
+            let (inner, poison, data) = {
+                let RwLock { ref inner, ref poison, ref data } = self;
+                (ptr::read(inner), ptr::read(poison), ptr::read(data))
             };
             mem::forget(self);
-            inner.lock.destroy();  // Keep in sync with the `Drop` impl.
+            inner.destroy();  // Keep in sync with the `Drop` impl.
+            drop(inner);
 
-            poison::map_result(inner.poison.borrow(), |_| data.into_inner())
+            poison::map_result(poison.borrow(), |_| data.into_inner())
         }
     }
 
@@ -334,19 +283,18 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rwlock_get_mut", since = "1.6.0")]
     pub fn get_mut(&mut self) -> LockResult<&mut T> {
         // We know statically that there are no other references to `self`, so
-        // there's no need to lock the inner StaticRwLock.
+        // there's no need to lock the inner lock.
         let data = unsafe { &mut *self.data.get() };
-        poison::map_result(self.inner.poison.borrow(), |_| data )
+        poison::map_result(self.poison.borrow(), |_| data)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 impl<T: ?Sized> Drop for RwLock<T> {
     #[unsafe_destructor_blind_to_params]
     fn drop(&mut self) {
         // IMPORTANT: This code needs to be kept in sync with `RwLock::into_inner`.
-        unsafe { self.inner.lock.destroy() }
+        unsafe { self.inner.destroy() }
     }
 }
 
@@ -370,114 +318,23 @@ impl<T: Default> Default for RwLock<T> {
     }
 }
 
-struct Dummy(UnsafeCell<()>);
-unsafe impl Sync for Dummy {}
-static DUMMY: Dummy = Dummy(UnsafeCell::new(()));
-
-#[unstable(feature = "static_rwlock",
-           reason = "may be merged with RwLock in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `RwLock::new` in a static should \
-                             suffice")]
-#[allow(deprecated)]
-impl StaticRwLock {
-    /// Creates a new rwlock.
-    pub const fn new() -> StaticRwLock {
-        StaticRwLock {
-            lock: sys::RWLock::new(),
-            poison: poison::Flag::new(),
-        }
-    }
-
-    /// Locks this rwlock with shared read access, blocking the current thread
-    /// until it can be acquired.
-    ///
-    /// See `RwLock::read`.
-    #[inline]
-    pub fn read(&'static self) -> LockResult<RwLockReadGuard<'static, ()>> {
-        unsafe {
-            self.lock.read();
-            RwLockReadGuard::new(self, &DUMMY.0)
-        }
-    }
-
-    /// Attempts to acquire this lock with shared read access.
-    ///
-    /// See `RwLock::try_read`.
-    #[inline]
-    pub fn try_read(&'static self)
-                    -> TryLockResult<RwLockReadGuard<'static, ()>> {
-        unsafe {
-            if self.lock.try_read(){
-                Ok(RwLockReadGuard::new(self, &DUMMY.0)?)
-            } else {
-                Err(TryLockError::WouldBlock)
-            }
-        }
-    }
-
-    /// Locks this rwlock with exclusive write access, blocking the current
-    /// thread until it can be acquired.
-    ///
-    /// See `RwLock::write`.
-    #[inline]
-    pub fn write(&'static self) -> LockResult<RwLockWriteGuard<'static, ()>> {
-        unsafe {
-            self.lock.write();
-            RwLockWriteGuard::new(self, &DUMMY.0)
-        }
-    }
-
-    /// Attempts to lock this rwlock with exclusive write access.
-    ///
-    /// See `RwLock::try_write`.
-    #[inline]
-    pub fn try_write(&'static self)
-                     -> TryLockResult<RwLockWriteGuard<'static, ()>> {
-        unsafe {
-            if self.lock.try_write() {
-                Ok(RwLockWriteGuard::new(self, &DUMMY.0)?)
-            } else {
-                Err(TryLockError::WouldBlock)
-            }
-        }
-    }
-
-    /// Deallocates all resources associated with this static lock.
-    ///
-    /// This method is unsafe to call as there is no guarantee that there are no
-    /// active users of the lock, and this also doesn't prevent any future users
-    /// of this lock. This method is required to be called to not leak memory on
-    /// all platforms.
-    pub unsafe fn destroy(&'static self) {
-        self.lock.destroy()
-    }
-}
-
-#[allow(deprecated)]
 impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
-    unsafe fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
-           -> LockResult<RwLockReadGuard<'rwlock, T>> {
+    unsafe fn new(lock: &'rwlock RwLock<T>)
+                  -> LockResult<RwLockReadGuard<'rwlock, T>> {
         poison::map_result(lock.poison.borrow(), |_| {
             RwLockReadGuard {
                 __lock: lock,
-                __data: &*data.get(),
             }
         })
     }
 }
 
-#[allow(deprecated)]
 impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
-    unsafe fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
-           -> LockResult<RwLockWriteGuard<'rwlock, T>> {
+    unsafe fn new(lock: &'rwlock RwLock<T>)
+                  -> LockResult<RwLockWriteGuard<'rwlock, T>> {
         poison::map_result(lock.poison.borrow(), |guard| {
             RwLockWriteGuard {
                 __lock: lock,
-                __data: &mut *data.get(),
                 __poison: guard,
             }
         })
@@ -488,42 +345,43 @@ impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
 impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
     type Target = T;
 
-    fn deref(&self) -> &T { self.__data }
+    fn deref(&self) -> &T {
+        unsafe { &*self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'rwlock, T: ?Sized> Deref for RwLockWriteGuard<'rwlock, T> {
     type Target = T;
 
-    fn deref(&self) -> &T { self.__data }
+    fn deref(&self) -> &T {
+        unsafe { &*self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'rwlock, T: ?Sized> DerefMut for RwLockWriteGuard<'rwlock, T> {
     fn deref_mut(&mut self) -> &mut T {
-        self.__data
+        unsafe { &mut *self.__lock.data.get() }
     }
 }
 
-#[allow(deprecated)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T> {
     fn drop(&mut self) {
-        unsafe { self.__lock.lock.read_unlock(); }
+        unsafe { self.__lock.inner.read_unlock(); }
     }
 }
 
-#[allow(deprecated)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized> Drop for RwLockWriteGuard<'a, T> {
     fn drop(&mut self) {
         self.__lock.poison.done(&self.__poison);
-        unsafe { self.__lock.lock.write_unlock(); }
+        unsafe { self.__lock.inner.write_unlock(); }
     }
 }
 
 #[cfg(test)]
-#[allow(deprecated)]
 mod tests {
     #![allow(deprecated)] // rand
 
@@ -532,7 +390,7 @@ mod tests {
     use rand::{self, Rng};
     use sync::mpsc::channel;
     use thread;
-    use sync::{Arc, RwLock, StaticRwLock, TryLockError};
+    use sync::{Arc, RwLock, TryLockError};
     use sync::atomic::{AtomicUsize, Ordering};
 
     #[derive(Eq, PartialEq, Debug)]
@@ -548,31 +406,23 @@ mod tests {
     }
 
     #[test]
-    fn static_smoke() {
-        static R: StaticRwLock = StaticRwLock::new();
-        drop(R.read().unwrap());
-        drop(R.write().unwrap());
-        drop((R.read().unwrap(), R.read().unwrap()));
-        drop(R.write().unwrap());
-        unsafe { R.destroy(); }
-    }
-
-    #[test]
     fn frob() {
-        static R: StaticRwLock = StaticRwLock::new();
         const N: usize = 10;
         const M: usize = 1000;
 
+        let r = Arc::new(RwLock::new(()));
+
         let (tx, rx) = channel::<()>();
         for _ in 0..N {
             let tx = tx.clone();
-            thread::spawn(move|| {
+            let r = r.clone();
+            thread::spawn(move || {
                 let mut rng = rand::thread_rng();
                 for _ in 0..M {
                     if rng.gen_weighted_bool(N) {
-                        drop(R.write().unwrap());
+                        drop(r.write().unwrap());
                     } else {
-                        drop(R.read().unwrap());
+                        drop(r.read().unwrap());
                     }
                 }
                 drop(tx);
@@ -580,7 +430,6 @@ mod tests {
         }
         drop(tx);
         let _ = rx.recv();
-        unsafe { R.destroy(); }
     }
 
     #[test]
diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs
index 6f185437e50..4c23ceb63f2 100644
--- a/src/libstd/sys/common/backtrace.rs
+++ b/src/libstd/sys/common/backtrace.rs
@@ -170,7 +170,9 @@ pub fn demangle(writer: &mut Write, s: &str) -> io::Result<()> {
                         "$u20$", => b" ",
                         "$u27$", => b"'",
                         "$u5b$", => b"[",
-                        "$u5d$", => b"]"
+                        "$u5d$", => b"]",
+                        "$u7b$", => b"{",
+                        "$u7d$", => b"}"
                     )
                 } else {
                     let idx = match rest.find('$') {
diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs
index 26925b12f93..442618c55b3 100644
--- a/src/libstd/sys/common/net.rs
+++ b/src/libstd/sys/common/net.rs
@@ -25,19 +25,23 @@ use time::Duration;
 
 #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
           target_os = "ios", target_os = "macos",
-          target_os = "openbsd", target_os = "netbsd"))]
+          target_os = "openbsd", target_os = "netbsd",
+          target_os = "solaris"))]
 use sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
 #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
               target_os = "ios", target_os = "macos",
-          target_os = "openbsd", target_os = "netbsd")))]
+              target_os = "openbsd", target_os = "netbsd",
+              target_os = "solaris")))]
 use sys::net::netc::IPV6_ADD_MEMBERSHIP;
 #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
           target_os = "ios", target_os = "macos",
-          target_os = "openbsd", target_os = "netbsd"))]
+          target_os = "openbsd", target_os = "netbsd",
+          target_os = "solaris"))]
 use sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP;
 #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
               target_os = "ios", target_os = "macos",
-          target_os = "openbsd", target_os = "netbsd")))]
+              target_os = "openbsd", target_os = "netbsd",
+              target_os = "solaris")))]
 use sys::net::netc::IPV6_DROP_MEMBERSHIP;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -601,3 +605,22 @@ impl fmt::Debug for UdpSocket {
             .finish()
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use prelude::v1::*;
+
+    use super::*;
+    use collections::HashMap;
+
+    #[test]
+    fn no_lookup_host_duplicates() {
+        let mut addrs = HashMap::new();
+        let lh = match lookup_host("localhost") {
+            Ok(lh) => lh,
+            Err(e) => panic!("couldn't resolve `localhost': {}", e)
+        };
+        let _na = lh.map(|sa| *addrs.entry(sa).or_insert(0) += 1).count();
+        assert!(addrs.values().filter(|&&v| v > 1).count() == 0);
+    }
+}
diff --git a/src/libstd/sys/common/poison.rs b/src/libstd/sys/common/poison.rs
index 83780a31cce..55212bf35d6 100644
--- a/src/libstd/sys/common/poison.rs
+++ b/src/libstd/sys/common/poison.rs
@@ -8,22 +8,28 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use cell::Cell;
 use error::{Error};
 use fmt;
 use marker::Reflect;
+use sync::atomic::{AtomicBool, Ordering};
 use thread;
 
-pub struct Flag { failed: Cell<bool> }
+pub struct Flag { failed: AtomicBool }
 
-// This flag is only ever accessed with a lock previously held. Note that this
-// a totally private structure.
-unsafe impl Send for Flag {}
-unsafe impl Sync for Flag {}
+// Note that the Ordering uses to access the `failed` field of `Flag` below is
+// always `Relaxed`, and that's because this isn't actually protecting any data,
+// it's just a flag whether we've panicked or not.
+//
+// The actual location that this matters is when a mutex is **locked** which is
+// where we have external synchronization ensuring that we see memory
+// reads/writes to this flag.
+//
+// As a result, if it matters, we should see the correct value for `failed` in
+// all cases.
 
 impl Flag {
     pub const fn new() -> Flag {
-        Flag { failed: Cell::new(false) }
+        Flag { failed: AtomicBool::new(false) }
     }
 
     #[inline]
@@ -39,13 +45,13 @@ impl Flag {
     #[inline]
     pub fn done(&self, guard: &Guard) {
         if !guard.panicking && thread::panicking() {
-            self.failed.set(true);
+            self.failed.store(true, Ordering::Relaxed);
         }
     }
 
     #[inline]
     pub fn get(&self) -> bool {
-        self.failed.get()
+        self.failed.load(Ordering::Relaxed)
     }
 }
 
diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs
index b6be85a4dfa..2c1a656290f 100644
--- a/src/libstd/sys/common/wtf8.rs
+++ b/src/libstd/sys/common/wtf8.rs
@@ -566,7 +566,7 @@ impl Wtf8 {
         if len < 3 {
             return None
         }
-        match ::slice_pat(&&self.bytes[(len - 3)..]) {
+        match &self.bytes[(len - 3)..] {
             &[0xED, b2 @ 0xA0...0xAF, b3] => Some(decode_surrogate(b2, b3)),
             _ => None
         }
@@ -578,7 +578,7 @@ impl Wtf8 {
         if len < 3 {
             return None
         }
-        match ::slice_pat(&&self.bytes[..3]) {
+        match &self.bytes[..3] {
             &[0xED, b2 @ 0xB0...0xBF, b3] => Some(decode_surrogate(b2, b3)),
             _ => None
         }
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 0524851df91..b315e676263 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -84,7 +84,7 @@ pub struct OpenOptions {
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct FilePermissions { mode: mode_t }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct FileType { mode: mode_t }
 
 pub struct DirBuilder { mode: mode_t }
@@ -205,9 +205,15 @@ impl Iterator for ReadDir {
                 // of the thread safety, on Illumos the readdir(3C) function is safe to use
                 // in threaded applications and it is generally preferred over the
                 // readdir_r(3C) function.
+                super::os::set_errno(0);
                 let entry_ptr = libc::readdir(self.dirp.0);
                 if entry_ptr.is_null() {
-                    return None
+                    // NULL can mean either the end is reached or an error occurred.
+                    // So we had to clear errno beforehand to check for an error now.
+                    return match super::os::errno() {
+                        0 => None,
+                        e => Some(Err(Error::from_raw_os_error(e))),
+                    }
                 }
 
                 let name = (*entry_ptr).d_name.as_ptr();
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 21ce6b19ceb..63e13f0bb47 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -35,28 +35,37 @@ use vec;
 const TMPBUF_SZ: usize = 128;
 static ENV_LOCK: Mutex = Mutex::new();
 
+
+extern {
+    #[cfg_attr(any(target_os = "linux", target_os = "emscripten"),
+               link_name = "__errno_location")]
+    #[cfg_attr(any(target_os = "bitrig",
+                   target_os = "netbsd",
+                   target_os = "openbsd",
+                   target_os = "android",
+                   target_env = "newlib"),
+               link_name = "__errno")]
+    #[cfg_attr(target_os = "solaris", link_name = "___errno")]
+    #[cfg_attr(any(target_os = "macos",
+                   target_os = "ios",
+                   target_os = "freebsd"),
+               link_name = "__error")]
+    fn errno_location() -> *mut c_int;
+}
+
 /// Returns the platform-specific value of errno
 #[cfg(not(target_os = "dragonfly"))]
 pub fn errno() -> i32 {
-    extern {
-        #[cfg_attr(any(target_os = "linux", target_os = "emscripten"),
-                   link_name = "__errno_location")]
-        #[cfg_attr(any(target_os = "bitrig",
-                       target_os = "netbsd",
-                       target_os = "openbsd",
-                       target_os = "android",
-                       target_env = "newlib"),
-                   link_name = "__errno")]
-        #[cfg_attr(target_os = "solaris", link_name = "___errno")]
-        #[cfg_attr(any(target_os = "macos",
-                       target_os = "ios",
-                       target_os = "freebsd"),
-                   link_name = "__error")]
-        fn errno_location() -> *const c_int;
+    unsafe {
+        (*errno_location()) as i32
     }
+}
 
+/// Sets the platform-specific value of errno
+#[cfg(target_os = "solaris")] // only needed for readdir so far
+pub fn set_errno(e: i32) {
     unsafe {
-        (*errno_location()) as i32
+        *errno_location() = e as c_int
     }
 }
 
@@ -227,11 +236,11 @@ pub fn current_exe() -> io::Result<PathBuf> {
                        libc::KERN_PROC_ARGV];
         let mib = mib.as_mut_ptr();
         let mut argv_len = 0;
-        cvt(libc::sysctl(mib, 4, 0 as *mut _, &mut argv_len,
-                         0 as *mut _, 0))?;
+        cvt(libc::sysctl(mib, 4, ptr::null_mut(), &mut argv_len,
+                         ptr::null_mut(), 0))?;
         let mut argv = Vec::<*const libc::c_char>::with_capacity(argv_len as usize);
         cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _,
-                         &mut argv_len, 0 as *mut _, 0))?;
+                         &mut argv_len, ptr::null_mut(), 0))?;
         argv.set_len(argv_len as usize);
         if argv[0].is_null() {
             return Err(io::Error::new(io::ErrorKind::Other,
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index 2dde9c0e615..01059413338 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -14,6 +14,7 @@ use cmp;
 use io;
 use libc::{self, c_int};
 use mem;
+use ptr;
 use sys::cvt_r;
 use sys::fd::FileDesc;
 
@@ -92,8 +93,8 @@ pub fn read2(p1: AnonPipe,
             let mut read: libc::fd_set = mem::zeroed();
             libc::FD_SET(p1.raw(), &mut read);
             libc::FD_SET(p2.raw(), &mut read);
-            libc::select(max + 1, &mut read, 0 as *mut _, 0 as *mut _,
-                         0 as *mut _)
+            libc::select(max + 1, &mut read, ptr::null_mut(), ptr::null_mut(),
+                         ptr::null_mut())
         })?;
 
         // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs
index 98cfdcdf110..d68867fb3d2 100644
--- a/src/libstd/sys/unix/process.rs
+++ b/src/libstd/sys/unix/process.rs
@@ -96,7 +96,7 @@ impl Command {
         let mut saw_nul = false;
         let program = os2c(program, &mut saw_nul);
         Command {
-            argv: vec![program.as_ptr(), 0 as *const _],
+            argv: vec![program.as_ptr(), ptr::null()],
             program: program,
             args: Vec::new(),
             env: None,
@@ -117,7 +117,7 @@ impl Command {
         // pointer.
         let arg = os2c(arg, &mut self.saw_nul);
         self.argv[self.args.len() + 1] = arg.as_ptr();
-        self.argv.push(0 as *const _);
+        self.argv.push(ptr::null());
 
         // Also make sure we keep track of the owned value to schedule a
         // destructor for this memory.
@@ -134,7 +134,7 @@ impl Command {
                 envp.push(s.as_ptr());
                 map.insert(k, (envp.len() - 1, s));
             }
-            envp.push(0 as *const _);
+            envp.push(ptr::null());
             self.env = Some(map);
             self.envp = Some(envp);
         }
@@ -158,7 +158,7 @@ impl Command {
             Entry::Vacant(e) => {
                 let len = envp.len();
                 envp[len - 1] = new_key.as_ptr();
-                envp.push(0 as *const _);
+                envp.push(ptr::null());
                 e.insert((len - 1, new_key));
             }
         }
@@ -183,7 +183,7 @@ impl Command {
 
     pub fn env_clear(&mut self) {
         self.env = Some(HashMap::new());
-        self.envp = Some(vec![0 as *const _]);
+        self.envp = Some(vec![ptr::null()]);
     }
 
     pub fn cwd(&mut self, dir: &OsStr) {
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 371319a93d2..1061ca87f64 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -12,7 +12,6 @@ use prelude::v1::*;
 
 use alloc::boxed::FnBox;
 use cmp;
-#[cfg(not(any(target_env = "newlib", target_os = "solaris")))]
 use ffi::CStr;
 use io;
 use libc;
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index 68eebba9e7b..a08cec38f73 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 use cmp::Ordering;
-use time::Duration;
 use libc;
+use time::Duration;
 
 pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
 
@@ -164,12 +164,14 @@ mod inner {
 
     impl SystemTime {
         pub fn now() -> SystemTime {
+            use ptr;
+
             let mut s = libc::timeval {
                 tv_sec: 0,
                 tv_usec: 0,
             };
             cvt(unsafe {
-                libc::gettimeofday(&mut s, 0 as *mut _)
+                libc::gettimeofday(&mut s, ptr::null_mut())
             }).unwrap();
             return SystemTime::from(s)
         }
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index 0e10a8d8e8d..82a44c1c110 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -30,9 +30,9 @@ use io;
 use libc::c_void;
 use mem;
 use ptr;
-use sync::StaticMutex;
 use sys::c;
 use sys::dynamic_lib::DynamicLibrary;
+use sys::mutex::Mutex;
 
 macro_rules! sym {
     ($lib:expr, $e:expr, $t:ident) => (
@@ -101,53 +101,59 @@ impl Drop for Cleanup {
 pub fn write(w: &mut Write) -> io::Result<()> {
     // According to windows documentation, all dbghelp functions are
     // single-threaded.
-    static LOCK: StaticMutex = StaticMutex::new();
-    let _g = LOCK.lock();
+    static LOCK: Mutex = Mutex::new();
+    unsafe {
+        LOCK.lock();
+        let res = _write(w);
+        LOCK.unlock();
+        return res
+    }
+}
 
+unsafe fn _write(w: &mut Write) -> io::Result<()> {
     let dbghelp = match DynamicLibrary::open("dbghelp.dll") {
         Ok(lib) => lib,
         Err(..) => return Ok(()),
     };
-    unsafe {
-        // Fetch the symbols necessary from dbghelp.dll
-        let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn);
-        let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn);
-        let StackWalk64 = sym!(dbghelp, "StackWalk64", StackWalk64Fn);
-
-        // Allocate necessary structures for doing the stack walk
-        let process = c::GetCurrentProcess();
-        let thread = c::GetCurrentThread();
-        let mut context: c::CONTEXT = mem::zeroed();
-        c::RtlCaptureContext(&mut context);
-        let mut frame: c::STACKFRAME64 = mem::zeroed();
-        let image = init_frame(&mut frame, &context);
-
-        // Initialize this process's symbols
-        let ret = SymInitialize(process, ptr::null_mut(), c::TRUE);
-        if ret != c::TRUE { return Ok(()) }
-        let _c = Cleanup { handle: process, SymCleanup: SymCleanup };
-
-        // And now that we're done with all the setup, do the stack walking!
-        // Start from -1 to avoid printing this stack frame, which will
-        // always be exactly the same.
-        let mut i = -1;
-        write!(w, "stack backtrace:\n")?;
-        while StackWalk64(image, process, thread, &mut frame, &mut context,
-                          ptr::null_mut(),
-                          ptr::null_mut(),
-                          ptr::null_mut(),
-                          ptr::null_mut()) == c::TRUE {
-            let addr = frame.AddrPC.Offset;
-            if addr == frame.AddrReturn.Offset || addr == 0 ||
-               frame.AddrReturn.Offset == 0 { break }
-
-            i += 1;
-
-            if i >= 0 {
-                printing::print(w, i, addr - 1, process, &dbghelp)?;
-            }
-        }
 
-        Ok(())
+    // Fetch the symbols necessary from dbghelp.dll
+    let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn);
+    let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn);
+    let StackWalk64 = sym!(dbghelp, "StackWalk64", StackWalk64Fn);
+
+    // Allocate necessary structures for doing the stack walk
+    let process = c::GetCurrentProcess();
+    let thread = c::GetCurrentThread();
+    let mut context: c::CONTEXT = mem::zeroed();
+    c::RtlCaptureContext(&mut context);
+    let mut frame: c::STACKFRAME64 = mem::zeroed();
+    let image = init_frame(&mut frame, &context);
+
+    // Initialize this process's symbols
+    let ret = SymInitialize(process, ptr::null_mut(), c::TRUE);
+    if ret != c::TRUE { return Ok(()) }
+    let _c = Cleanup { handle: process, SymCleanup: SymCleanup };
+
+    // And now that we're done with all the setup, do the stack walking!
+    // Start from -1 to avoid printing this stack frame, which will
+    // always be exactly the same.
+    let mut i = -1;
+    write!(w, "stack backtrace:\n")?;
+    while StackWalk64(image, process, thread, &mut frame, &mut context,
+                      ptr::null_mut(),
+                      ptr::null_mut(),
+                      ptr::null_mut(),
+                      ptr::null_mut()) == c::TRUE {
+        let addr = frame.AddrPC.Offset;
+        if addr == frame.AddrReturn.Offset || addr == 0 ||
+           frame.AddrReturn.Offset == 0 { break }
+
+        i += 1;
+
+        if i >= 0 {
+            printing::print(w, i, addr - 1, process, &dbghelp)?;
+        }
     }
+
+    Ok(())
 }
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index c243e890526..2683e57256d 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -38,7 +38,7 @@ pub struct FileAttr {
     reparse_tag: c::DWORD,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub enum FileType {
     Dir, File, SymlinkFile, SymlinkDir, ReparsePoint, MountPoint,
 }
@@ -117,7 +117,7 @@ impl Drop for FindNextFileHandle {
 
 impl DirEntry {
     fn new(root: &Arc<PathBuf>, wfd: &c::WIN32_FIND_DATAW) -> Option<DirEntry> {
-        match ::slice_pat(&&wfd.cFileName[0..3]) {
+        match &wfd.cFileName[0..3] {
             // check for '.' and '..'
             &[46, 0, ..] |
             &[46, 46, 0, ..] => return None,
diff --git a/src/libstd/sys/windows/handle.rs b/src/libstd/sys/windows/handle.rs
index 74546bb893b..d10abae2865 100644
--- a/src/libstd/sys/windows/handle.rs
+++ b/src/libstd/sys/windows/handle.rs
@@ -46,10 +46,10 @@ impl Handle {
 
     pub fn new_event(manual: bool, init: bool) -> io::Result<Handle> {
         unsafe {
-            let event = c::CreateEventW(0 as *mut _,
+            let event = c::CreateEventW(ptr::null_mut(),
                                         manual as c::BOOL,
                                         init as c::BOOL,
-                                        0 as *const _);
+                                        ptr::null());
             if event.is_null() {
                 Err(io::Error::last_os_error())
             } else {
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index 8631a63d653..6e9c67051a6 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -12,9 +12,10 @@ use prelude::v1::*;
 use os::windows::prelude::*;
 
 use ffi::OsStr;
-use path::Path;
 use io;
 use mem;
+use path::Path;
+use ptr;
 use rand::{self, Rng};
 use slice;
 use sys::c;
@@ -66,7 +67,7 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
                                              4096,
                                              4096,
                                              0,
-                                             0 as *mut _);
+                                             ptr::null_mut());
 
             // We pass the FILE_FLAG_FIRST_PIPE_INSTANCE flag above, and we're
             // also just doing a best effort at selecting a unique name. If