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/collections/hash/map.rs8
-rw-r--r--src/libstd/dynamic_lib.rs4
-rw-r--r--src/libstd/env.rs14
-rw-r--r--src/libstd/error.rs16
-rw-r--r--src/libstd/ffi/c_str.rs35
-rw-r--r--src/libstd/ffi/os_str.rs40
-rw-r--r--src/libstd/fs.rs235
-rw-r--r--src/libstd/io/buffered.rs17
-rw-r--r--src/libstd/io/error.rs2
-rw-r--r--src/libstd/io/mod.rs55
-rw-r--r--src/libstd/io/stdio.rs53
-rw-r--r--src/libstd/io/util.rs2
-rw-r--r--src/libstd/lib.rs4
-rw-r--r--src/libstd/net/addr.rs6
-rw-r--r--src/libstd/net/ip.rs1
-rw-r--r--src/libstd/net/tcp.rs23
-rw-r--r--src/libstd/net/udp.rs46
-rw-r--r--src/libstd/num/f32.rs75
-rw-r--r--src/libstd/num/f64.rs4
-rw-r--r--src/libstd/num/mod.rs5
-rw-r--r--src/libstd/os/linux/raw.rs3
-rw-r--r--src/libstd/os/openbsd/raw.rs2
-rw-r--r--src/libstd/os/raw.rs14
-rw-r--r--src/libstd/panic.rs73
-rw-r--r--src/libstd/panicking.rs160
-rw-r--r--src/libstd/path.rs24
-rw-r--r--src/libstd/rand/os.rs31
-rw-r--r--src/libstd/rand/reader.rs2
-rw-r--r--src/libstd/rt.rs16
-rw-r--r--src/libstd/sync/condvar.rs6
-rw-r--r--src/libstd/sync/mpsc/mod.rs4
-rw-r--r--src/libstd/sys/common/io.rs2
-rw-r--r--src/libstd/sys/common/libunwind.rs3
-rw-r--r--src/libstd/sys/common/poison.rs2
-rw-r--r--src/libstd/sys/common/remutex.rs10
-rw-r--r--src/libstd/sys/common/unwind/mod.rs2
-rw-r--r--src/libstd/sys/common/util.rs4
-rw-r--r--src/libstd/sys/common/wtf8.rs2
-rw-r--r--src/libstd/sys/unix/ext/io.rs2
-rw-r--r--src/libstd/sys/unix/fs.rs6
-rw-r--r--src/libstd/sys/unix/mod.rs28
-rw-r--r--src/libstd/sys/unix/process.rs37
-rw-r--r--src/libstd/sys/unix/stack_overflow.rs21
-rw-r--r--src/libstd/sys/windows/mod.rs22
-rw-r--r--src/libstd/thread/mod.rs10
-rw-r--r--src/libstd/thread/scoped_tls.rs41
-rw-r--r--src/libstd/time/duration.rs3
-rw-r--r--src/libstd/time/mod.rs5
48 files changed, 813 insertions, 367 deletions
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 9ab440f289e..e43101b7c9d 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -1346,11 +1346,15 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> {
 pub enum Entry<'a, K: 'a, V: 'a> {
     /// An occupied Entry.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Occupied(OccupiedEntry<'a, K, V>),
+    Occupied(
+        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] OccupiedEntry<'a, K, V>
+    ),
 
     /// A vacant Entry.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Vacant(VacantEntry<'a, K, V>),
+    Vacant(
+        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] VacantEntry<'a, K, V>
+    ),
 }
 
 /// Possible states of a VacantEntry.
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index 62ec23ccb20..41001153c3c 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -16,7 +16,7 @@
             reason = "API has not been scrutinized and is highly likely to \
                       either disappear or change",
             issue = "27810")]
-#![rustc_deprecated(since = "1.5.0", reason = "replaced with crates.io crates")]
+#![rustc_deprecated(since = "1.5.0", reason = "replaced with 'dylib' on crates.io")]
 #![allow(missing_docs)]
 #![allow(deprecated)]
 
@@ -132,6 +132,7 @@ mod tests {
     #[cfg_attr(any(windows,
                    target_os = "android",  // FIXME #10379
                    target_env = "musl"), ignore)]
+    #[allow(deprecated)]
     fn test_loading_cosine() {
         // The math library does not need to be loaded since it is already
         // statically linked in
@@ -164,6 +165,7 @@ mod tests {
               target_os = "bitrig",
               target_os = "netbsd",
               target_os = "openbsd"))]
