about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-01 22:41:08 +0000
committerbors <bors@rust-lang.org>2015-04-01 22:41:08 +0000
commit2e3b0c051dca9880bf66b5366dccd2e0bb424b99 (patch)
tree2e8b8ea5a0daf51f819acaab9b9e2572459e2a60 /src/libstd
parentd528aa9960cb9b937d8ef6c09905a6a8076d5f3a (diff)
parent0304e15e5c39654346e827c2bb25ca41ed310c86 (diff)
downloadrust-2e3b0c051dca9880bf66b5366dccd2e0bb424b99.tar.gz
rust-2e3b0c051dca9880bf66b5366dccd2e0bb424b99.zip
Auto merge of #23955 - alexcrichton:rollup, r=alexcrichton
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/error.rs152
-rw-r--r--src/libstd/io/mod.rs12
-rw-r--r--src/libstd/lib.rs3
-rw-r--r--src/libstd/net/addr.rs2
-rw-r--r--src/libstd/path.rs215
-rw-r--r--src/libstd/rand/os.rs4
-rw-r--r--src/libstd/rt/at_exit_imp.rs2
-rw-r--r--src/libstd/rt/mod.rs3
-rw-r--r--src/libstd/sync/condvar.rs50
-rw-r--r--src/libstd/sync/future.rs5
-rw-r--r--src/libstd/sys/common/thread.rs3
-rw-r--r--src/libstd/sys/unix/os.rs2
-rw-r--r--src/libstd/thread/mod.rs60
-rw-r--r--src/libstd/thunk.rs42
14 files changed, 456 insertions, 99 deletions
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
new file mode 100644
index 00000000000..150ffcdd77a
--- /dev/null
+++ b/src/libstd/error.rs
@@ -0,0 +1,152 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Traits for working with Errors.
+//!
+//! # The `Error` trait
+//!
+//! `Error` is a trait representing the basic expectations for error values,
+//! i.e. values of type `E` in `Result<T, E>`. At a minimum, errors must provide
+//! a description, but they may optionally provide additional detail (via
+//! `Display`) and cause chain information:
+//!
+//! ```
+//! use std::fmt::Display;
+//!
+//! trait Error: Display {
+//!     fn description(&self) -> &str;
+//!
+//!     fn cause(&self) -> Option<&Error> { None }
+//! }
+//! ```
+//!
+//! The `cause` method is generally used when errors cross "abstraction
+//! boundaries", i.e.  when a one module must report an error that is "caused"
+//! by an error from a lower-level module. This setup makes it possible for the
+//! high-level module to provide its own errors that do not commit to any
+//! particular implementation, but also reveal some of its implementation for
+//! debugging via `cause` chains.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+// A note about crates and the facade:
+//
+// Originally, the `Error` trait was defined in libcore, and the impls
+// were scattered about. However, coherence objected to this
+// arrangement, because to create the blanket impls for `Box` required
+// knowing that `&str: !Error`, and we have no means to deal with that
+// sort of conflict just now. Therefore, for the time being, we have
+// moved the `Error` trait into libstd. As we evolve a sol'n to the
+// coherence challenge (e.g., specialization, neg impls, etc) we can
+// reconsider what crate these items belong in.
+
+use boxed::Box;
+use convert::From;
+use fmt::{self, Debug, Display};
+use marker::Send;
+use num;
+use option::Option;
+use option::Option::None;
+use str;
+use string::{self, String};
+
+/// Base functionality for all errors in Rust.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Error: Debug + Display {
+    /// A short description of the error.
+    ///
+    /// The description should not contain newlines or sentence-ending
+    /// punctuation, to facilitate embedding in larger user-facing
+    /// strings.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn description(&self) -> &str;
+
+    /// The lower-level cause of this error, if any.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn cause(&self) -> Option<&Error> { None }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
+    fn from(err: E) -> Box<Error + 'a> {
+        Box::new(err)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, E: Error + Send + 'a> From<E> for Box<Error + Send + 'a> {
+    fn from(err: E) -> Box<Error + Send + 'a> {
+        Box::new(err)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, 'b> From<&'b str> for Box<Error + Send + 'a> {
+    fn from(err: &'b str) -> Box<Error + Send + 'a> {
+        #[derive(Debug)]
+        struct StringError(String);
+
+        impl Error for StringError {
+            fn description(&self) -> &str { &self.0 }
+        }
+
+        impl Display for StringError {
+            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                Display::fmt(&self.0, f)
+            }
+        }
+
+        Box::new(StringError(String::from_str(err)))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for str::ParseBoolError {
+    fn description(&self) -> &str { "failed to parse bool" }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for str::Utf8Error {
+    fn description(&self) -> &str {
+        match *self {
+            str::Utf8Error::TooShort => "invalid utf-8: not enough bytes",
+            str::Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for num::ParseIntError {
+    fn description(&self) -> &str {
+        self.description()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for num::ParseFloatError {
+    fn description(&self) -> &str {
+        self.description()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for string::FromUtf8Error {
+    fn description(&self) -> &str {
+        "invalid utf-8"
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for string::FromUtf16Error {
+    fn description(&self) -> &str {
+        "invalid utf-16"
+    }
+}
+
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index a014d6e68ff..c6335015d72 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -101,18 +101,14 @@ fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
 fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
     let start_len = buf.len();
     let mut len = start_len;
-    let mut cap_bump = 16;
+    let mut new_write_size = 16;
     let ret;
     loop {
         if len == buf.len() {
-            if buf.capacity() == buf.len() {
-                if cap_bump < DEFAULT_BUF_SIZE {
-                    cap_bump *= 2;
-                }
-                buf.reserve(cap_bump);
+            if new_write_size < DEFAULT_BUF_SIZE {
+                new_write_size *= 2;
             }
-            let new_area = buf.capacity() - buf.len();
-            buf.extend(iter::repeat(0).take(new_area));
+            buf.extend(iter::repeat(0).take(new_write_size));
         }
 
         match r.read(&mut buf[len..]) {
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 41ac3d60df5..5c9ff544fa3 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -183,7 +183,7 @@ pub use core::raw;
 pub use core::simd;
 pub use core::result;
 pub use core::option;
-pub use core::error;
+pub mod error;
 
 #[cfg(not(test))] pub use alloc::boxed;
 pub use alloc::rc;
@@ -243,6 +243,7 @@ mod uint_macros;
 #[path = "num/f64.rs"]   pub mod f64;
 
 pub mod ascii;
+
 pub mod thunk;
 
 /* Common traits */
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index c45230e91ba..886f252fb19 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -441,7 +441,7 @@ impl ToSocketAddrs for str {
         }
 
         // split the string by ':' and convert the second part to u16
-        let mut parts_iter = self.rsplitn(1, ':');
+        let mut parts_iter = self.rsplitn(2, ':');
         let port_str = try_opt!(parts_iter.next(), "invalid socket address");
         let host = try_opt!(parts_iter.next(), "invalid socket address");
         let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 9006ed33654..4471b5afa84 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -343,6 +343,15 @@ impl<'a> Prefix<'a> {
 
 /// Determine whether the character is one of the permitted path
 /// separators for the current platform.
+///
+/// # Examples
+///
+/// ```
+/// use std::path;
+///
+/// assert!(path::is_separator('/'));
+/// assert!(!path::is_separator('❤'));
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn is_separator(c: char) -> bool {
     use ascii::*;
@@ -406,7 +415,7 @@ fn split_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
         // contents of the encoding and (2) new &OsStr values are produced
         // only from ASCII-bounded slices of existing &OsStr values.
 
-        let mut iter = os_str_as_u8_slice(file).rsplitn(1, |b| *b == b'.');
+        let mut iter = os_str_as_u8_slice(file).rsplitn(2, |b| *b == b'.');
         let after = iter.next();
         let before = iter.next();
         if before == Some(b"") {
@@ -539,6 +548,18 @@ impl<'a> AsRef<OsStr> for Component<'a> {
 ///
 /// See the module documentation for an in-depth explanation of components and
 /// their role in the API.
+///
+/// # Examples
+///
+/// ```
+/// use std::path::Path;
+///
+/// let path = Path::new("/tmp/foo/bar.txt");
+///
+/// for component in path.components() {
+///     println!("{:?}", component);
+/// }
+/// ```
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Components<'a> {
@@ -609,6 +630,16 @@ impl<'a> Components<'a> {
     }
 
     /// Extract a slice corresponding to the portion of the path remaining for iteration.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo/bar.txt");
+    ///
+    /// println!("{:?}", path.components().as_path());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_path(&self) -> &'a Path {
         let mut comps = self.clone();
@@ -1210,12 +1241,28 @@ impl Path {
     /// Directly wrap a string slice as a `Path` slice.
     ///
     /// This is a cost-free conversion.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// Path::new("foo.txt");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &Path {
         unsafe { mem::transmute(s.as_ref()) }
     }
 
     /// Yield the underlying `OsStr` slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let os_str = Path::new("foo.txt").as_os_str();
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_os_str(&self) -> &OsStr {
         &self.inner
@@ -1224,6 +1271,14 @@ impl Path {
     /// Yield a `&str` slice if the `Path` is valid unicode.
     ///
     /// This conversion may entail doing a check for UTF-8 validity.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path_str = Path::new("foo.txt").to_str();
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_str(&self) -> Option<&str> {
         self.inner.to_str()
@@ -1232,12 +1287,28 @@ impl Path {
     /// Convert a `Path` to a `Cow<str>`.
     ///
     /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path_str = Path::new("foo.txt").to_string_lossy();
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_string_lossy(&self) -> Cow<str> {
         self.inner.to_string_lossy()
     }
 
     /// Convert a `Path` to an owned `PathBuf`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path_str = Path::new("foo.txt").to_path_buf();
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_path_buf(&self) -> PathBuf {
         PathBuf::from(self.inner.to_os_string())
@@ -1251,6 +1322,14 @@ impl Path {
     /// * On Windows, a path is absolute if it has a prefix and starts with the
     /// root: `c:\windows` is absolute, while `c:temp` and `\temp` are not. In
     /// other words, `path.is_absolute() == path.prefix().is_some() && path.has_root()`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// assert_eq!(false, Path::new("foo.txt").is_absolute());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_absolute(&self) -> bool {
         self.has_root() &&
@@ -1258,6 +1337,14 @@ impl Path {
     }
 
     /// A path is *relative* if it is not absolute.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// assert!(Path::new("foo.txt").is_relative());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_relative(&self) -> bool {
         !self.is_absolute()
@@ -1281,6 +1368,14 @@ impl Path {
     ///     * has no prefix and begins with a separator, e.g. `\\windows`
     ///     * has a prefix followed by a separator, e.g. `c:\windows` but not `c:windows`
     ///     * has any non-disk prefix, e.g. `\\server\share`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// assert!(Path::new("/etc/passwd").has_root());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn has_root(&self) -> bool {
          self.components().has_root()
@@ -1297,8 +1392,11 @@ impl Path {
     ///
     /// let path = Path::new("/foo/bar");
     /// let foo = path.parent().unwrap();
+    ///
     /// assert!(foo == Path::new("/foo"));
+    ///
     /// let root = foo.parent().unwrap();
+    ///
     /// assert!(root == Path::new("/"));
     /// assert!(root.parent() == None);
     /// ```
@@ -1318,6 +1416,17 @@ impl Path {
     ///
     /// If the path terminates in `.`, `..`, or consists solely or a root of
     /// prefix, `file_name` will return `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("hello_world.rs");
+    /// let filename = "hello_world.rs";
+    ///
+    /// assert_eq!(filename, path.file_name().unwrap());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn file_name(&self) -> Option<&OsStr> {
         self.components().next_back().and_then(|p| match p {
@@ -1337,12 +1446,32 @@ impl Path {
     }
 
     /// Determines whether `base` is a prefix of `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/etc/passwd");
+    ///
+    /// assert!(path.starts_with("/etc"));
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn starts_with<P: AsRef<Path>>(&self, base: P) -> bool {
         iter_after(self.components(), base.as_ref().components()).is_some()
     }
 
     /// Determines whether `child` is a suffix of `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/etc/passwd");
+    ///
+    /// assert!(path.ends_with("passwd"));
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn ends_with<P: AsRef<Path>>(&self, child: P) -> bool {
         iter_after(self.components().rev(), child.as_ref().components().rev()).is_some()
@@ -1356,6 +1485,16 @@ impl Path {
     /// * The entire file name if there is no embedded `.`;
     /// * The entire file name if the file name begins with `.` and has no other `.`s within;
     /// * Otherwise, the portion of the file name before the final `.`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("foo.rs");
+    ///
+    /// assert_eq!("foo", path.file_stem().unwrap());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn file_stem(&self) -> Option<&OsStr> {
         self.file_name().map(split_file_at_dot).and_then(|(before, after)| before.or(after))
@@ -1369,6 +1508,16 @@ impl Path {
     /// * None, if there is no embedded `.`;
     /// * None, if the file name begins with `.` and has no other `.`s within;
     /// * Otherwise, the portion of the file name after the final `.`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("foo.rs");
+    ///
+    /// assert_eq!("rs", path.extension().unwrap());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn extension(&self) -> Option<&OsStr> {
         self.file_name().map(split_file_at_dot).and_then(|(before, after)| before.and(after))
@@ -1377,6 +1526,16 @@ impl Path {
     /// Creates an owned `PathBuf` with `path` adjoined to `self`.
     ///
     /// See `PathBuf::push` for more details on what it means to adjoin a path.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp");
+    ///
+    /// let new_path = path.join("foo");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn join<P: AsRef<Path>>(&self, path: P) -> PathBuf {
         let mut buf = self.to_path_buf();
@@ -1387,6 +1546,16 @@ impl Path {
     /// Creates an owned `PathBuf` like `self` but with the given file name.
     ///
     /// See `PathBuf::set_file_name` for more details.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo.rs");
+    ///
+    /// let new_path = path.with_file_name("bar.rs");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_file_name<S: AsRef<OsStr>>(&self, file_name: S) -> PathBuf {
         let mut buf = self.to_path_buf();
@@ -1397,6 +1566,16 @@ impl Path {
     /// Creates an owned `PathBuf` like `self` but with the given extension.
     ///
     /// See `PathBuf::set_extension` for more details.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo.rs");
+    ///
+    /// let new_path = path.with_extension("foo.txt");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
         let mut buf = self.to_path_buf();
@@ -1405,6 +1584,18 @@ impl Path {
     }
 
     /// Produce an iterator over the components of the path.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo.rs");
+    ///
+    /// for component in path.components() {
+    ///     println!("{:?}", component);
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn components(&self) -> Components {
         let prefix = parse_prefix(self.as_os_str());
@@ -1418,6 +1609,18 @@ impl Path {
     }
 
     /// Produce an iterator over the path's components viewed as `OsStr` slices.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo.rs");
+    ///
+    /// for component in path.iter() {
+    ///     println!("{:?}", component);
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter(&self) -> Iter {
         Iter { inner: self.components() }
@@ -1425,6 +1628,16 @@ impl Path {
 
     /// Returns an object that implements `Display` for safely printing paths
     /// that may contain non-Unicode data.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo.rs");
+    ///
+    /// println!("{}", path.display());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn display(&self) -> Display {
         Display { path: self }
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index 7aba40dc6be..38c57eec684 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -185,9 +185,9 @@ mod imp {
 mod imp {
     use prelude::v1::*;
 
+    use io;
     use old_io::IoResult;
     use mem;
-    use os;
     use rand::Rng;
     use libc::{c_int, size_t};
 
@@ -241,7 +241,7 @@ mod imp {
                 SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr())
             };
             if ret == -1 {
-                panic!("couldn't generate random bytes: {}", os::last_os_error());
+                panic!("couldn't generate random bytes: {}", io::Error::last_os_error());
             }
         }
     }
diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs
index 9079c0aaffb..beb2870807a 100644
--- a/src/libstd/rt/at_exit_imp.rs
+++ b/src/libstd/rt/at_exit_imp.rs
@@ -64,7 +64,7 @@ pub fn cleanup() {
             if queue as usize != 0 {
                 let queue: Box<Queue> = Box::from_raw(queue);
                 for to_run in *queue {
-                    to_run.invoke(());
+                    to_run();
                 }
             }
         }
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 696c7960c3e..632d9647212 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -21,7 +21,6 @@
 
 use prelude::v1::*;
 use sys;
-use thunk::Thunk;
 use usize;
 
 // Reexport some of our utilities which are expected by other crates.
@@ -153,7 +152,7 @@ fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
 /// that the closure could not be registered, meaning that it is not scheduled
 /// to be rune.
 pub fn at_exit<F: FnOnce() + Send + 'static>(f: F) -> Result<(), ()> {
-    if at_exit_imp::push(Thunk::new(f)) {Ok(())} else {Err(())}
+    if at_exit_imp::push(Box::new(f)) {Ok(())} else {Err(())}
 }
 
 /// One-time runtime cleanup.
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index 69c5267ab69..a7d8b287a64 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -140,33 +140,43 @@ impl Condvar {
     /// Wait on this condition variable for a notification, timing out after a
     /// specified duration.
     ///
-    /// The semantics of this function are equivalent to `wait()` except that
-    /// the thread will be blocked for roughly no longer than `dur`. This method
-    /// should not be used for precise timing due to anomalies such as
-    /// preemption or platform differences that may not cause the maximum amount
-    /// of time waited to be precisely `dur`.
+    /// The semantics of this function are equivalent to `wait()`
+    /// except that the thread will be blocked for roughly no longer
+    /// than `ms` milliseconds. This method should not be used for
+    /// precise timing due to anomalies such as preemption or platform
+    /// differences that may not cause the maximum amount of time
+    /// waited to be precisely `ms`.
     ///
-    /// If the wait timed out, then `false` will be returned. Otherwise if a
-    /// notification was received then `true` will be returned.
+    /// The returned boolean is `false` only if the timeout is known
+    /// to have elapsed.
     ///
     /// Like `wait`, the lock specified will be re-acquired when this function
     /// returns, regardless of whether the timeout elapsed or not.
-    #[unstable(feature = "std_misc")]
-    pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>, dur: Duration)
-                           -> LockResult<(MutexGuard<'a, T>, bool)> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn wait_timeout_ms<'a, T>(&self, guard: MutexGuard<'a, T>, ms: u32)
+                                  -> LockResult<(MutexGuard<'a, T>, bool)> {
         unsafe {
             let me: &'static Condvar = &*(self as *const _);
-            me.inner.wait_timeout(guard, dur)
+            me.inner.wait_timeout_ms(guard, ms)
         }
     }
 
+    /// Deprecated: use `wait_timeout_ms` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0", reason = "use wait_timeout_ms instead")]
+    pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>, dur: Duration)
+                               -> LockResult<(MutexGuard<'a, T>, bool)> {
+        self.wait_timeout_ms(guard, dur.num_milliseconds() as u32)
+    }
+
     /// Wait on this condition variable for a notification, timing out after a
     /// specified duration.
     ///
     /// The semantics of this function are equivalent to `wait_timeout` except
     /// that the implementation will repeatedly wait while the duration has not
     /// passed and the provided function returns `false`.
-    #[unstable(feature = "std_misc")]
+    #[unstable(feature = "wait_timeout_with",
+               reason = "unsure if this API is broadly needed or what form it should take")]
     pub fn wait_timeout_with<'a, T, F>(&self,
                                        guard: MutexGuard<'a, T>,
                                        dur: Duration,
@@ -235,12 +245,12 @@ impl StaticCondvar {
     /// See `Condvar::wait_timeout`.
     #[unstable(feature = "std_misc",
                reason = "may be merged with Condvar in the future")]
-    pub fn wait_timeout<'a, T>(&'static self, guard: MutexGuard<'a, T>, dur: Duration)
-                               -> LockResult<(MutexGuard<'a, T>, bool)> {
+    pub fn wait_timeout_ms<'a, T>(&'static self, guard: MutexGuard<'a, T>, ms: u32)
+                                  -> LockResult<(MutexGuard<'a, T>, bool)> {
         let (poisoned, success) = unsafe {
             let lock = mutex::guard_lock(&guard);
             self.verify(lock);
-            let success = self.inner.wait_timeout(lock, dur);
+            let success = self.inner.wait_timeout(lock, Duration::milliseconds(ms as i64));
             (mutex::guard_poison(&guard).get(), success)
         };
         if poisoned {
@@ -275,7 +285,8 @@ impl StaticCondvar {
             let now = SteadyTime::now();
             let consumed = &now - &start;
             let guard = guard_result.unwrap_or_else(|e| e.into_inner());
-            let (new_guard_result, no_timeout) = match self.wait_timeout(guard, dur - consumed) {
+            let res = self.wait_timeout_ms(guard, (dur - consumed).num_milliseconds() as u32);
+            let (new_guard_result, no_timeout) = match res {
                 Ok((new_guard, no_timeout)) => (Ok(new_guard), no_timeout),
                 Err(err) => {
                     let (new_guard, no_timeout) = err.into_inner();
@@ -350,6 +361,7 @@ mod tests {
     use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
     use thread;
     use time::Duration;
+    use u32;
 
     #[test]
     fn smoke() {
@@ -418,19 +430,19 @@ mod tests {
     }
 
     #[test]
-    fn wait_timeout() {
+    fn wait_timeout_ms() {
         static C: StaticCondvar = CONDVAR_INIT;
         static M: StaticMutex = MUTEX_INIT;
 
         let g = M.lock().unwrap();
-        let (g, _no_timeout) = C.wait_timeout(g, Duration::nanoseconds(1000)).unwrap();
+        let (g, _no_timeout) = C.wait_timeout_ms(g, 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(g, Duration::days(1)).unwrap();
+        let (g, no_timeout) = C.wait_timeout_ms(g, u32::MAX).unwrap();
         assert!(no_timeout);
         drop(g);
         unsafe { C.destroy(); M.destroy(); }
diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs
index b2afe28fed4..2cdde1aca9e 100644
--- a/src/libstd/sync/future.rs
+++ b/src/libstd/sync/future.rs
@@ -36,6 +36,7 @@
 use core::prelude::*;
 use core::mem::replace;
 
+use boxed::Box;
 use self::FutureState::*;
 use sync::mpsc::{Receiver, channel};
 use thunk::Thunk;
@@ -84,7 +85,7 @@ impl<A> Future<A> {
                 match replace(&mut self.state, Evaluating) {
                     Forced(_) | Evaluating => panic!("Logic error."),
                     Pending(f) => {
-                        self.state = Forced(f.invoke(()));
+                        self.state = Forced(f());
                         self.get_ref()
                     }
                 }
@@ -114,7 +115,7 @@ impl<A> Future<A> {
          * function. It is not spawned into another task.
          */
 
-        Future {state: Pending(Thunk::new(f))}
+        Future {state: Pending(Box::new(f))}
     }
 }
 
diff --git a/src/libstd/sys/common/thread.rs b/src/libstd/sys/common/thread.rs
index f45daea18a2..1845b6266ed 100644
--- a/src/libstd/sys/common/thread.rs
+++ b/src/libstd/sys/common/thread.rs
@@ -25,6 +25,7 @@ pub fn start_thread(main: *mut libc::c_void) {
     unsafe {
         stack::record_os_managed_stack_bounds(0, usize::MAX);
         let _handler = stack_overflow::Handler::new();
-        Box::from_raw(main as *mut Thunk).invoke(());
+        let main: Box<Thunk> = Box::from_raw(main as *mut Thunk);
+        main();
     }
 }
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 7b13e951b9b..d2220bdec32 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -409,7 +409,7 @@ pub fn env() -> Env {
     };
 
     fn parse(input: &[u8]) -> (OsString, OsString) {
-        let mut it = input.splitn(1, |b| *b == b'=');
+        let mut it = input.splitn(2, |b| *b == b'=');
         let key = it.next().unwrap().to_vec();
         let default: &[u8] = &[];
         let val = it.next().unwrap_or(default).to_vec();
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 1202b353317..5fe6e80d6e9 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -257,7 +257,7 @@ impl Builder {
     pub fn spawn<F>(self, f: F) -> io::Result<JoinHandle> where
         F: FnOnce(), F: Send + 'static
     {
-        self.spawn_inner(Thunk::new(f)).map(|i| JoinHandle(i))
+        self.spawn_inner(Box::new(f)).map(|i| JoinHandle(i))
     }
 
     /// Spawn a new child thread that must be joined within a given
@@ -279,7 +279,7 @@ impl Builder {
     pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where
         T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
     {
-        self.spawn_inner(Thunk::new(f)).map(|inner| {
+        self.spawn_inner(Box::new(f)).map(|inner| {
             JoinGuard { inner: inner, _marker: PhantomData }
         })
     }
@@ -315,7 +315,7 @@ impl Builder {
                 thread_info::set(imp::guard::current(), their_thread);
             }
 
-            let mut output = None;
+            let mut output: Option<T> = None;
             let try_result = {
                 let ptr = &mut output;
 
@@ -327,7 +327,11 @@ impl Builder {
                 // 'unwinding' flag in the thread itself. For these reasons,
                 // this unsafety should be ok.
                 unsafe {
-                    unwind::try(move || *ptr = Some(f.invoke(())))
+                    unwind::try(move || {
+                        let f: Thunk<(), T> = f;
+                        let v: T = f();
+                        *ptr = Some(v)
+                    })
                 }
             };
             unsafe {
@@ -340,7 +344,7 @@ impl Builder {
         };
 
         Ok(JoinInner {
-            native: try!(unsafe { imp::create(stack_size, Thunk::new(main)) }),
+            native: try!(unsafe { imp::create(stack_size, Box::new(main)) }),
             thread: my_thread,
             packet: my_packet,
             joined: false,
@@ -465,9 +469,16 @@ pub fn catch_panic<F, R>(f: F) -> Result<R>
 /// specifics or platform-dependent functionality. Note that on unix platforms
 /// this function will not return early due to a signal being received or a
 /// spurious wakeup.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn sleep_ms(ms: u32) {
+    imp::sleep(Duration::milliseconds(ms as i64))
+}
+
+/// Deprecated: use `sleep_ms` instead.
 #[unstable(feature = "thread_sleep",
            reason = "recently added, needs an RFC, and `Duration` itself is \
                      unstable")]
+#[deprecated(since = "1.0.0", reason = "use sleep_ms instead")]
 pub fn sleep(dur: Duration) {
     imp::sleep(dur)
 }
@@ -501,17 +512,24 @@ pub fn park() {
 /// amount of time waited to be precisely *duration* long.
 ///
 /// See the module doc for more detail.
-#[unstable(feature = "std_misc", reason = "recently introduced, depends on Duration")]
-pub fn park_timeout(duration: Duration) {
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn park_timeout_ms(ms: u32) {
     let thread = current();
     let mut guard = thread.inner.lock.lock().unwrap();
     if !*guard {
-        let (g, _) = thread.inner.cvar.wait_timeout(guard, duration).unwrap();
+        let (g, _) = thread.inner.cvar.wait_timeout_ms(guard, ms).unwrap();
         guard = g;
     }
     *guard = false;
 }
 
+/// Deprecated: use `park_timeout_ms`
+#[unstable(feature = "std_misc", reason = "recently introduced, depends on Duration")]
+#[deprecated(since = "1.0.0", reason = "use park_timeout_ms instead")]
+pub fn park_timeout(duration: Duration) {
+    park_timeout_ms(duration.num_milliseconds() as u32)
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Thread
 ////////////////////////////////////////////////////////////////////////////////
@@ -716,6 +734,7 @@ mod test {
     use thread;
     use thunk::Thunk;
     use time::Duration;
+    use u32;
 
     // !!! These tests are dangerous. If something is buggy, they will hang, !!!
     // !!! instead of exiting cleanly. This might wedge the buildbots.       !!!
@@ -820,7 +839,7 @@ mod test {
         let x: Box<_> = box 1;
         let x_in_parent = (&*x) as *const i32 as usize;
 
-        spawnfn(Thunk::new(move|| {
+        spawnfn(Box::new(move|| {
             let x_in_child = (&*x) as *const i32 as usize;
             tx.send(x_in_child).unwrap();
         }));
@@ -832,7 +851,7 @@ mod test {
     #[test]
     fn test_avoid_copying_the_body_spawn() {
         avoid_copying_the_body(|v| {
-            thread::spawn(move || v.invoke(()));
+            thread::spawn(move || v());
         });
     }
 
@@ -840,7 +859,7 @@ mod test {
     fn test_avoid_copying_the_body_thread_spawn() {
         avoid_copying_the_body(|f| {
             thread::spawn(move|| {
-                f.invoke(());
+                f();
             });
         })
     }
@@ -849,7 +868,7 @@ mod test {
     fn test_avoid_copying_the_body_join() {
         avoid_copying_the_body(|f| {
             let _ = thread::spawn(move|| {
-                f.invoke(())
+                f()
             }).join();
         })
     }
@@ -862,13 +881,13 @@ mod test {
         // valgrind-friendly. try this at home, instead..!)
         const GENERATIONS: u32 = 16;
         fn child_no(x: u32) -> Thunk<'static> {
-            return Thunk::new(move|| {
+            return Box::new(move|| {
                 if x < GENERATIONS {
-                    thread::spawn(move|| child_no(x+1).invoke(()));
+                    thread::spawn(move|| child_no(x+1)());
                 }
             });
         }
-        thread::spawn(|| child_no(0).invoke(()));
+        thread::spawn(|| child_no(0)());
     }
 
     #[test]
@@ -936,14 +955,14 @@ mod test {
     fn test_park_timeout_unpark_before() {
         for _ in 0..10 {
             thread::current().unpark();
-            thread::park_timeout(Duration::seconds(10_000_000));
+            thread::park_timeout_ms(u32::MAX);
         }
     }
 
     #[test]
     fn test_park_timeout_unpark_not_called() {
         for _ in 0..10 {
-            thread::park_timeout(Duration::milliseconds(10));
+            thread::park_timeout_ms(10);
         }
     }
 
@@ -959,14 +978,13 @@ mod test {
                 th.unpark();
             });
 
-            thread::park_timeout(Duration::seconds(10_000_000));
+            thread::park_timeout_ms(u32::MAX);
         }
     }
 
     #[test]
-    fn sleep_smoke() {
-        thread::sleep(Duration::milliseconds(2));
-        thread::sleep(Duration::milliseconds(-2));
+    fn sleep_ms_smoke() {
+        thread::sleep_ms(2);
     }
 
     // NOTE: the corresponding test for stderr is in run-pass/task-stderr, due
diff --git a/src/libstd/thunk.rs b/src/libstd/thunk.rs
index a9cb05b368f..6091794ed42 100644
--- a/src/libstd/thunk.rs
+++ b/src/libstd/thunk.rs
@@ -12,45 +12,9 @@
 #![allow(missing_docs)]
 #![unstable(feature = "std_misc")]
 
-use alloc::boxed::Box;
+use alloc::boxed::{Box, FnBox};
 use core::marker::Send;
-use core::ops::FnOnce;
 
-pub struct Thunk<'a, A=(),R=()> {
-    invoke: Box<Invoke<A,R>+Send + 'a>,
-}
+pub type Thunk<'a, A=(), R=()> =
+    Box<FnBox<A,Output=R> + Send + 'a>;
 
-impl<'a, R> Thunk<'a,(),R> {
-    pub fn new<F>(func: F) -> Thunk<'a,(),R>
-        where F : FnOnce() -> R, F : Send + 'a
-    {
-        Thunk::with_arg(move|()| func())
-    }
-}
-
-impl<'a,A,R> Thunk<'a,A,R> {
-    pub fn with_arg<F>(func: F) -> Thunk<'a,A,R>
-        where F : FnOnce(A) -> R, F : Send + 'a
-    {
-        Thunk {
-            invoke: Box::<F>::new(func)
-        }
-    }
-
-    pub fn invoke(self, arg: A) -> R {
-        self.invoke.invoke(arg)
-    }
-}
-
-pub trait Invoke<A=(),R=()> {
-    fn invoke(self: Box<Self>, arg: A) -> R;
-}
-
-impl<A,R,F> Invoke<A,R> for F
-    where F : FnOnce(A) -> R
-{
-    fn invoke(self: Box<F>, arg: A) -> R {
-        let f = *self;
-        f(arg)
-    }
-}