+    #[allow(deprecated)]
     fn test_errors_do_not_crash() {
         // Open /dev/null as a library to get an error, and make sure
         // that only causes an error, and not a crash.
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index 760733872ea..db136190082 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -218,7 +218,7 @@ pub enum VarError {
     /// valid unicode data. The found data is returned as a payload of this
     /// variant.
     #[stable(feature = "env", since = "1.0.0")]
-    NotUnicode(OsString),
+    NotUnicode(#[cfg_attr(not(stage0), stable(feature = "env", since = "1.0.0"))] OsString),
 }
 
 #[stable(feature = "env", since = "1.0.0")]
@@ -615,6 +615,8 @@ pub mod consts {
     /// - mips
     /// - mipsel
     /// - powerpc
+    /// - powerpc64
+    /// - powerpc64le
     #[stable(feature = "env", since = "1.0.0")]
     pub const ARCH: &'static str = super::arch::ARCH;
 
@@ -867,6 +869,16 @@ mod arch {
     pub const ARCH: &'static str = "powerpc";
 }
 
+#[cfg(target_arch = "powerpc64")]
+mod arch {
+    pub const ARCH: &'static str = "powerpc64";
+}
+
+#[cfg(target_arch = "powerpc64le")]
+mod arch {
+    pub const ARCH: &'static str = "powerpc64le";
+}
+
 #[cfg(target_arch = "le32")]
 mod arch {
     pub const ARCH: &'static str = "le32";
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 46d03169b2d..c44a4bfe0f1 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -119,6 +119,15 @@ impl From<String> for Box<Error + Send + Sync> {
     }
 }
 
+#[stable(feature = "string_box_error", since = "1.7.0")]
+impl From<String> for Box<Error> {
+    fn from(str_err: String) -> Box<Error> {
+        let err1: Box<Error + Send + Sync> = From::from(str_err);
+        let err2: Box<Error> = err1;
+        err2
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> {
     fn from(err: &'b str) -> Box<Error + Send + Sync + 'a> {
@@ -126,6 +135,13 @@ impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> {
     }
 }
 
+#[stable(feature = "string_box_error", since = "1.7.0")]
+impl<'a> From<&'a str> for Box<Error> {
+    fn from(err: &'a str) -> Box<Error> {
+        From::from(String::from(err))
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Error for str::ParseBoolError {
     fn description(&self) -> &str { "failed to parse bool" }
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 3f3913471b8..9a41272299e 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -20,7 +20,7 @@ use iter::Iterator;
 use libc;
 use mem;
 use memchr;
-use ops::Deref;
+use ops;
 use option::Option::{self, Some, None};
 use os::raw::c_char;
 use result::Result::{self, Ok, Err};
@@ -282,7 +282,7 @@ impl CString {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Deref for CString {
+impl ops::Deref for CString {
     type Target = CStr;
 
     fn deref(&self) -> &CStr {
@@ -522,6 +522,37 @@ impl ToOwned for CStr {
     }
 }
 
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl<'a> From<&'a CStr> for CString {
+    fn from(s: &'a CStr) -> CString {
+        s.to_owned()
+    }
+}
+
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl ops::Index<ops::RangeFull> for CString {
+    type Output = CStr;
+
+    #[inline]
+    fn index(&self, _index: ops::RangeFull) -> &CStr {
+        self
+    }
+}
+
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl AsRef<CStr> for CStr {
+    fn as_ref(&self) -> &CStr {
+        self
+    }
+}
+
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl AsRef<CStr> for CString {
+    fn as_ref(&self) -> &CStr {
+        self
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 90b108e6770..eb5ddecbd05 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -8,27 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! A type that can represent all platform-native strings, but is cheaply
-//! interconvertable with Rust strings.
-//!
-//! The need for this type arises from the fact that:
-//!
-//! * On Unix systems, strings are often arbitrary sequences of non-zero
-//!   bytes, in many cases interpreted as UTF-8.
-//!
-//! * On Windows, strings are often arbitrary sequences of non-zero 16-bit
-//!   values, interpreted as UTF-16 when it is valid to do so.
-//!
-//! * In Rust, strings are always valid UTF-8, but may contain zeros.
-//!
-//! The types in this module bridge this gap by simultaneously representing Rust
-//! and platform-native string values, and in particular allowing a Rust string
-//! to be converted into an "OS" string with no cost.
-//!
-//! **Note**: At the moment, these types are extremely bare-bones, usable only
-//! for conversion to/from various other string types. Eventually these types
-//! will offer a full-fledged string API.
-
 use borrow::{Borrow, Cow, ToOwned};
 use ffi::CString;
 use fmt::{self, Debug};
@@ -42,14 +21,29 @@ use vec::Vec;
 use sys::os_str::{Buf, Slice};
 use sys_common::{AsInner, IntoInner, FromInner};
 
-/// Owned, mutable OS strings.
+/// A type that can represent owned, mutable platform-native strings, but is
+/// cheaply interconvertable with Rust strings.
+///
+/// The need for this type arises from the fact that:
+///
+/// * On Unix systems, strings are often arbitrary sequences of non-zero
+///   bytes, in many cases interpreted as UTF-8.
+///
+/// * On Windows, strings are often arbitrary sequences of non-zero 16-bit
+///   values, interpreted as UTF-16 when it is valid to do so.
+///
+/// * In Rust, strings are always valid UTF-8, but may contain zeros.
+///
+/// `OsString` and `OsStr` bridge this gap by simultaneously representing Rust
+/// and platform-native string values, and in particular allowing a Rust string
+/// to be converted into an "OS" string with no cost.
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct OsString {
     inner: Buf
 }
 
-/// Slices into OS strings.
+/// Slices into OS strings (see `OsString`).
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct OsStr {
     inner: Slice
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 715749f50d4..635ed91f35d 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -715,7 +715,7 @@ impl DirEntry {
     /// This function will not traverse symlinks if this entry points at a
     /// symlink.
     ///
-    /// # Platform behavior
+    /// # Platform-specific behavior
     ///
     /// On Windows this function is cheap to call (no extra system calls
     /// needed), but on Unix platforms this function is the equivalent of
@@ -730,7 +730,7 @@ impl DirEntry {
     /// This function will not traverse symlinks if this entry points at a
     /// symlink.
     ///
-    /// # Platform behavior
+    /// # Platform-specific behavior
     ///
     /// On Windows and most Unix platforms this function is free (no extra
     /// system calls needed), but some Unix platforms may require the equivalent
@@ -758,11 +758,20 @@ impl AsInner<fs_imp::DirEntry> for DirEntry {
 /// guarantee that the file is immediately deleted (e.g. depending on
 /// platform, other open file descriptors may prevent immediate removal).
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `unlink` function on Unix
+/// and the `DeleteFile` function on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
 /// # Errors
 ///
-/// This function will return an error if `path` points to a directory, if the
-/// user lacks permissions to remove the file, or if some other filesystem-level
-/// error occurs.
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * `path` points to a directory.
+/// * The user lacks permissions to remove the file.
 ///
 /// # Examples
 ///
@@ -785,6 +794,21 @@ pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// This function will traverse symbolic links to query information about the
 /// destination file.
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `stat` function on Unix
+/// and the `GetFileAttributesEx` function on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
+/// # Errors
+///
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * The user lacks permissions to perform `metadata` call on `path`.
+/// * `path` does not exist.
+///
 /// # Examples
 ///
 /// ```rust
@@ -796,12 +820,6 @@ pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// # Ok(())
 /// # }
 /// ```
-///
-/// # Errors
-///
-/// This function will return an error if the user lacks the requisite
-/// permissions to perform a `metadata` call on the given `path` or if there
-/// is no entry in the filesystem at the provided path.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
     fs_imp::stat(path.as_ref()).map(Metadata)
@@ -809,6 +827,21 @@ pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
 
 /// Query the metadata about a file without following symlinks.
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `lstat` function on Unix
+/// and the `GetFileAttributesEx` function on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
+/// # Errors
+///
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * The user lacks permissions to perform `metadata` call on `path`.
+/// * `path` does not exist.
+///
 /// # Examples
 ///
 /// ```rust
@@ -829,12 +862,21 @@ pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
 ///
 /// This will not work if the new name is on a different mount point.
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `rename` function on Unix
+/// and the `MoveFileEx` function with the `MOVEFILE_REPLACE_EXISTING` flag on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
 /// # Errors
 ///
-/// This function will return an error if the provided `from` doesn't exist, if
-/// the process lacks permissions to view the contents, if `from` and `to`
-/// reside on separate filesystems, or if some other intermittent I/O error
-/// occurs.
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * `from` does not exist.
+/// * The user lacks permissions to view contents.
+/// * `from` and `to` are on separate filesystems.
 ///
 /// # Examples
 ///
@@ -842,7 +884,7 @@ pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
 /// use std::fs;
 ///
 /// # fn foo() -> std::io::Result<()> {
-/// try!(fs::rename("a.txt", "b.txt"));
+/// try!(fs::rename("a.txt", "b.txt")); // Rename a.txt to b.txt
 /// # Ok(())
 /// # }
 /// ```
@@ -861,15 +903,24 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
 ///
 /// On success, the total number of bytes copied is returned.
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `open` function in Unix
+/// with `O_RDONLY` for `from` and `O_WRONLY`, `O_CREAT`, and `O_TRUNC` for `to`.
+/// `O_CLOEXEC` is set for returned file descriptors.
+/// On Windows, this function currently corresponds to `CopyFileEx`.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
 /// # Errors
 ///
 /// This function will return an error in the following situations, but is not
 /// limited to just these cases:
 ///
-/// * The `from` path is not a file
-/// * The `from` file does not exist
+/// * The `from` path is not a file.
+/// * The `from` file does not exist.
 /// * The current process does not have the permission rights to access
-///   `from` or write `to`
+///   `from` or write `to`.
 ///
 /// # Examples
 ///
@@ -877,7 +928,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
 /// use std::fs;
 ///
 /// # fn foo() -> std::io::Result<()> {
-/// try!(fs::copy("foo.txt", "bar.txt"));
+/// try!(fs::copy("foo.txt", "bar.txt"));  // Copy foo.txt to bar.txt
 /// # Ok(()) }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -890,13 +941,27 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
 /// The `dst` path will be a link pointing to the `src` path. Note that systems
 /// often require these two paths to both be located on the same filesystem.
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `link` function on Unix
+/// and the `CreateHardLink` function on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
+/// # Errors
+///
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * The `src` path is not a file or doesn't exist.
+///
 /// # Examples
 ///
 /// ```
 /// use std::fs;
 ///
 /// # fn foo() -> std::io::Result<()> {
-/// try!(fs::hard_link("a.txt", "b.txt"));
+/// try!(fs::hard_link("a.txt", "b.txt")); // Hard link a.txt to b.txt
 /// # Ok(())
 /// # }
 /// ```
@@ -933,11 +998,21 @@ pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<(
 
 /// Reads a symbolic link, returning the file that the link points to.
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `readlink` function on Unix
+/// and the `CreateFile` function with `FILE_FLAG_OPEN_REPARSE_POINT` and
+/// `FILE_FLAG_BACKUP_SEMANTICS` flags on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
 /// # Errors
 ///
-/// This function will return an error on failure. Failure conditions include
-/// reading a file that does not exist or reading a file that is not a symbolic
-/// link.
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * `path` is not a symbolic link.
+/// * `path` does not exist.
 ///
 /// # Examples
 ///
@@ -957,8 +1032,20 @@ pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
 /// Returns the canonical form of a path with all intermediate components
 /// normalized and symbolic links resolved.
 ///
-/// This function may return an error in situations like where the path does not
-/// exist, a component in the path is not a directory, or an I/O error happens.
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `realpath` function on Unix
+/// and the `CreateFile` and `GetFinalPathNameByHandle` functions on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
+/// # Errors
+///
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * `path` does not exist.
+/// * A component in path is not a directory.
 ///
 /// # Examples
 ///
@@ -977,10 +1064,20 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
 
 /// Creates a new, empty directory at the provided path
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `mkdir` function on Unix
+/// and the `CreateDirectory` function on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
 /// # Errors
 ///
-/// This function will return an error if the user lacks permissions to make a
-/// new directory at the provided `path`, or if the directory already exists.
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * User lacks permissions to create directory at `path`.
+/// * `path` already exists.
 ///
 /// # Examples
 ///
@@ -1000,9 +1097,19 @@ pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// Recursively create a directory and all of its parent components if they
 /// are missing.
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `mkdir` function on Unix
+/// and the `CreateDirectory` function on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
 /// # Errors
 ///
-/// This function will fail if any directory in the path specified by `path`
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * If any directory in the path specified by `path`
 /// does not already exist and it could not be created otherwise. The specific
 /// error conditions for when a directory is being created (after it is
 /// determined to not exist) are outlined by `fs::create_dir`.
@@ -1024,10 +1131,20 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 
 /// Removes an existing, empty directory.
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `rmdir` function on Unix
+/// and the `RemoveDirectory` function on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
 /// # Errors
 ///
-/// This function will return an error if the user lacks permissions to remove
-/// the directory at the provided `path`, or if the directory isn't empty.
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * The user lacks permissions to remove the directory at the provided `path`.
+/// * The directory isn't empty.
 ///
 /// # Examples
 ///
@@ -1050,6 +1167,14 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// This function does **not** follow symbolic links and it will simply remove the
 /// symbolic link itself.
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to `opendir`, `lstat`, `rm` and `rmdir` functions on Unix
+/// and the `FindFirstFile`, `GetFileAttributesEx`, `DeleteFile`, and `RemoveDirectory` functions
+/// on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
 /// # Errors
 ///
 /// See `file::remove_file` and `fs::remove_dir`.
@@ -1087,6 +1212,22 @@ fn _remove_dir_all(path: &Path) -> io::Result<()> {
 /// The iterator will yield instances of `io::Result<DirEntry>`. New errors may
 /// be encountered after an iterator is initially constructed.
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `opendir` function on Unix
+/// and the `FindFirstFile` function on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
+/// # Errors
+///
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * The provided `path` doesn't exist.
+/// * The process lacks permissions to view the contents.
+/// * The `path` points at a non-directory file.
+///
 /// # Examples
 ///
 /// ```
@@ -1109,12 +1250,6 @@ fn _remove_dir_all(path: &Path) -> io::Result<()> {
 ///     Ok(())
 /// }
 /// ```
-///
-/// # Errors
-///
-/// This function will return an error if the provided `path` doesn't exist, if
-/// the process lacks permissions to view the contents or if the `path` points
-/// at a non-directory file
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
     fs_imp::readdir(path.as_ref()).map(ReadDir)
@@ -1180,6 +1315,21 @@ impl Iterator for WalkDir {
 
 /// Changes the permissions found on a file or a directory.
 ///
+/// # Platform-specific behavior
+///
+/// This function currently corresponds to the `chmod` function on Unix
+/// and the `SetFileAttributes` function on Windows.
+/// Note that, this [may change in the future][changes].
+/// [changes]: ../io/index.html#platform-specific-behavior
+///
+/// # Errors
+///
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * `path` does not exist.
+/// * The user lacks the permission to change attributes of the file.
+///
 /// # Examples
 ///
 /// ```
@@ -1192,12 +1342,6 @@ impl Iterator for WalkDir {
 /// # Ok(())
 /// # }
 /// ```
-///
-/// # Errors
-///
-/// This function will return an error if the provided `path` doesn't exist, if
-/// the process lacks permissions to change the attributes of the file, or if
-/// some other I/O error is encountered.
 #[stable(feature = "set_permissions", since = "1.1.0")]
 pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions)
                                        -> io::Result<()> {
@@ -1281,7 +1425,6 @@ mod tests {
     use io::{ErrorKind, SeekFrom};
     use path::PathBuf;
     use path::Path as Path2;
-    use os;
     use rand::{self, StdRng, Rng};
     use str;
 
@@ -1410,8 +1553,8 @@ mod tests {
         let message = "ten-four";
         let mut read_mem = [0; 4];
         let set_cursor = 4 as u64;
-        let mut tell_pos_pre_read;
-        let mut tell_pos_post_read;
+        let tell_pos_pre_read;
+        let tell_pos_post_read;
         let tmpdir = tmpdir();
         let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt");
         {
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 79eedbeda2c..a9a79fe2c77 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -772,26 +772,11 @@ impl<W: Write> fmt::Debug for LineWriter<W> where W: fmt::Debug {
     }
 }
 
-struct InternalBufWriter<W: Write>(BufWriter<W>);
-
-impl<W: Read + Write> InternalBufWriter<W> {
-    fn get_mut(&mut self) -> &mut BufWriter<W> {
-        let InternalBufWriter(ref mut w) = *self;
-        return w;
-    }
-}
-
-impl<W: Read + Write> Read for InternalBufWriter<W> {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        self.get_mut().inner.as_mut().unwrap().read(buf)
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
     use io::prelude::*;
-    use io::{self, BufReader, BufWriter, Cursor, LineWriter, SeekFrom};
+    use io::{self, BufReader, BufWriter, LineWriter, SeekFrom};
     use test;
 
     /// A dummy reader intended at testing short-reads propagation.
diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index 1dd96f5ddfc..e3f17c839f1 100644
--- a/src/libstd/io/error.rs
+++ b/src/libstd/io/error.rs
@@ -377,7 +377,7 @@ mod test {
         struct TestError;
 
         impl fmt::Display for TestError {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+            fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
                 Ok(())
             }
         }
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index cc3f8097a88..abb47b69418 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -112,7 +112,7 @@
 //! ```
 //!
 //! `BufWriter` doesn't add any new ways of writing; it just buffers every call
-//! to [`write()`][write]:
+//! to [`write()`][write()]:
 //!
 //! ```
 //! use std::io;
@@ -134,7 +134,7 @@
 //! # }
 //! ```
 //!
-//! [write]: trait.Write.html#tymethod.write
+//! [write()]: trait.Write.html#tymethod.write
 //!
 //! ## Standard input and output
 //!
@@ -237,7 +237,16 @@
 //! to read the line and print it, so we use `()`.
 //!
 //! [result]: type.Result.html
-//! [try]: macro.try!.html
+//! [try]: ../macro.try!.html
+//!
+//! ## Platform-specific behavior
+//!
+//! Many I/O functions throughout the standard library are documented to indicate
+//! what various library or syscalls they are delegated to. This is done to help
+//! applications both understand what's happening under the hood as well as investigate
+//! any possibly unclear semantics. Note, however, that this is informative, not a binding
+//! contract. The implementation of many of these functions are subject to change over
+//! time and may call fewer or more syscalls/library functions.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -390,7 +399,7 @@ fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize>
 ///
 /// [`File`][file]s implement `Read`:
 ///
-/// [file]: ../std/fs/struct.File.html
+/// [file]: ../fs/struct.File.html
 ///
 /// ```
 /// use std::io;
@@ -450,7 +459,7 @@ pub trait Read {
     ///
     /// [`File`][file]s implement `Read`:
     ///
-    /// [file]: ../std/fs/struct.File.html
+    /// [file]: ../fs/struct.File.html
     ///
     /// ```
     /// use std::io;
@@ -492,7 +501,7 @@ pub trait Read {
     ///
     /// [`File`][file]s implement `Read`:
     ///
-    /// [file]: ../std/fs/struct.File.html
+    /// [file]: ../fs/struct.File.html
     ///
     /// ```
     /// use std::io;
@@ -531,7 +540,7 @@ pub trait Read {
     ///
     /// [`File`][file]s implement `Read`:
     ///
-    /// [file]: ../std/fs/struct.File.html
+    /// [file]: ../fs/struct.File.html
     ///
     /// ```
     /// use std::io;
@@ -591,7 +600,7 @@ pub trait Read {
     ///
     /// [`File`][file]s implement `Read`:
     ///
-    /// [file]: ../std/fs/struct.File.html
+    /// [file]: ../fs/struct.File.html
     ///
     /// ```
     /// use std::io;
@@ -634,7 +643,7 @@ pub trait Read {
     ///
     /// [`File`][file]s implement `Read`:
     ///
-    /// [file]: ../std/fs/struct.File.html
+    /// [file]: ../fs/struct.File.html
     ///
     /// ```
     /// use std::io;
@@ -673,7 +682,7 @@ pub trait Read {
     ///
     /// [`File`][file]s implement `Read`:
     ///
-    /// [file]: ../std/fs/struct.File.html
+    /// [file]: ../fs/struct.File.html
     ///
     /// ```
     /// use std::io;
@@ -709,7 +718,7 @@ pub trait Read {
     ///
     /// [`File`][file]s implement `Read`:
     ///
-    /// [file]: ../std/fs/struct.File.html
+    /// [file]: ../fs/struct.File.html
     ///
     /// ```
     /// #![feature(io)]
@@ -744,7 +753,7 @@ pub trait Read {
     ///
     /// [`File`][file]s implement `Read`:
     ///
-    /// [file]: ../std/fs/struct.File.html
+    /// [file]: ../fs/struct.File.html
     ///
     /// ```
     /// use std::io;
@@ -780,7 +789,7 @@ pub trait Read {
     ///
     /// [`File`][file]s implement `Read`:
     ///
-    /// [file]: ../std/fs/struct.File.html
+    /// [file]: ../fs/struct.File.html
     ///
     /// ```
     /// use std::io;
@@ -814,7 +823,7 @@ pub trait Read {
     ///
     /// [`File`][file]s implement `Read`:
     ///
-    /// [file]: ../std/fs/struct.File.html
+    /// [file]: ../fs/struct.File.html
     ///
     /// ```
     /// #![feature(io)]
@@ -992,8 +1001,8 @@ pub trait Write {
     /// explicitly be called. The [`write!`][write] macro should be favored to
     /// invoke this method instead.
     ///
-    /// [formatargs]: ../std/macro.format_args!.html
-    /// [write]: ../std/macro.write!.html
+    /// [formatargs]: ../macro.format_args!.html
+    /// [write]: ../macro.write!.html
     ///
     /// This function internally uses the [`write_all`][writeall] method on
     /// this trait and hence will continuously write data so long as no errors
@@ -1126,7 +1135,7 @@ pub trait Write {
 ///
 /// [`File`][file]s implement `Seek`:
 ///
-/// [file]: ../std/fs/struct.File.html
+/// [file]: ../fs/struct.File.html
 ///
 /// ```
 /// use std::io;
@@ -1166,23 +1175,23 @@ pub trait Seek {
 pub enum SeekFrom {
     /// Set the offset to the provided number of bytes.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Start(u64),
+    Start(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] u64),
 
     /// Set the offset to the size of this object plus the specified number of
     /// bytes.
     ///
-    /// It is possible to seek beyond the end of an object, but is an error to
+    /// It is possible to seek beyond the end of an object, but it's an error to
     /// seek before byte 0.
     #[stable(feature = "rust1", since = "1.0.0")]
-    End(i64),
+    End(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] i64),
 
     /// Set the offset to the current position plus the specified number of
     /// bytes.
     ///
-    /// It is possible to seek beyond the end of an object, but is an error to
+    /// It is possible to seek beyond the end of an object, but it's an error to
     /// seek before byte 0.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Current(i64),
+    Current(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] i64),
 }
 
 fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
@@ -1983,7 +1992,7 @@ mod tests {
         b.iter(|| {
             let mut lr = repeat(1).take(10000000);
             let mut vec = Vec::with_capacity(1024);
-            super::read_to_end(&mut lr, &mut vec);
+            super::read_to_end(&mut lr, &mut vec)
         });
     }
 }
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 985dbdd895f..79091fd3d6b 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -133,14 +133,17 @@ fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
 /// A handle to the standard input stream of a process.
 ///
 /// Each handle is a shared reference to a global buffer of input data to this
-/// process. A handle can be `lock`'d to gain full access to `BufRead` methods
+/// process. A handle can be `lock`'d to gain full access to [`BufRead`] methods
 /// (e.g. `.lines()`). Writes to this handle are otherwise locked with respect
 /// to other writes.
 ///
 /// This handle implements the `Read` trait, but beware that concurrent reads
 /// of `Stdin` must be executed with care.
 ///
-/// Created by the function `io::stdin()`.
+/// Created by the [`io::stdin`] method.
+///
+/// [`io::stdin`]: fn.stdin.html
+/// [`BufRead`]: trait.BufRead.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdin {
     inner: Arc<Mutex<BufReader<Maybe<StdinRaw>>>>,
@@ -148,8 +151,12 @@ pub struct Stdin {
 
 /// A locked reference to the `Stdin` handle.
 ///
-/// This handle implements both the `Read` and `BufRead` traits and is
-/// constructed via the `lock` method on `Stdin`.
+/// This handle implements both the [`Read`] and [`BufRead`] traits, and
+/// is constructed via the [`Stdin::lock`] method.
+///
+/// [`Read`]: trait.Read.html
+/// [`BufRead`]: trait.BufRead.html
+/// [`Stdin::lock`]: struct.Stdin.html#method.lock
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdinLock<'a> {
     inner: MutexGuard<'a, BufReader<Maybe<StdinRaw>>>,
@@ -159,7 +166,7 @@ pub struct StdinLock<'a> {
 ///
 /// Each handle returned is a reference to a shared global buffer whose access
 /// is synchronized via a mutex. If you need more explicit control over
-/// locking, see the [lock() method][lock].
+/// locking, see the [`lock() method`][lock].
 ///
 /// [lock]: struct.Stdin.html#method.lock
 ///
@@ -221,8 +228,11 @@ impl Stdin {
     /// guard.
     ///
     /// The lock is released when the returned lock goes out of scope. The
-    /// returned guard also implements the `Read` and `BufRead` traits for
+    /// returned guard also implements the [`Read`] and [`BufRead`] traits for
     /// accessing the underlying data.
+    ///
+    /// [`Read`]: trait.Read.html
+    /// [`BufRead`]: trait.BufRead.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdinLock {
         StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
@@ -231,7 +241,9 @@ impl Stdin {
     /// Locks this handle and reads a line of input into the specified buffer.
     ///
     /// For detailed semantics of this method, see the documentation on
-    /// `BufRead::read_line`.
+    /// [`BufRead::read_line`].
+    ///
+    /// [`BufRead::read_line`]: trait.BufRead.html#method.read_line
     ///
     /// # Examples
     ///
@@ -252,7 +264,7 @@ impl Stdin {
     ///
     /// - Pipe some text to it, e.g. `printf foo | path/to/executable`
     /// - Give it text interactively by running the executable directly,
-    //    in which case it will wait for the Enter key to be pressed before
+    ///   in which case it will wait for the Enter key to be pressed before
     ///   continuing
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn read_line(&self, buf: &mut String) -> io::Result<usize> {
@@ -314,7 +326,9 @@ const OUT_MAX: usize = ::usize::MAX;
 /// output stream. Access is also synchronized via a lock and explicit control
 /// over locking is available via the `lock` method.
 ///
-/// Created by the function `io::stdout()`.
+/// Created by the [`io::stdout`] method.
+///
+/// [`io::stdout`]: fn.stdout.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdout {
     // FIXME: this should be LineWriter or BufWriter depending on the state of
@@ -325,8 +339,11 @@ pub struct Stdout {
 
 /// A locked reference to the `Stdout` handle.
 ///
-/// This handle implements the `Write` trait and is constructed via the `lock`
-/// method on `Stdout`.
+/// This handle implements the [`Write`] trait, and is constructed via
+/// the [`Stdout::lock`] method.
+///
+/// [`Write`]: trait.Write.html
+/// [`Stdout::lock`]: struct.Stdout.html#method.lock
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdoutLock<'a> {
     inner: ReentrantMutexGuard<'a, RefCell<LineWriter<Maybe<StdoutRaw>>>>,
@@ -336,9 +353,9 @@ pub struct StdoutLock<'a> {
 ///
 /// Each handle returned is a reference to a shared global buffer whose access
 /// is synchronized via a mutex. If you need more explicit control over
-/// locking, see the [lock() method][lock].
+/// locking, see the [Stdout::lock] method.
 ///
-/// [lock]: struct.Stdout.html#method.lock
+/// [Stdout::lock]: struct.Stdout.html#method.lock
 ///
 /// # Examples
 ///
@@ -424,7 +441,9 @@ impl<'a> Write for StdoutLock<'a> {
 
 /// A handle to the standard error stream of a process.
 ///
-/// For more information, see `stderr`
+/// For more information, see the [`io::stderr`] method.
+///
+/// [`io::stderr`]: fn.stderr.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stderr {
     inner: Arc<ReentrantMutex<RefCell<Maybe<StderrRaw>>>>,
@@ -432,8 +451,10 @@ pub struct Stderr {
 
 /// A locked reference to the `Stderr` handle.
 ///
-/// This handle implements the `Write` trait and is constructed via the `lock`
-/// method on `Stderr`.
+/// This handle implements the `Write` trait and is constructed via
+/// the [`Stderr::lock`] method.
+///
+/// [`Stderr::lock`]: struct.Stderr.html#method.lock
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StderrLock<'a> {
     inner: ReentrantMutexGuard<'a, RefCell<Maybe<StderrRaw>>>,
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index 07a9548224a..e05a0d577ff 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -199,6 +199,7 @@ mod tests {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn tee() {
         let mut buf = [0; 10];
         {
@@ -209,6 +210,7 @@ mod tests {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn broadcast() {
         let mut buf1 = [0; 10];
         let mut buf2 = [0; 10];
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index e66cc49290a..824acda522f 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -76,7 +76,7 @@
 //! `i32`](primitive.i32.html) that lists all the methods that can be called on
 //! 32-bit integers (very useful), and there is a [page for the module
 //! `std::i32`](i32/index.html) that documents the constant values [`MIN`] and
-//! [`MAX`] (rarely useful).
+//! [`MAX`](i32/constant.MAX.html) (rarely useful).
 //!
 //! Note the documentation for the primitives [`str`] and [`[T]`][slice] (also
 //! called 'slice'). Many method calls on [`String`] and [`Vec<T>`] are actually
@@ -153,7 +153,6 @@
 //!
 //! [I/O]: io/index.html
 //! [`MIN`]: i32/constant.MIN.html
-//! [`MAX`]: i32/constant.MAX.html
 //! [TCP]: net/struct.TcpStream.html
 //! [The Rust Prelude]: prelude/index.html
 //! [UDP]: net/struct.UdpSocket.html
@@ -255,6 +254,7 @@
 #![feature(slice_concat_ext)]
 #![feature(slice_patterns)]
 #![feature(staged_api)]
+#![feature(stmt_expr_attributes)]
 #![feature(str_char)]
 #![feature(str_internals)]
 #![feature(str_utf16)]
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index 9c4e2b1a54c..7ae389615ac 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -32,10 +32,10 @@ use vec;
 pub enum SocketAddr {
     /// An IPv4 socket address which is a (ip, port) combination.
     #[stable(feature = "rust1", since = "1.0.0")]
-    V4(SocketAddrV4),
+    V4(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] SocketAddrV4),
     /// An IPv6 socket address
     #[stable(feature = "rust1", since = "1.0.0")]
-    V6(SocketAddrV6),
+    V6(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] SocketAddrV6),
 }
 
 /// An IPv4 socket address which is a (ip, port) combination.
@@ -468,9 +468,7 @@ impl<'a, T: ToSocketAddrs + ?Sized> ToSocketAddrs for &'a T {
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
-    use io;
     use net::*;
-    use net::Ipv6MulticastScope::*;
     use net::test::{tsa, sa6, sa4};
 
     #[test]
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index 00be17f7383..808cf5cc031 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -527,7 +527,6 @@ impl FromInner<c::in6_addr> for Ipv6Addr {
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
-    use io;
     use net::*;
     use net::Ipv6MulticastScope::*;
     use net::test::{tsa, sa6, sa4};
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index f54d4f80480..f9c38c38458 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -319,7 +319,7 @@ mod tests {
     use net::test::{next_test_ip4, next_test_ip6};
     use sync::mpsc::channel;
     use sys_common::AsInner;
-    use time::Duration;
+    use time::{Instant, Duration};
     use thread;
 
     fn each_ip(f: &mut FnMut(SocketAddr)) {
@@ -929,6 +929,7 @@ mod tests {
 
         t!(stream.set_write_timeout(None));
         assert_eq!(None, t!(stream.write_timeout()));
+        drop(listener);
     }
 
     #[test]
@@ -940,11 +941,11 @@ mod tests {
         t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
 
         let mut buf = [0; 10];
-        let wait = Duration::span(|| {
-            let kind = stream.read(&mut buf).err().expect("expected error").kind();
-            assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
-        });
-        assert!(wait > Duration::from_millis(400));
+        let start = Instant::now();
+        let kind = stream.read(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        assert!(start.elapsed() > Duration::from_millis(400));
+        drop(listener);
     }
 
     #[test]
@@ -962,10 +963,10 @@ mod tests {
         t!(stream.read(&mut buf));
         assert_eq!(b"hello world", &buf[..]);
 
-        let wait = Duration::span(|| {
-            let kind = stream.read(&mut buf).err().expect("expected error").kind();
-            assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
-        });
-        assert!(wait > Duration::from_millis(400));
+        let start = Instant::now();
+        let kind = stream.read(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        assert!(start.elapsed() > Duration::from_millis(400));
+        drop(listener);
     }
 }
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index b212d4d32aa..29ac991a547 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -27,18 +27,19 @@ use time::Duration;
 /// use std::net::UdpSocket;
 ///
 /// # fn foo() -> std::io::Result<()> {
-/// let mut socket = try!(UdpSocket::bind("127.0.0.1:34254"));
+/// {
+///     let mut socket = try!(UdpSocket::bind("127.0.0.1:34254"));
 ///
-/// let mut buf = [0; 10];
-/// let (amt, src) = try!(socket.recv_from(&mut buf));
+///     // read from the socket
+///     let mut buf = [0; 10];
+///     let (amt, src) = try!(socket.recv_from(&mut buf));
 ///
-/// // Send a reply to the socket we received data from
-/// let buf = &mut buf[..amt];
-/// buf.reverse();
-/// try!(socket.send_to(buf, &src));
-///
-/// drop(socket); // close the socket
-/// # Ok(())
+///     // send a reply to the socket we received data from
+///     let buf = &mut buf[..amt];
+///     buf.reverse();
+///     try!(socket.send_to(buf, &src));
+///     # Ok(())
+/// } // the socket is closed here
 /// # }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -169,7 +170,7 @@ mod tests {
     use net::test::{next_test_ip4, next_test_ip6};
     use sync::mpsc::channel;
     use sys_common::AsInner;
-    use time::Duration;
+    use time::{Instant, Duration};
     use thread;
 
     fn each_ip(f: &mut FnMut(SocketAddr, SocketAddr)) {
@@ -370,22 +371,22 @@ mod tests {
     fn test_read_timeout() {
         let addr = next_test_ip4();
 
-        let mut stream = t!(UdpSocket::bind(&addr));
+        let stream = t!(UdpSocket::bind(&addr));
         t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
 
         let mut buf = [0; 10];
-        let wait = Duration::span(|| {
-            let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
-            assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
-        });
-        assert!(wait > Duration::from_millis(400));
+
+        let start = Instant::now();
+        let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        assert!(start.elapsed() > Duration::from_millis(400));
     }
 
     #[test]
     fn test_read_with_timeout() {
         let addr = next_test_ip4();
 
-        let mut stream = t!(UdpSocket::bind(&addr));
+        let stream = t!(UdpSocket::bind(&addr));
         t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
 
         t!(stream.send_to(b"hello world", &addr));
@@ -394,10 +395,9 @@ mod tests {
         t!(stream.recv_from(&mut buf));
         assert_eq!(b"hello world", &buf[..]);
 
-        let wait = Duration::span(|| {
-            let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
-            assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
-        });
-        assert!(wait > Duration::from_millis(400));
+        let start = Instant::now();
+        let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        assert!(start.elapsed() > Duration::from_millis(400));
     }
 }
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index 30bee80fbf6..7f57d6dc650 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -15,11 +15,16 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
+#[cfg(not(test))]
 use core::num;
+#[cfg(not(test))]
 use intrinsics;
+#[cfg(not(test))]
 use libc::c_int;
+#[cfg(not(test))]
 use num::FpCategory;
 
+
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON};
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -57,7 +62,7 @@ mod cmath {
         pub fn hypotf(x: c_float, y: c_float) -> c_float;
     }
 
-    // See the comments in `core::float::Float::floor` for why MSVC is special
+    // See the comments in the `floor` function for why MSVC is special
     // here.
     #[cfg(not(target_env = "msvc"))]
     extern {
@@ -79,44 +84,54 @@ mod cmath {
     mod shims {
         use libc::{c_float, c_int};
 
+        #[inline]
         pub unsafe fn acosf(n: c_float) -> c_float {
             f64::acos(n as f64) as c_float
         }
 
+        #[inline]
         pub unsafe fn asinf(n: c_float) -> c_float {
             f64::asin(n as f64) as c_float
         }
 
+        #[inline]
         pub unsafe fn atan2f(n: c_float, b: c_float) -> c_float {
             f64::atan2(n as f64, b as f64) as c_float
         }
 
+        #[inline]
         pub unsafe fn atanf(n: c_float) -> c_float {
             f64::atan(n as f64) as c_float
         }
 
+        #[inline]
         pub unsafe fn coshf(n: c_float) -> c_float {
             f64::cosh(n as f64) as c_float
         }
 
+        #[inline]
         pub unsafe fn frexpf(x: c_float, value: &mut c_int) -> c_float {
             let (a, b) = f64::frexp(x as f64);
             *value = b as c_int;
             a as c_float
         }
 
+        #[inline]
         pub unsafe fn ldexpf(x: c_float, n: c_int) -> c_float {
             f64::ldexp(x as f64, n as isize) as c_float
         }
 
+        #[inline]
         pub unsafe fn sinhf(n: c_float) -> c_float {
             f64::sinh(n as f64) as c_float
         }
 
+        #[inline]
         pub unsafe fn tanf(n: c_float) -> c_float {
             f64::tan(n as f64) as c_float
         }
 
+        #[inline]
         pub unsafe fn tanhf(n: c_float) -> c_float {
             f64::tanh(n as f64) as c_float
         }
@@ -267,8 +282,6 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn floor(self) -> f32 {
-        return floorf(self);
-
         // On MSVC LLVM will lower many math intrinsics to a call to the
         // corresponding function. On MSVC, however, many of these functions
         // aren't actually available as symbols to call, but rather they are all
@@ -283,9 +296,9 @@ impl f32 {
         // redirect to this comment, so `floorf` is just one case of a missing
         // function on MSVC, but there are many others elsewhere.
         #[cfg(target_env = "msvc")]
-        fn floorf(f: f32) -> f32 { (f as f64).floor() as f32 }
+        return (self as f64).floor() as f32;
         #[cfg(not(target_env = "msvc"))]
-        fn floorf(f: f32) -> f32 { unsafe { intrinsics::floorf32(f) } }
+        return unsafe { intrinsics::floorf32(self) };
     }
 
     /// Returns the smallest integer greater than or equal to a number.
@@ -300,13 +313,11 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ceil(self) -> f32 {
-        return ceilf(self);
-
         // see notes above in `floor`
         #[cfg(target_env = "msvc")]
-        fn ceilf(f: f32) -> f32 { (f as f64).ceil() as f32 }
+        return (self as f64).ceil() as f32;
         #[cfg(not(target_env = "msvc"))]
-        fn ceilf(f: f32) -> f32 { unsafe { intrinsics::ceilf32(f) } }
+        return unsafe { intrinsics::ceilf32(self) };
     }
 
     /// Returns the nearest integer to a number. Round half-way cases away from
@@ -501,13 +512,11 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn powf(self, n: f32) -> f32 {
-        return powf(self, n);
-
         // see notes above in `floor`
         #[cfg(target_env = "msvc")]
-        fn powf(f: f32, n: f32) -> f32 { (f as f64).powf(n as f64) as f32 }
+        return (self as f64).powf(n as f64) as f32;
         #[cfg(not(target_env = "msvc"))]
-        fn powf(f: f32, n: f32) -> f32 { unsafe { intrinsics::powf32(f, n) } }
+        return unsafe { intrinsics::powf32(self, n) };
     }
 
     /// Takes the square root of a number.
@@ -552,13 +561,11 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn exp(self) -> f32 {
-        return expf(self);
-
         // see notes above in `floor`
         #[cfg(target_env = "msvc")]
-        fn expf(f: f32) -> f32 { (f as f64).exp() as f32 }
+        return (self as f64).exp() as f32;
         #[cfg(not(target_env = "msvc"))]
-        fn expf(f: f32) -> f32 { unsafe { intrinsics::expf32(f) } }
+        return unsafe { intrinsics::expf32(self) };
     }
 
     /// Returns `2^(self)`.
@@ -596,13 +603,11 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ln(self) -> f32 {
-        return logf(self);
-
         // see notes above in `floor`
         #[cfg(target_env = "msvc")]
-        fn logf(f: f32) -> f32 { (f as f64).ln() as f32 }
+        return (self as f64).ln() as f32;
         #[cfg(not(target_env = "msvc"))]
-        fn logf(f: f32) -> f32 { unsafe { intrinsics::logf32(f) } }
+        return unsafe { intrinsics::logf32(self) };
     }
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
@@ -659,20 +664,16 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log10(self) -> f32 {
-        return log10f(self);
-
         // see notes above in `floor`
         #[cfg(target_env = "msvc")]
-        fn log10f(f: f32) -> f32 { (f as f64).log10() as f32 }
+        return (self as f64).log10() as f32;
         #[cfg(not(target_env = "msvc"))]
-        fn log10f(f: f32) -> f32 { unsafe { intrinsics::log10f32(f) } }
+        return unsafe { intrinsics::log10f32(self) };
     }
 
     /// Converts radians to degrees.
     ///
     /// ```
-    /// #![feature(float_extras)]
-    ///
     /// use std::f32::{self, consts};
     ///
     /// let angle = consts::PI;
@@ -681,16 +682,13 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[unstable(feature = "float_extras", reason = "desirability is unclear",
-               issue = "27752")]
+    #[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
     #[inline]
     pub fn to_degrees(self) -> f32 { num::Float::to_degrees(self) }
 
     /// Converts degrees to radians.
     ///
     /// ```
-    /// #![feature(float_extras)]
-    ///
     /// use std::f32::{self, consts};
     ///
     /// let angle = 180.0f32;
@@ -699,8 +697,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[unstable(feature = "float_extras", reason = "desirability is unclear",
-               issue = "27752")]
+    #[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
     #[inline]
     pub fn to_radians(self) -> f32 { num::Float::to_radians(self) }
 
@@ -885,13 +882,11 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sin(self) -> f32 {
-        return sinf(self);
-
         // see notes in `core::f32::Float::floor`
         #[cfg(target_env = "msvc")]
-        fn sinf(f: f32) -> f32 { (f as f64).sin() as f32 }
+        return (self as f64).sin() as f32;
         #[cfg(not(target_env = "msvc"))]
-        fn sinf(f: f32) -> f32 { unsafe { intrinsics::sinf32(f) } }
+        return unsafe { intrinsics::sinf32(self) };
     }
 
     /// Computes the cosine of a number (in radians).
@@ -908,13 +903,11 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn cos(self) -> f32 {
-        return cosf(self);
-
         // see notes in `core::f32::Float::floor`
         #[cfg(target_env = "msvc")]
-        fn cosf(f: f32) -> f32 { (f as f64).cos() as f32 }
+        return (self as f64).cos() as f32;
         #[cfg(not(target_env = "msvc"))]
-        fn cosf(f: f32) -> f32 { unsafe { intrinsics::cosf32(f) } }
+        return unsafe { intrinsics::cosf32(self) };
     }
 
     /// Computes the tangent of a number (in radians).
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index d444b259445..b6a85ee0e9f 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -15,9 +15,13 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
+#[cfg(not(test))]
 use core::num;
+#[cfg(not(test))]
 use intrinsics;
+#[cfg(not(test))]
 use libc::c_int;
+#[cfg(not(test))]
 use num::FpCategory;
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index 8e207f5e6cf..faaff494cab 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -47,11 +47,6 @@ pub fn test_num<T>(ten: T, two: T) where
 #[cfg(test)]
 mod tests {
     use super::*;
-    use i8;
-    use i16;
-    use i32;
-    use i64;
-    use isize;
     use u8;
     use u16;
     use u32;
diff --git a/src/libstd/os/linux/raw.rs b/src/libstd/os/linux/raw.rs
index f44199f311b..953d0917141 100644
--- a/src/libstd/os/linux/raw.rs
+++ b/src/libstd/os/linux/raw.rs
@@ -205,7 +205,8 @@ mod arch {
     }
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64",
+          target_arch = "powerpc64le"))]
 mod arch {
     use super::{dev_t, mode_t};
     use os::raw::{c_long, c_int};
diff --git a/src/libstd/os/openbsd/raw.rs b/src/libstd/os/openbsd/raw.rs
index 209546c4e4f..b4d49395303 100644
--- a/src/libstd/os/openbsd/raw.rs
+++ b/src/libstd/os/openbsd/raw.rs
@@ -16,7 +16,7 @@ use os::raw::c_long;
 use os::unix::raw::{uid_t, gid_t};
 
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u32;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i32;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = i32;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64;
diff --git a/src/libstd/os/raw.rs b/src/libstd/os/raw.rs
index 17d6b2605c6..62080fee48e 100644
--- a/src/libstd/os/raw.rs
+++ b/src/libstd/os/raw.rs
@@ -14,11 +14,17 @@
 
 #[cfg(any(target_os = "android",
           all(target_os = "linux", any(target_arch = "aarch64",
-                                       target_arch = "arm"))))]
+                                       target_arch = "arm",
+                                       target_arch = "powerpc",
+                                       target_arch = "powerpc64",
+                                       target_arch = "powerpc64le"))))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8;
 #[cfg(not(any(target_os = "android",
               all(target_os = "linux", any(target_arch = "aarch64",
-                                           target_arch = "arm")))))]
+                                           target_arch = "arm",
+                                           target_arch = "powerpc",
+                                           target_arch = "powerpc64",
+                                           target_arch = "powerpc64le")))))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8;
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8;
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8;
@@ -88,7 +94,8 @@ mod tests {
             c_longlong c_ulonglong c_float c_double);
     }
 
-    #[cfg(unix)]
+    #[cfg(all(unix, not(target_os = "android")))]
+    #[test]
     fn unix() {
         {
             use os::unix::raw;
@@ -101,6 +108,7 @@ mod tests {
     }
 
     #[cfg(windows)]
+    #[test]
     fn windows() {
         use os::windows::raw;
     }
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 6e4ba337b08..8c0a785a102 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -13,6 +13,8 @@
 #![unstable(feature = "std_panic", reason = "awaiting feedback",
             issue = "27719")]
 
+use any::Any;
+use boxed::Box;
 use cell::UnsafeCell;
 use ops::{Deref, DerefMut};
 use ptr::{Unique, Shared};
@@ -21,6 +23,8 @@ use sync::{Arc, Mutex, RwLock};
 use sys_common::unwind;
 use thread::Result;
 
+pub use panicking::{take_handler, set_handler, PanicInfo, Location};
+
 /// A marker trait which represents "panic safe" types in Rust.
 ///
 /// This trait is implemented by default for many types and behaves similarly in
@@ -39,15 +43,15 @@ use thread::Result;
 ///    panics.
 /// 2. This broken invariant is then later observed.
 ///
-/// Typically in Rust it is difficult to perform step (2) because catching a
+/// Typically in Rust, it is difficult to perform step (2) because catching a
 /// panic involves either spawning a thread (which in turns makes it difficult
 /// to later witness broken invariants) or using the `recover` function in this
-/// module. Additionally, even if an invariant is witness, it typically isn't a
+/// module. Additionally, even if an invariant is witnessed, it typically isn't a
 /// problem in Rust because there's no uninitialized values (like in C or C++).
 ///
 /// It is possible, however, for **logical** invariants to be broken in Rust,
 /// which can end up causing behavioral bugs. Another key aspect of panic safety
-/// in Rust is that in the absence of `unsafe` code, a panic cannot lead to
+/// in Rust is that, in the absence of `unsafe` code, a panic cannot lead to
 /// memory unsafety.
 ///
 /// That was a bit of a whirlwind tour of panic safety, but for more information
@@ -58,12 +62,12 @@ use thread::Result;
 /// ## What is `RecoverSafe`?
 ///
 /// Now that we've got an idea of what panic safety is in Rust, it's also
-/// important to understand that this trait represents. As mentioned above, one
+/// important to understand what this trait represents. As mentioned above, one
 /// way to witness broken invariants is through the `recover` function in this
 /// module as it allows catching a panic and then re-using the environment of
 /// the closure.
 ///
-/// Simply but, a type `T` implements `RecoverSafe` if it cannot easily allow
+/// Simply put, a type `T` implements `RecoverSafe` if it cannot easily allow
 /// witnessing a broken invariant through the use of `recover` (catching a
 /// panic). This trait is a marker trait, so it is automatically implemented for
 /// many types, and it is also structurally composed (e.g. a struct is recover
@@ -99,8 +103,11 @@ use thread::Result;
                             across a recover boundary"]
 pub trait RecoverSafe {}
 
-/// A marker trait representing types which do not contain an `UnsafeCell` by
-/// value internally.
+/// A marker trait representing types where a shared reference is considered
+/// recover safe.
+///
+/// This trait is namely not implemented by `UnsafeCell`, the root of all
+/// interior mutability.
 ///
 /// This is a "helper marker trait" used to provide impl blocks for the
 /// `RecoverSafe` trait, for more information see that documentation.
@@ -108,7 +115,7 @@ pub trait RecoverSafe {}
 #[rustc_on_unimplemented = "the type {Self} contains interior mutability \
                             and a reference may not be safely transferrable \
                             across a recover boundary"]
-pub trait NoUnsafeCell {}
+pub trait RefRecoverSafe {}
 
 /// A simple wrapper around a type to assert that it is panic safe.
 ///
@@ -157,11 +164,11 @@ pub struct AssertRecoverSafe<T>(T);
 // * Our custom AssertRecoverSafe wrapper is indeed recover safe
 impl RecoverSafe for .. {}
 impl<'a, T: ?Sized> !RecoverSafe for &'a mut T {}
-impl<'a, T: NoUnsafeCell + ?Sized> RecoverSafe for &'a T {}
-impl<T: NoUnsafeCell + ?Sized> RecoverSafe for *const T {}
-impl<T: NoUnsafeCell + ?Sized> RecoverSafe for *mut T {}
+impl<'a, T: RefRecoverSafe + ?Sized> RecoverSafe for &'a T {}
+impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *const T {}
+impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *mut T {}
 impl<T: RecoverSafe> RecoverSafe for Unique<T> {}
-impl<T: NoUnsafeCell + ?Sized> RecoverSafe for Shared<T> {}
+impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Shared<T> {}
 impl<T: ?Sized> RecoverSafe for Mutex<T> {}
 impl<T: ?Sized> RecoverSafe for RwLock<T> {}
 impl<T> RecoverSafe for AssertRecoverSafe<T> {}
@@ -169,15 +176,16 @@ impl<T> RecoverSafe for AssertRecoverSafe<T> {}
 // not covered via the Shared impl above b/c the inner contents use
 // Cell/AtomicUsize, but the usage here is recover safe so we can lift the
 // impl up one level to Arc/Rc itself
-impl<T: NoUnsafeCell + ?Sized> RecoverSafe for Rc<T> {}
-impl<T: NoUnsafeCell + ?Sized> RecoverSafe for Arc<T> {}
+impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Rc<T> {}
+impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Arc<T> {}
 
-// Pretty simple implementations for the `NoUnsafeCell` marker trait, basically
-// just saying that this is a marker trait and `UnsafeCell` is the only thing
-// which doesn't implement it (which then transitively applies to everything
-// else.
-impl NoUnsafeCell for .. {}
-impl<T: ?Sized> !NoUnsafeCell for UnsafeCell<T> {}
+// Pretty simple implementations for the `RefRecoverSafe` marker trait,
+// basically just saying that this is a marker trait and `UnsafeCell` is the
+// only thing which doesn't implement it (which then transitively applies to
+// everything else).
+impl RefRecoverSafe for .. {}
+impl<T: ?Sized> !RefRecoverSafe for UnsafeCell<T> {}
+impl<T> RefRecoverSafe for AssertRecoverSafe<T> {}
 
 impl<T> AssertRecoverSafe<T> {
     /// Creates a new `AssertRecoverSafe` wrapper around the provided type.
@@ -253,3 +261,28 @@ pub fn recover<F: FnOnce() -> R + RecoverSafe, R>(f: F) -> Result<R> {
     }
     Ok(result.unwrap())
 }
+
+/// Triggers a panic without invoking the panic handler.
+///
+/// This is designed to be used in conjunction with `recover` to, for example,
+/// carry a panic across a layer of C code.
+///
+/// # Examples
+///
+/// ```should_panic
+/// #![feature(std_panic, recover, panic_propagate)]
+///
+/// use std::panic;
+///
+/// let result = panic::recover(|| {
+///     panic!("oh no!");
+/// });
+///
+/// if let Err(err) = result {
+///     panic::propagate(err);
+/// }
+/// ```
+#[unstable(feature = "panic_propagate", reason = "awaiting feedback", issue = "30752")]
+pub fn propagate(payload: Box<Any + Send>) -> ! {
+    unwind::rust_panic(payload)
+}
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 2b2af350c99..8561ecd9c4c 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -15,10 +15,12 @@ use any::Any;
 use cell::Cell;
 use cell::RefCell;
 use intrinsics;
+use sync::StaticRwLock;
 use sys::stdio::Stderr;
 use sys_common::backtrace;
 use sys_common::thread_info;
 use sys_common::util;
+use thread;
 
 thread_local! { pub static PANIC_COUNT: Cell<usize> = Cell::new(0) }
 
@@ -28,11 +30,138 @@ thread_local! {
     }
 }
 
-fn log_panic(obj: &(Any+Send), file: &'static str, line: u32,
-             log_backtrace: bool) {
-    let msg = match obj.downcast_ref::<&'static str>() {
+#[derive(Copy, Clone)]
+enum Handler {
+    Default,
+    Custom(*mut (Fn(&PanicInfo) + 'static + Sync + Send)),
+}
+
+static HANDLER_LOCK: StaticRwLock = StaticRwLock::new();
+static mut HANDLER: Handler = Handler::Default;
+
+/// Registers a custom panic handler, replacing any that was previously
+/// registered.
+///
+/// The panic handler is invoked when a thread panics, but before it begins
+/// unwinding the stack. The default handler prints a message to standard error
+/// and generates a backtrace if requested, but this behavior can be customized
+/// with the `set_handler` and `take_handler` functions.
+///
+/// The handler is provided with a `PanicInfo` struct which contains information
+/// about the origin of the panic, including the payload passed to `panic!` and
+/// the source code location from which the panic originated.
+///
+/// The panic handler is a global resource.
+///
+/// # Panics
+///
+/// Panics if called from a panicking thread.
+#[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+pub fn set_handler<F>(handler: F) where F: Fn(&PanicInfo) + 'static + Sync + Send {
+    if thread::panicking() {
+        panic!("cannot modify the panic handler from a panicking thread");
+    }
+
+    let handler = Box::new(handler);
+    unsafe {
+        let lock = HANDLER_LOCK.write();
+        let old_handler = HANDLER;
+        HANDLER = Handler::Custom(Box::into_raw(handler));
+        drop(lock);
+
+        if let Handler::Custom(ptr) = old_handler {
+            Box::from_raw(ptr);
+        }
+    }
+}
+
+/// Unregisters the current panic handler, returning it.
+///
+/// If no custom handler is registered, the default handler will be returned.
+///
+/// # Panics
+///
+/// Panics if called from a panicking thread.
+#[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
+    if thread::panicking() {
+        panic!("cannot modify the panic handler from a panicking thread");
+    }
+
+    unsafe {
+        let lock = HANDLER_LOCK.write();
+        let handler = HANDLER;
+        HANDLER = Handler::Default;
+        drop(lock);
+
+        match handler {
+            Handler::Default => Box::new(default_handler),
+            Handler::Custom(ptr) => {Box::from_raw(ptr)} // FIXME #30530
+        }
+    }
+}
+
+/// A struct providing information about a panic.
+#[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+pub struct PanicInfo<'a> {
+    payload: &'a (Any + Send),
+    location: Location<'a>,
+}
+
+impl<'a> PanicInfo<'a> {
+    /// Returns the payload associated with the panic.
+    ///
+    /// This will commonly, but not always, be a `&'static str` or `String`.
+    #[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+    pub fn payload(&self) -> &(Any + Send) {
+        self.payload
+    }
+
+    /// Returns information about the location from which the panic originated,
+    /// if available.
+    ///
+    /// This method will currently always return `Some`, but this may change
+    /// in future versions.
+    #[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+    pub fn location(&self) -> Option<&Location> {
+        Some(&self.location)
+    }
+}
+
+/// A struct containing information about the location of a panic.
+#[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+pub struct Location<'a> {
+    file: &'a str,
+    line: u32,
+}
+
+impl<'a> Location<'a> {
+    /// Returns the name of the source file from which the panic originated.
+    #[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+    pub fn file(&self) -> &str {
+        self.file
+    }
+
+    /// Returns the line number from which the panic originated.
+    #[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+    pub fn line(&self) -> u32 {
+        self.line
+    }
+}
+
+fn default_handler(info: &PanicInfo) {
+    let panics = PANIC_COUNT.with(|s| s.get());
+
+    // If this is a double panic, make sure that we print a backtrace
+    // for this panic. Otherwise only print it if logging is enabled.
+    let log_backtrace = panics >= 2 || backtrace::log_enabled();
+
+    let file = info.location.file;
+    let line = info.location.line;
+
+    let msg = match info.payload.downcast_ref::<&'static str>() {
         Some(s) => *s,
-        None => match obj.downcast_ref::<String>() {
+        None => match info.payload.downcast_ref::<String>() {
             Some(s) => &s[..],
             None => "Box<Any>",
         }
@@ -77,14 +206,25 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
     // debugger provides a useable stacktrace.
     if panics >= 3 {
         util::dumb_print(format_args!("thread panicked while processing \
-                                       panic. aborting."));
+                                       panic. aborting.\n"));
         unsafe { intrinsics::abort() }
     }
 
-    // If this is a double panic, make sure that we print a backtrace
-    // for this panic. Otherwise only print it if logging is enabled.
-    let log_backtrace = panics >= 2 || backtrace::log_enabled();
-    log_panic(obj, file, line, log_backtrace);
+    let info = PanicInfo {
+        payload: obj,
+        location: Location {
+            file: file,
+            line: line,
+        },
+    };
+
+    unsafe {
+        let _lock = HANDLER_LOCK.read();
+        match HANDLER {
+            Handler::Default => default_handler(&info),
+            Handler::Custom(ptr) => (*ptr)(&info),
+        }
+    }
 
     if panics >= 2 {
         // If a thread panics while it's already unwinding then we
@@ -92,7 +232,7 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
         // just abort. In the future we may consider resuming
         // unwinding or otherwise exiting the thread cleanly.
         util::dumb_print(format_args!("thread panicked while panicking. \
-                                       aborting."));
+                                       aborting.\n"));
         unsafe { intrinsics::abort() }
     }
 }
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index d0b9cc4c460..3956f948eb9 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -266,27 +266,33 @@ mod platform {
 pub enum Prefix<'a> {
     /// Prefix `\\?\`, together with the given component immediately following it.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Verbatim(&'a OsStr),
+    Verbatim(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr),
 
     /// Prefix `\\?\UNC\`, with the "server" and "share" components following it.
     #[stable(feature = "rust1", since = "1.0.0")]
-    VerbatimUNC(&'a OsStr, &'a OsStr),
+    VerbatimUNC(
+        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr,
+        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr,
+    ),
 
     /// Prefix like `\\?\C:\`, for the given drive letter
     #[stable(feature = "rust1", since = "1.0.0")]
-    VerbatimDisk(u8),
+    VerbatimDisk(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] u8),
 
     /// Prefix `\\.\`, together with the given component immediately following it.
     #[stable(feature = "rust1", since = "1.0.0")]
-    DeviceNS(&'a OsStr),
+    DeviceNS(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr),
 
     /// Prefix `\\server\share`, with the given "server" and "share" components.
     #[stable(feature = "rust1", since = "1.0.0")]
-    UNC(&'a OsStr, &'a OsStr),
+    UNC(
+        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr,
+        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr,
+    ),
 
     /// Prefix `C:` for the given disk drive.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Disk(u8),
+    Disk(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] u8),
 }
 
 impl<'a> Prefix<'a> {
@@ -528,7 +534,9 @@ pub enum Component<'a> {
     ///
     /// Does not occur on Unix.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Prefix(PrefixComponent<'a>),
+    Prefix(
+        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] PrefixComponent<'a>
+    ),
 
     /// The root directory component, appears after any prefix and before anything else
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -544,7 +552,7 @@ pub enum Component<'a> {
 
     /// A normal component, i.e. `a` and `b` in `a/b`
     #[stable(feature = "rust1", since = "1.0.0")]
-    Normal(&'a OsStr),
+    Normal(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr),
 }
 
 impl<'a> Component<'a> {
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index c7cb10a4707..619f100f1a1 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -30,23 +30,24 @@ mod imp {
                   target_arch = "x86",
                   target_arch = "arm",
                   target_arch = "aarch64",
-                  target_arch = "powerpc")))]
+                  target_arch = "powerpc",
+                  target_arch = "powerpc64",
+                  target_arch = "powerpc64le")))]
     fn getrandom(buf: &mut [u8]) -> libc::c_long {
-        extern "C" {
-            fn syscall(number: libc::c_long, ...) -> libc::c_long;
-        }
-
         #[cfg(target_arch = "x86_64")]
         const NR_GETRANDOM: libc::c_long = 318;
         #[cfg(target_arch = "x86")]
         const NR_GETRANDOM: libc::c_long = 355;
-        #[cfg(any(target_arch = "arm", target_arch = "powerpc"))]
+        #[cfg(target_arch = "arm")]
         const NR_GETRANDOM: libc::c_long = 384;
+        #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64",
+                  target_arch = "powerpc64le"))]
+        const NR_GETRANDOM: libc::c_long = 359;
         #[cfg(target_arch = "aarch64")]
         const NR_GETRANDOM: libc::c_long = 278;
 
         unsafe {
-            syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0)
+            libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0)
         }
     }
 
@@ -55,7 +56,9 @@ mod imp {
                       target_arch = "x86",
                       target_arch = "arm",
                       target_arch = "aarch64",
-                      target_arch = "powerpc"))))]
+                      target_arch = "powerpc",
+                      target_arch = "powerpc64",
+                      target_arch = "powerpc64le"))))]
     fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }
 
     fn getrandom_fill_bytes(v: &mut [u8]) {
@@ -92,7 +95,9 @@ mod imp {
                   target_arch = "x86",
                   target_arch = "arm",
                   target_arch = "aarch64",
-                  target_arch = "powerpc")))]
+                  target_arch = "powerpc",
+                  target_arch = "powerpc64",
+                  target_arch = "powerpc64le")))]
     fn is_getrandom_available() -> bool {
         use sync::atomic::{AtomicBool, Ordering};
         use sync::Once;
@@ -120,7 +125,9 @@ mod imp {
                       target_arch = "x86",
                       target_arch = "arm",
                       target_arch = "aarch64",
-                      target_arch = "powerpc"))))]
+                      target_arch = "powerpc",
+                      target_arch = "powerpc64",
+                      target_arch = "powerpc64le"))))]
     fn is_getrandom_available() -> bool { false }
 
     /// A random number generator that retrieves randomness straight from
@@ -226,7 +233,7 @@ mod imp {
             // getentropy(2) permits a maximum buffer size of 256 bytes
             for s in v.chunks_mut(256) {
                 let ret = unsafe {
-                    libc::syscall(libc::NR_GETENTROPY, s.as_mut_ptr(), s.len())
+                    libc::getentropy(s.as_mut_ptr() as *mut libc::c_void, s.len())
                 };
                 if ret == -1 {
                     panic!("unexpected getentropy error: {}", errno());
@@ -381,8 +388,6 @@ mod imp {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use sync::mpsc::channel;
     use rand::Rng;
     use super::OsRng;
diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs
index 36adf44cd3a..08bc809ed4d 100644
--- a/src/libstd/rand/reader.rs
+++ b/src/libstd/rand/reader.rs
@@ -63,8 +63,6 @@ impl<R: Read> Rng for ReaderRng<R> {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use super::ReaderRng;
     use rand::Rng;
 
diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs
index 63fb9b561ff..fcd827e2a8b 100644
--- a/src/libstd/rt.rs
+++ b/src/libstd/rt.rs
@@ -22,13 +22,7 @@
             issue = "0")]
 #![doc(hidden)]
 
-use borrow::ToOwned;
-use mem;
-use panic;
-use sys;
-use sys_common::thread_info::{self, NewThread};
-use sys_common;
-use thread::Thread;
+
 
 // Reexport some of our utilities which are expected by other crates.
 pub use sys_common::unwind::{begin_unwind, begin_unwind_fmt};
@@ -41,6 +35,14 @@ pub use sys_common::unwind::imp::eh_frame_registry::*;
 #[cfg(not(test))]
 #[lang = "start"]
 fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
+    use borrow::ToOwned;
+    use mem;
+    use panic;
+    use sys;
+    use sys_common;
+    use sys_common::thread_info::{self, NewThread};
+    use thread::Thread;
+
     sys::init();
 
     let failed = unsafe {
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index d817a261f7c..1f7fe820bf8 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -510,15 +510,15 @@ mod tests {
         static M: StaticMutex = StaticMutex::new();
 
         let g = M.lock().unwrap();
-        let (g, _no_timeout) = C.wait_timeout_ms(g, 1).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, no_timeout) = C.wait_timeout_ms(g, u32::MAX).unwrap();
-        assert!(no_timeout);
+        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(); }
     }
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index e87ae19c583..3eb5db09bc0 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -385,12 +385,12 @@ pub enum TrySendError<T> {
     /// this is not a buffered channel, then there is no receiver available to
     /// acquire the data.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Full(T),
+    Full(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] T),
 
     /// This channel's receiving half has disconnected, so the data could not be
     /// sent. The data is returned back to the callee in this case.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Disconnected(T),
+    Disconnected(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] T),
 }
 
 enum Flavor<T> {
diff --git a/src/libstd/sys/common/io.rs b/src/libstd/sys/common/io.rs
index 151d853fc9f..9f2f0df3a64 100644
--- a/src/libstd/sys/common/io.rs
+++ b/src/libstd/sys/common/io.rs
@@ -133,7 +133,7 @@ mod tests {
         b.iter(|| {
             let mut lr = repeat(1).take(10000000);
             let mut vec = Vec::with_capacity(1024);
-            unsafe { read_to_end_uninitialized(&mut lr, &mut vec) };
+            unsafe { read_to_end_uninitialized(&mut lr, &mut vec) }
         });
     }
 }
diff --git a/src/libstd/sys/common/libunwind.rs b/src/libstd/sys/common/libunwind.rs
index feb05c7b560..77d1eed9623 100644
--- a/src/libstd/sys/common/libunwind.rs
+++ b/src/libstd/sys/common/libunwind.rs
@@ -83,7 +83,8 @@ pub const unwinder_private_data_size: usize = 2;
 #[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
 pub const unwinder_private_data_size: usize = 2;
 
-#[cfg(target_arch = "powerpc")]
+#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64",
+          target_arch = "powerpc64le"))]
 pub const unwinder_private_data_size: usize = 2;
 
 #[repr(C)]
diff --git a/src/libstd/sys/common/poison.rs b/src/libstd/sys/common/poison.rs
index 446a4445b2d..2cfa04c843b 100644
--- a/src/libstd/sys/common/poison.rs
+++ b/src/libstd/sys/common/poison.rs
@@ -71,7 +71,7 @@ pub enum TryLockError<T> {
     /// The lock could not be acquired because another thread failed while holding
     /// the lock.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Poisoned(PoisonError<T>),
+    Poisoned(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] PoisonError<T>),
     /// The lock could not be acquired at this time because the operation would
     /// otherwise block.
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/sys/common/remutex.rs b/src/libstd/sys/common/remutex.rs
index f3f21e47a14..31caa68c4b7 100644
--- a/src/libstd/sys/common/remutex.rs
+++ b/src/libstd/sys/common/remutex.rs
@@ -167,7 +167,6 @@ mod tests {
     use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
     use cell::RefCell;
     use sync::Arc;
-    use boxed;
     use thread;
 
     #[test]
@@ -208,13 +207,13 @@ mod tests {
     fn trylock_works() {
         let m = Arc::new(ReentrantMutex::new(()));
         let m2 = m.clone();
-        let lock = m.try_lock().unwrap();
-        let lock2 = m.try_lock().unwrap();
+        let _lock = m.try_lock().unwrap();
+        let _lock2 = m.try_lock().unwrap();
         thread::spawn(move || {
             let lock = m2.try_lock();
             assert!(lock.is_err());
         }).join().unwrap();
-        let lock3 = m.try_lock().unwrap();
+        let _lock3 = m.try_lock().unwrap();
     }
 
     pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>);
@@ -233,9 +232,8 @@ mod tests {
             *lock.borrow_mut() = 1;
             let lock2 = mc.lock().unwrap();
             *lock.borrow_mut() = 2;
-            let answer = Answer(lock2);
+            let _answer = Answer(lock2);
             panic!("What the answer to my lifetimes dilemma is?");
-            drop(answer);
         }).join();
         assert!(result.is_err());
         let r = m.lock().err().unwrap().into_inner();
diff --git a/src/libstd/sys/common/unwind/mod.rs b/src/libstd/sys/common/unwind/mod.rs
index 0f10e727461..666b2ed72ad 100644
--- a/src/libstd/sys/common/unwind/mod.rs
+++ b/src/libstd/sys/common/unwind/mod.rs
@@ -172,7 +172,7 @@ pub fn panicking() -> bool {
 #[inline(never)]
 #[no_mangle]
 #[allow(private_no_mangle_fns)]
-fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
+pub fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
     unsafe {
         imp::panic(cause)
     }
diff --git a/src/libstd/sys/common/util.rs b/src/libstd/sys/common/util.rs
index 979f1f48669..b7a6b7650d5 100644
--- a/src/libstd/sys/common/util.rs
+++ b/src/libstd/sys/common/util.rs
@@ -35,12 +35,12 @@ pub fn dumb_print(args: fmt::Arguments) {
 }
 
 pub fn abort(args: fmt::Arguments) -> ! {
-    dumb_print(format_args!("fatal runtime error: {}", args));
+    dumb_print(format_args!("fatal runtime error: {}\n", args));
     unsafe { intrinsics::abort(); }
 }
 
 #[allow(dead_code)] // stack overflow detection not enabled on all platforms
 pub unsafe fn report_overflow() {
-    dumb_print(format_args!("\nthread '{}' has overflowed its stack",
+    dumb_print(format_args!("\nthread '{}' has overflowed its stack\n",
                             thread::current().name().unwrap_or("<unknown>")));
 }
diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs
index 2e092d5f770..bc997af3a27 100644
--- a/src/libstd/sys/common/wtf8.rs
+++ b/src/libstd/sys/common/wtf8.rs
@@ -1067,7 +1067,7 @@ mod tests {
     #[test]
     fn wtf8buf_show_str() {
         let text = "a\té 💩\r";
-        let mut string = Wtf8Buf::from_str(text);
+        let string = Wtf8Buf::from_str(text);
         assert_eq!(format!("{:?}", text), format!("{:?}", string));
     }
 
diff --git a/src/libstd/sys/unix/ext/io.rs b/src/libstd/sys/unix/ext/io.rs
index 52ac37c6e33..4163ede46af 100644
--- a/src/libstd/sys/unix/ext/io.rs
+++ b/src/libstd/sys/unix/ext/io.rs
@@ -33,7 +33,7 @@ pub trait AsRawFd {
     /// Extracts the raw file descriptor.
     ///
     /// This method does **not** pass ownership of the raw file descriptor
-    /// to the caller. The descriptor is only guarantee to be valid while
+    /// to the caller. The descriptor is only guaranteed to be valid while
     /// the original object has not yet been destroyed.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn as_raw_fd(&self) -> RawFd;
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index e8575a6c21c..10fda3fcd7f 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -204,7 +204,8 @@ impl DirEntry {
 
     #[cfg(any(target_os = "macos",
               target_os = "ios",
-              target_os = "netbsd"))]
+              target_os = "netbsd",
+              target_os = "openbsd"))]
     fn name_bytes(&self) -> &[u8] {
         unsafe {
             ::slice::from_raw_parts(self.entry.d_name.as_ptr() as *const u8,
@@ -213,8 +214,7 @@ impl DirEntry {
     }
     #[cfg(any(target_os = "freebsd",
               target_os = "dragonfly",
-              target_os = "bitrig",
-              target_os = "openbsd"))]
+              target_os = "bitrig"))]
     fn name_bytes(&self) -> &[u8] {
         unsafe {
             ::slice::from_raw_parts(self.entry.d_name.as_ptr() as *const u8,
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index 68b0c3d6b0e..9771b057d8d 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -15,6 +15,7 @@ use io::{self, ErrorKind};
 use libc;
 use num::One;
 use ops::Neg;
+use alloc::oom;
 
 #[cfg(target_os = "android")]   pub use os::android as platform;
 #[cfg(target_os = "bitrig")]    pub use os::bitrig as platform;
@@ -45,7 +46,23 @@ pub mod thread_local;
 pub mod time;
 pub mod stdio;
 
-#[cfg(not(target_os = "nacl"))]
+// A nicer handler for out-of-memory situations than the default one. This one
+// prints a message to stderr before aborting. It is critical that this code
+// does not allocate any memory since we are in an OOM situation. Any errors are
+// ignored while printing since there's nothing we can do about them and we are
+// about to exit anyways.
+fn oom_handler() -> ! {
+    use intrinsics;
+    let msg = "fatal runtime error: out of memory\n";
+    unsafe {
+        libc::write(libc::STDERR_FILENO,
+                    msg.as_ptr() as *const libc::c_void,
+                    msg.len() as libc::size_t);
+        intrinsics::abort();
+    }
+}
+
+#[cfg(not(any(target_os = "nacl", test)))]
 pub fn init() {
     use libc::signal;
     // By default, some platforms will send a *signal* when an EPIPE error
@@ -58,9 +75,14 @@ pub fn init() {
     unsafe {
         assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != !0);
     }
+
+    oom::set_oom_handler(oom_handler);
+}
+
+#[cfg(all(target_os = "nacl", not(test)))]
+pub fn init() {
+    oom::set_oom_handler(oom_handler);
 }
-#[cfg(target_os = "nacl")]
-pub fn init() { }
 
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
     match errno as libc::c_int {
diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs
index 407fcb0a1b8..bb9d37f93ab 100644
--- a/src/libstd/sys/unix/process.rs
+++ b/src/libstd/sys/unix/process.rs
@@ -288,6 +288,32 @@ impl Process {
             unsafe { libc::_exit(1) }
         }
 
+        // Make sure that the source descriptors are not an stdio descriptor,
+        // otherwise the order which we set the child's descriptors may blow
+        // away a descriptor which we are hoping to save. For example,
+        // suppose we want the child's stderr to be the parent's stdout, and
+        // the child's stdout to be the parent's stderr. No matter which we
+        // dup first, the second will get overwritten prematurely.
+        let maybe_migrate = |src: Stdio, output: &mut AnonPipe| {
+            match src {
+                Stdio::Raw(fd @ libc::STDIN_FILENO) |
+                Stdio::Raw(fd @ libc::STDOUT_FILENO) |
+                Stdio::Raw(fd @ libc::STDERR_FILENO) => {
+                    let fd = match cvt_r(|| libc::dup(fd)) {
+                        Ok(fd) => fd,
+                        Err(_) => fail(output),
+                    };
+                    let fd = FileDesc::new(fd);
+                    fd.set_cloexec();
+                    Stdio::Raw(fd.into_raw())
+                },
+
+                s @ Stdio::None |
+                s @ Stdio::Inherit |
+                s @ Stdio::Raw(_) => s,
+            }
+        };
+
         let setup = |src: Stdio, dst: c_int| {
             match src {
                 Stdio::Inherit => true,
@@ -313,6 +339,12 @@ impl Process {
             }
         };
 
+        // Make sure we migrate all source descriptors before
+        // we start overwriting them
+        let in_fd = maybe_migrate(in_fd, &mut output);
+        let out_fd = maybe_migrate(out_fd, &mut output);
+        let err_fd = maybe_migrate(err_fd, &mut output);
+
         if !setup(in_fd, libc::STDIN_FILENO) { fail(&mut output) }
         if !setup(out_fd, libc::STDOUT_FILENO) { fail(&mut output) }
         if !setup(err_fd, libc::STDERR_FILENO) { fail(&mut output) }
@@ -462,8 +494,7 @@ mod tests {
     use mem;
     use ptr;
     use libc;
-    use slice;
-    use sys::{self, cvt, pipe};
+    use sys::{self, cvt};
 
     macro_rules! t {
         ($e:expr) => {
@@ -482,6 +513,8 @@ mod tests {
 
     #[cfg(target_os = "android")]
     unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
+        use slice;
+
         let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
         let bit = (signum - 1) as usize;
         raw[bit / 8] |= 1 << (bit % 8);
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 9a7f98d24cd..fc49f4257be 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -7,11 +7,13 @@
 // <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.
+#![cfg_attr(test, allow(dead_code))]
 
 use libc;
 use self::imp::{make_handler, drop_handler};
 
-pub use self::imp::{init, cleanup};
+pub use self::imp::cleanup;
+pub use self::imp::init;
 
 pub struct Handler {
     _data: *mut libc::c_void
@@ -40,12 +42,11 @@ impl Drop for Handler {
           target_os = "openbsd"))]
 mod imp {
     use super::Handler;
-    use sys_common::util::report_overflow;
     use mem;
     use ptr;
+    use libc::{sigaltstack, SIGSTKSZ};
     use libc::{sigaction, SIGBUS, SIG_DFL,
-               SA_SIGINFO, SA_ONSTACK, sigaltstack,
-               SIGSTKSZ, sighandler_t};
+               SA_SIGINFO, SA_ONSTACK, sighandler_t};
     use libc;
     use libc::{mmap, munmap};
     use libc::{SIGSEGV, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON};
@@ -58,19 +59,19 @@ mod imp {
     static mut PAGE_SIZE: usize = 0;
 
     #[cfg(any(target_os = "linux", target_os = "android"))]
-    unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> *mut libc::c_void {
+    unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
         #[repr(C)]
         struct siginfo_t {
             a: [libc::c_int; 3], // si_signo, si_code, si_errno,
             si_addr: *mut libc::c_void,
         }
 
-        (*(info as *const siginfo_t)).si_addr
+        (*(info as *const siginfo_t)).si_addr as usize
     }
 
     #[cfg(not(any(target_os = "linux", target_os = "android")))]
-    unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> *mut libc::c_void {
-        (*info).si_addr
+    unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
+        (*info).si_addr as usize
     }
 
     // Signal handler for the SIGSEGV and SIGBUS handlers. We've got guard pages
@@ -94,8 +95,10 @@ mod imp {
     unsafe extern fn signal_handler(signum: libc::c_int,
                                     info: *mut libc::siginfo_t,
                                     _data: *mut libc::c_void) {
+        use sys_common::util::report_overflow;
+
         let guard = thread_info::stack_guard().unwrap_or(0);
-        let addr = siginfo_si_addr(info) as usize;
+        let addr = siginfo_si_addr(info);
 
         // If the faulting address is within the guard page, then we print a
         // message saying so.
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 7e5342a3fd4..16c4ae8257c 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -20,6 +20,7 @@ use num::Zero;
 use os::windows::ffi::{OsStrExt, OsStringExt};
 use path::PathBuf;
 use time::Duration;
+use alloc::oom;
 
 #[macro_use] pub mod compat;
 
@@ -42,7 +43,26 @@ pub mod thread_local;
 pub mod time;
 pub mod stdio;
 
-pub fn init() {}
+// See comment in sys/unix/mod.rs
+fn oom_handler() -> ! {
+    use intrinsics;
+    use ptr;
+    let msg = "fatal runtime error: out of memory\n";
+    unsafe {
+        // WriteFile silently fails if it is passed an invalid handle, so there
+        // is no need to check the result of GetStdHandle.
+        c::WriteFile(c::GetStdHandle(c::STD_ERROR_HANDLE),
+                     msg.as_ptr() as c::LPVOID,
+                     msg.len() as c::DWORD,
+                     ptr::null_mut(),
+                     ptr::null_mut());
+        intrinsics::abort();
+    }
+}
+
+pub fn init() {
+    oom::set_oom_handler(oom_handler);
+}
 
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
     match errno as c::DWORD {
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 0e525f39421..116cd5da2ce 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -830,14 +830,14 @@ mod tests {
     fn test_park_timeout_unpark_before() {
         for _ in 0..10 {
             thread::current().unpark();
-            thread::park_timeout_ms(u32::MAX);
+            thread::park_timeout(Duration::from_millis(u32::MAX as u64));
         }
     }
 
     #[test]
     fn test_park_timeout_unpark_not_called() {
         for _ in 0..10 {
-            thread::park_timeout_ms(10);
+            thread::park_timeout(Duration::from_millis(10));
         }
     }
 
@@ -847,17 +847,17 @@ mod tests {
             let th = thread::current();
 
             let _guard = thread::spawn(move || {
-                super::sleep_ms(50);
+                super::sleep(Duration::from_millis(50));
                 th.unpark();
             });
 
-            thread::park_timeout_ms(u32::MAX);
+            thread::park_timeout(Duration::from_millis(u32::MAX as u64));
         }
     }
 
     #[test]
     fn sleep_ms_smoke() {
-        thread::sleep_ms(2);
+        thread::sleep(Duration::from_millis(2));
     }
 
     // NOTE: the corresponding test for stderr is in run-pass/thread-stderr, due
diff --git a/src/libstd/thread/scoped_tls.rs b/src/libstd/thread/scoped_tls.rs
index 2c92bc504c8..dc0bc6dfe02 100644
--- a/src/libstd/thread/scoped_tls.rs
+++ b/src/libstd/thread/scoped_tls.rs
@@ -87,32 +87,9 @@ macro_rules! scoped_thread_local {
            issue = "0")]
 #[macro_export]
 #[allow_internal_unstable]
-#[cfg(no_elf_tls)]
 macro_rules! __scoped_thread_local_inner {
     ($t:ty) => {{
-        static _KEY: $crate::thread::__ScopedKeyInner<$t> =
-            $crate::thread::__ScopedKeyInner::new();
-        fn _getit() -> &'static $crate::thread::__ScopedKeyInner<$t> { &_KEY }
-        $crate::thread::ScopedKey::new(_getit)
-    }}
-}
-
-#[doc(hidden)]
-#[unstable(feature = "thread_local_internals",
-           reason = "should not be necessary",
-           issue = "0")]
-#[macro_export]
-#[allow_internal_unstable]
-#[cfg(not(no_elf_tls))]
-macro_rules! __scoped_thread_local_inner {
-    ($t:ty) => {{
-        #[cfg_attr(not(any(windows,
-                           target_os = "android",
-                           target_os = "ios",
-                           target_os = "netbsd",
-                           target_os = "openbsd",
-                           target_arch = "aarch64")),
-                   thread_local)]
+        #[cfg_attr(target_thread_local, thread_local)]
         static _KEY: $crate::thread::__ScopedKeyInner<$t> =
             $crate::thread::__ScopedKeyInner::new();
         fn _getit() -> &'static $crate::thread::__ScopedKeyInner<$t> { &_KEY }
@@ -221,13 +198,7 @@ impl<T> ScopedKey<T> {
     }
 }
 
-#[cfg(not(any(windows,
-              target_os = "android",
-              target_os = "ios",
-              target_os = "netbsd",
-              target_os = "openbsd",
-              target_arch = "aarch64",
-              no_elf_tls)))]
+#[cfg(target_thread_local)]
 #[doc(hidden)]
 mod imp {
     use cell::Cell;
@@ -246,13 +217,7 @@ mod imp {
     }
 }
 
-#[cfg(any(windows,
-          target_os = "android",
-          target_os = "ios",
-          target_os = "netbsd",
-          target_os = "openbsd",
-          target_arch = "aarch64",
-          no_elf_tls))]
+#[cfg(not(target_thread_local))]
 #[doc(hidden)]
 mod imp {
     use cell::Cell;
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 0981a8c4a5b..7ecb3920cc8 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -40,7 +40,7 @@ const MILLIS_PER_SEC: u64 = 1_000;
 /// let ten_millis = Duration::from_millis(10);
 /// ```
 #[stable(feature = "duration", since = "1.3.0")]
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
 pub struct Duration {
     secs: u64,
     nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
@@ -173,7 +173,6 @@ impl Div<u32> for Duration {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use super::Duration;
 
     #[test]
diff --git a/src/libstd/time/mod.rs b/src/libstd/time/mod.rs
index e3ce8e0de4b..f885733c2d1 100644
--- a/src/libstd/time/mod.rs
+++ b/src/libstd/time/mod.rs
@@ -23,6 +23,7 @@ pub use self::duration::Duration;
 mod duration;
 
 /// A measurement of a monotonically increasing clock.
+///  Opaque and useful only with `Duration`.
 ///
 /// Instants are always guaranteed to be greater than any previously measured
 /// instant when created, and are often useful for tasks such as measuring
@@ -42,8 +43,8 @@ mod duration;
 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
 pub struct Instant(time::Instant);
 
-/// A measurement of the system clock appropriate for timestamps such as those
-/// on files on the filesystem.
+/// A measurement of the system clock, useful for talking to
+/// external entities like the file system or other processes.
 ///
 /// Distinct from the `Instant` type, this time measurement **is not
 /// monotonic**. This means that you can save a file to the file system, then