about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-20 15:45:07 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-20 22:36:13 -0800
commit3cb9fa26ef9905c00a29ea577fb55a12a91c8e7b (patch)
treea1091c2dd4d5fc6d09be609ffc106295797a6e0a /src/libstd
parent29bd9a06efd2f8c8a7b1102e2203cc0e6ae2dcba (diff)
downloadrust-3cb9fa26ef9905c00a29ea577fb55a12a91c8e7b.tar.gz
rust-3cb9fa26ef9905c00a29ea577fb55a12a91c8e7b.zip
std: Rename Show/String to Debug/Display
This commit is an implementation of [RFC 565][rfc] which is a stabilization of
the `std::fmt` module and the implementations of various formatting traits.
Specifically, the following changes were performed:

[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md

* The `Show` trait is now deprecated, it was renamed to `Debug`
* The `String` trait is now deprecated, it was renamed to `Display`
* Many `Debug` and `Display` implementations were audited in accordance with the
  RFC and audited implementations now have the `#[stable]` attribute
  * Integers and floats no longer print a suffix
  * Smart pointers no longer print details that they are a smart pointer
  * Paths with `Debug` are now quoted and escape characters
* The `unwrap` methods on `Result` now require `Display` instead of `Debug`
* The `Error` trait no longer has a `detail` method and now requires that
  `Display` must be implemented. With the loss of `String`, this has moved into
  libcore.
* `impl<E: Error> FromError<E> for Box<Error>` now exists
* `derive(Show)` has been renamed to `derive(Debug)`. This is not currently
  warned about due to warnings being emitted on stage1+

While backwards compatibility is attempted to be maintained with a blanket
implementation of `Display` for the old `String` trait (and the same for
`Show`/`Debug`) this is still a breaking change due to primitives no longer
implementing `String` as well as modifications such as `unwrap` and the `Error`
trait. Most code is fairly straightforward to update with a rename or tweaks of
method calls.

[breaking-change]
Closes #21436
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/collections/hash/map.rs12
-rw-r--r--src/libstd/collections/hash/set.rs10
-rw-r--r--src/libstd/error.rs137
-rw-r--r--src/libstd/ffi/c_str.rs9
-rw-r--r--src/libstd/fmt.rs27
-rw-r--r--src/libstd/io/buffered.rs12
-rw-r--r--src/libstd/io/fs.rs50
-rw-r--r--src/libstd/io/mem.rs4
-rw-r--r--src/libstd/io/mod.rs32
-rw-r--r--src/libstd/io/net/ip.rs6
-rw-r--r--src/libstd/io/process.rs15
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/num/mod.rs4
-rw-r--r--src/libstd/os.rs12
-rw-r--r--src/libstd/path/mod.rs8
-rw-r--r--src/libstd/path/posix.rs5
-rw-r--r--src/libstd/path/windows.rs5
-rw-r--r--src/libstd/sync/mpsc/mod.rs20
-rw-r--r--src/libstd/sync/poison.rs8
-rw-r--r--src/libstd/thread.rs12
-rw-r--r--src/libstd/time/duration.rs3
21 files changed, 127 insertions, 266 deletions
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index d3ac632617d..0f1da8c5d3a 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -18,7 +18,7 @@ use borrow::BorrowFrom;
 use clone::Clone;
 use cmp::{max, Eq, PartialEq};
 use default::Default;
-use fmt::{self, Show};
+use fmt::{self, Debug};
 use hash::{self, Hash, SipHasher};
 use iter::{self, Iterator, ExactSizeIterator, IteratorExt, FromIterator, Extend, Map};
 use marker::Sized;
@@ -270,7 +270,7 @@ fn test_resize_policy() {
 /// ```
 /// use std::collections::HashMap;
 ///
-/// #[derive(Hash, Eq, PartialEq, Show)]
+/// #[derive(Hash, Eq, PartialEq, Debug)]
 /// struct Viking {
 ///     name: String,
 ///     country: String,
@@ -1216,8 +1216,8 @@ impl<K, V, S, H> Eq for HashMap<K, V, S>
 {}
 
 #[stable]
-impl<K, V, S, H> Show for HashMap<K, V, S>
-    where K: Eq + Hash<H> + Show, V: Show,
+impl<K, V, S, H> Debug for HashMap<K, V, S>
+    where K: Eq + Hash<H> + Debug, V: Debug,
           S: HashState<Hasher=H>,
           H: hash::Hasher<Output=u64>
 {
@@ -1996,8 +1996,8 @@ mod test_map {
 
         let map_str = format!("{:?}", map);
 
-        assert!(map_str == "HashMap {1i: 2i, 3i: 4i}" ||
-                map_str == "HashMap {3i: 4i, 1i: 2i}");
+        assert!(map_str == "HashMap {1: 2, 3: 4}" ||
+                map_str == "HashMap {3: 4, 1: 2}");
         assert_eq!(format!("{:?}", empty), "HashMap {}");
     }
 
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 1293f45161d..29e247d96d2 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -15,7 +15,7 @@ use clone::Clone;
 use cmp::{Eq, PartialEq};
 use core::marker::Sized;
 use default::Default;
-use fmt::Show;
+use fmt::Debug;
 use fmt;
 use hash::{self, Hash};
 use iter::{Iterator, ExactSizeIterator, IteratorExt, FromIterator, Map, Chain, Extend};
@@ -71,7 +71,7 @@ use super::state::HashState;
 ///
 /// ```
 /// use std::collections::HashSet;
-/// #[derive(Hash, Eq, PartialEq, Show)]
+/// #[derive(Hash, Eq, PartialEq, Debug)]
 /// struct Viking<'a> {
 ///     name: &'a str,
 ///     power: uint,
@@ -596,8 +596,8 @@ impl<T, S, H> Eq for HashSet<T, S>
 {}
 
 #[stable]
-impl<T, S, H> fmt::Show for HashSet<T, S>
-    where T: Eq + Hash<H> + fmt::Show,
+impl<T, S, H> fmt::Debug for HashSet<T, S>
+    where T: Eq + Hash<H> + fmt::Debug,
           S: HashState<Hasher=H>,
           H: hash::Hasher<Output=u64>
 {
@@ -1179,7 +1179,7 @@ mod test_set {
 
         let set_str = format!("{:?}", set);
 
-        assert!(set_str == "HashSet {1i, 2i}" || set_str == "HashSet {2i, 1i}");
+        assert!(set_str == "HashSet {1, 2}" || set_str == "HashSet {2, 1}");
         assert_eq!(format!("{:?}", empty), "HashSet {}");
     }
 
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
deleted file mode 100644
index ff128461978..00000000000
--- a/src/libstd/error.rs
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! 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 and cause
-//! chain information:
-//!
-//! ```
-//! trait Error {
-//!     fn description(&self) -> &str;
-//!
-//!     fn detail(&self) -> Option<String> { None }
-//!     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.
-//!
-//! # The `FromError` trait
-//!
-//! `FromError` is a simple trait that expresses conversions between different
-//! error types. To provide maximum flexibility, it does not require either of
-//! the types to actually implement the `Error` trait, although this will be the
-//! common case.
-//!
-//! The main use of this trait is in the `try!` macro, which uses it to
-//! automatically convert a given error to the error specified in a function's
-//! return type.
-//!
-//! For example,
-//!
-//! ```
-//! use std::error::FromError;
-//! use std::io::{File, IoError};
-//! use std::os::{MemoryMap, MapError};
-//! use std::path::Path;
-//!
-//! enum MyError {
-//!     Io(IoError),
-//!     Map(MapError)
-//! }
-//!
-//! impl FromError<IoError> for MyError {
-//!     fn from_error(err: IoError) -> MyError {
-//!         MyError::Io(err)
-//!     }
-//! }
-//!
-//! impl FromError<MapError> for MyError {
-//!     fn from_error(err: MapError) -> MyError {
-//!         MyError::Map(err)
-//!     }
-//! }
-//!
-//! #[allow(unused_variables)]
-//! fn open_and_map() -> Result<(), MyError> {
-//!     let f = try!(File::open(&Path::new("foo.txt")));
-//!     let m = try!(MemoryMap::new(0, &[]));
-//!     // do something interesting here...
-//!     Ok(())
-//! }
-//! ```
-
-#![stable]
-
-use prelude::v1::*;
-
-use str::Utf8Error;
-use string::{FromUtf8Error, FromUtf16Error};
-
-/// Base functionality for all errors in Rust.
-#[unstable = "the exact API of this trait may change"]
-pub trait Error {
-    /// A short description of the error; usually a static string.
-    fn description(&self) -> &str;
-
-    /// A detailed description of the error, usually including dynamic information.
-    fn detail(&self) -> Option<String> { None }
-
-    /// The lower-level cause of this error, if any.
-    fn cause(&self) -> Option<&Error> { None }
-}
-
-/// A trait for types that can be converted from a given error type `E`.
-#[stable]
-pub trait FromError<E> {
-    /// Perform the conversion.
-    fn from_error(err: E) -> Self;
-}
-
-// Any type is convertable from itself
-#[stable]
-impl<E> FromError<E> for E {
-    fn from_error(err: E) -> E {
-        err
-    }
-}
-
-#[stable]
-impl Error for Utf8Error {
-    fn description(&self) -> &str {
-        match *self {
-            Utf8Error::TooShort => "invalid utf-8: not enough bytes",
-            Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
-        }
-    }
-
-    fn detail(&self) -> Option<String> { Some(self.to_string()) }
-}
-
-#[stable]
-impl Error for FromUtf8Error {
-    fn description(&self) -> &str { "invalid utf-8" }
-    fn detail(&self) -> Option<String> { Some(self.to_string()) }
-}
-
-#[stable]
-impl Error for FromUtf16Error {
-    fn description(&self) -> &str { "invalid utf-16" }
-}
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index d7f8eb2e415..b7f4b070591 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -119,7 +119,8 @@ impl Deref for CString {
     }
 }
 
-impl fmt::Show for CString {
+#[stable]
+impl fmt::Debug for CString {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         String::from_utf8_lossy(self.as_bytes()).fmt(f)
     }
@@ -215,4 +216,10 @@ mod tests {
             assert_eq!(s.as_bytes(), b"\0");
         }
     }
+
+    #[test]
+    fn formatted() {
+        let s = CString::from_slice(b"12");
+        assert_eq!(format!("{:?}", s), "\"12\"");
+    }
 }
diff --git a/src/libstd/fmt.rs b/src/libstd/fmt.rs
index 88fb983361a..f3b159cf819 100644
--- a/src/libstd/fmt.rs
+++ b/src/libstd/fmt.rs
@@ -123,8 +123,8 @@
 //! This allows multiple actual types to be formatted via `{:x}` (like `i8` as
 //! well as `int`).  The current mapping of types to traits is:
 //!
-//! * *nothing* ⇒ `String`
-//! * `?` ⇒ `Show`
+//! * *nothing* ⇒ `Display`
+//! * `?` ⇒ `Debug`
 //! * `o` ⇒ `Octal`
 //! * `x` ⇒ `LowerHex`
 //! * `X` ⇒ `UpperHex`
@@ -137,7 +137,7 @@
 //! `std::fmt::Binary` trait can then be formatted with `{:b}`. Implementations
 //! are provided for these traits for a number of primitive types by the
 //! standard library as well. If no format is specified (as in `{}` or `{:6}`),
-//! then the format trait used is the `String` trait.
+//! then the format trait used is the `Display` trait.
 //!
 //! When implementing a format trait for your own type, you will have to
 //! implement a method of the signature:
@@ -145,7 +145,7 @@
 //! ```rust
 //! # use std::fmt;
 //! # struct Foo; // our custom type
-//! # impl fmt::Show for Foo {
+//! # impl fmt::Display for Foo {
 //! fn fmt(&self, f: &mut std::fmt::Formatter) -> fmt::Result {
 //! # write!(f, "testing, testing")
 //! # } }
@@ -171,13 +171,13 @@
 //! use std::f64;
 //! use std::num::Float;
 //!
-//! #[derive(Show)]
+//! #[derive(Debug)]
 //! struct Vector2D {
 //!     x: int,
 //!     y: int,
 //! }
 //!
-//! impl fmt::String for Vector2D {
+//! impl fmt::Display for Vector2D {
 //!     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 //!         // The `f` value implements the `Writer` trait, which is what the
 //!         // write! macro is expecting. Note that this formatting ignores the
@@ -211,22 +211,22 @@
 //! }
 //! ```
 //!
-//! #### fmt::String vs fmt::Show
+//! #### fmt::Display vs fmt::Debug
 //!
 //! These two formatting traits have distinct purposes:
 //!
-//! - `fmt::String` implementations assert that the type can be faithfully
+//! - `fmt::Display` implementations assert that the type can be faithfully
 //!   represented as a UTF-8 string at all times. It is **not** expected that
-//!   all types implement the `String` trait.
-//! - `fmt::Show` implementations should be implemented for **all** public types.
+//!   all types implement the `Display` trait.
+//! - `fmt::Debug` implementations should be implemented for **all** public types.
 //!   Output will typically represent the internal state as faithfully as possible.
-//!   The purpose of the `Show` trait is to facilitate debugging Rust code. In
-//!   most cases, using `#[derive(Show)]` is sufficient and recommended.
+//!   The purpose of the `Debug` trait is to facilitate debugging Rust code. In
+//!   most cases, using `#[derive(Debug)]` is sufficient and recommended.
 //!
 //! Some examples of the output from both traits:
 //!
 //! ```
-//! assert_eq!(format!("{} {:?}", 3i32, 4i32), "3 4i32");
+//! assert_eq!(format!("{} {:?}", 3i32, 4i32), "3 4");
 //! assert_eq!(format!("{} {:?}", 'a', 'b'), "a 'b'");
 //! assert_eq!(format!("{} {:?}", "foo\n", "bar\n"), "foo\n \"bar\\n\"");
 //! ```
@@ -409,6 +409,7 @@ use string;
 
 pub use core::fmt::{Formatter, Result, Writer, rt};
 pub use core::fmt::{Show, String, Octal, Binary};
+pub use core::fmt::{Display, Debug};
 pub use core::fmt::{LowerHex, UpperHex, Pointer};
 pub use core::fmt::{LowerExp, UpperExp};
 pub use core::fmt::Error;
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 8c38bc009cc..c1244abbfcb 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -52,7 +52,8 @@ pub struct BufferedReader<R> {
     cap: uint,
 }
 
-impl<R> fmt::Show for BufferedReader<R> where R: fmt::Show {
+#[stable]
+impl<R> fmt::Debug for BufferedReader<R> where R: fmt::Debug {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         write!(fmt, "BufferedReader {{ reader: {:?}, buffer: {}/{} }}",
                self.inner, self.cap - self.pos, self.buf.len())
@@ -150,7 +151,8 @@ pub struct BufferedWriter<W> {
     pos: uint
 }
 
-impl<W> fmt::Show for BufferedWriter<W> where W: fmt::Show {
+#[stable]
+impl<W> fmt::Debug for BufferedWriter<W> where W: fmt::Debug {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         write!(fmt, "BufferedWriter {{ writer: {:?}, buffer: {}/{} }}",
                self.inner.as_ref().unwrap(), self.pos, self.buf.len())
@@ -249,7 +251,8 @@ pub struct LineBufferedWriter<W> {
     inner: BufferedWriter<W>,
 }
 
-impl<W> fmt::Show for LineBufferedWriter<W> where W: fmt::Show {
+#[stable]
+impl<W> fmt::Debug for LineBufferedWriter<W> where W: fmt::Debug {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         write!(fmt, "LineBufferedWriter {{ writer: {:?}, buffer: {}/{} }}",
                self.inner.inner, self.inner.pos, self.inner.buf.len())
@@ -339,7 +342,8 @@ pub struct BufferedStream<S> {
     inner: BufferedReader<InternalBufferedWriter<S>>
 }
 
-impl<S> fmt::Show for BufferedStream<S> where S: fmt::Show {
+#[stable]
+impl<S> fmt::Debug for BufferedStream<S> where S: fmt::Debug {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let reader = &self.inner;
         let writer = &self.inner.inner.0;
diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs
index 64406d88253..cc36c5640d0 100644
--- a/src/libstd/io/fs.rs
+++ b/src/libstd/io/fs.rs
@@ -156,7 +156,7 @@ impl File {
                 })
             }
         }).update_err("couldn't open path as file", |e| {
-            format!("{}; path={:?}; mode={}; access={}", e, path.display(),
+            format!("{}; path={}; mode={}; access={}", e, path.display(),
                 mode_string(mode), access_string(access))
         })
     }
@@ -211,7 +211,7 @@ impl File {
     pub fn fsync(&mut self) -> IoResult<()> {
         self.fd.fsync()
             .update_err("couldn't fsync file",
-                        |e| format!("{}; path={:?}", e, self.path.display()))
+                        |e| format!("{}; path={}", e, self.path.display()))
     }
 
     /// This function is similar to `fsync`, except that it may not synchronize
@@ -221,7 +221,7 @@ impl File {
     pub fn datasync(&mut self) -> IoResult<()> {
         self.fd.datasync()
             .update_err("couldn't datasync file",
-                        |e| format!("{}; path={:?}", e, self.path.display()))
+                        |e| format!("{}; path={}", e, self.path.display()))
     }
 
     /// Either truncates or extends the underlying file, updating the size of
@@ -235,7 +235,7 @@ impl File {
     pub fn truncate(&mut self, size: i64) -> IoResult<()> {
         self.fd.truncate(size)
             .update_err("couldn't truncate file", |e|
-                format!("{}; path={:?}; size={:?}", e, self.path.display(), size))
+                format!("{}; path={}; size={}", e, self.path.display(), size))
     }
 
     /// Returns true if the stream has reached the end of the file.
@@ -255,7 +255,7 @@ impl File {
     pub fn stat(&self) -> IoResult<FileStat> {
         self.fd.fstat()
             .update_err("couldn't fstat file", |e|
-                format!("{}; path={:?}", e, self.path.display()))
+                format!("{}; path={}", e, self.path.display()))
     }
 }
 
@@ -283,7 +283,7 @@ impl File {
 pub fn unlink(path: &Path) -> IoResult<()> {
     fs_imp::unlink(path)
            .update_err("couldn't unlink path", |e|
-               format!("{}; path={:?}", e, path.display()))
+               format!("{}; path={}", e, path.display()))
 }
 
 /// Given a path, query the file system to get information about a file,
@@ -310,7 +310,7 @@ pub fn unlink(path: &Path) -> IoResult<()> {
 pub fn stat(path: &Path) -> IoResult<FileStat> {
     fs_imp::stat(path)
            .update_err("couldn't stat path", |e|
-               format!("{}; path={:?}", e, path.display()))
+               format!("{}; path={}", e, path.display()))
 }
 
 /// Perform the same operation as the `stat` function, except that this
@@ -324,7 +324,7 @@ pub fn stat(path: &Path) -> IoResult<FileStat> {
 pub fn lstat(path: &Path) -> IoResult<FileStat> {
     fs_imp::lstat(path)
            .update_err("couldn't lstat path", |e|
-               format!("{}; path={:?}", e, path.display()))
+               format!("{}; path={}", e, path.display()))
 }
 
 /// Rename a file or directory to a new name.
@@ -424,14 +424,14 @@ pub fn copy(from: &Path, to: &Path) -> IoResult<()> {
 pub fn chmod(path: &Path, mode: io::FilePermission) -> IoResult<()> {
     fs_imp::chmod(path, mode.bits() as uint)
            .update_err("couldn't chmod path", |e|
-               format!("{}; path={:?}; mode={:?}", e, path.display(), mode))
+               format!("{}; path={}; mode={:?}", e, path.display(), mode))
 }
 
 /// Change the user and group owners of a file at the specified path.
 pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> {
     fs_imp::chown(path, uid, gid)
            .update_err("couldn't chown path", |e|
-               format!("{}; path={:?}; uid={}; gid={}", e, path.display(), uid, gid))
+               format!("{}; path={}; uid={}; gid={}", e, path.display(), uid, gid))
 }
 
 /// Creates a new hard link on the filesystem. The `dst` path will be a
@@ -460,7 +460,7 @@ pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
 pub fn readlink(path: &Path) -> IoResult<Path> {
     fs_imp::readlink(path)
            .update_err("couldn't resolve symlink for path", |e|
-               format!("{}; path={:?}", e, path.display()))
+               format!("{}; path={}", e, path.display()))
 }
 
 /// Create a new, empty directory at the provided path
@@ -483,7 +483,7 @@ pub fn readlink(path: &Path) -> IoResult<Path> {
 pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> {
     fs_imp::mkdir(path, mode.bits() as uint)
            .update_err("couldn't create directory", |e|
-               format!("{}; path={:?}; mode={:?}", e, path.display(), mode))
+               format!("{}; path={}; mode={}", e, path.display(), mode))
 }
 
 /// Remove an existing, empty directory
@@ -505,7 +505,7 @@ pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> {
 pub fn rmdir(path: &Path) -> IoResult<()> {
     fs_imp::rmdir(path)
            .update_err("couldn't remove directory", |e|
-               format!("{}; path={:?}", e, path.display()))
+               format!("{}; path={}", e, path.display()))
 }
 
 /// Retrieve a vector containing all entries within a provided directory
@@ -545,7 +545,7 @@ pub fn rmdir(path: &Path) -> IoResult<()> {
 pub fn readdir(path: &Path) -> IoResult<Vec<Path>> {
     fs_imp::readdir(path)
            .update_err("couldn't read directory",
-                       |e| format!("{}; path={:?}", e, path.display()))
+                       |e| format!("{}; path={}", e, path.display()))
 }
 
 /// Returns an iterator that will recursively walk the directory structure
@@ -555,7 +555,7 @@ pub fn readdir(path: &Path) -> IoResult<Vec<Path>> {
 pub fn walk_dir(path: &Path) -> IoResult<Directories> {
     Ok(Directories {
         stack: try!(readdir(path).update_err("couldn't walk directory",
-                                             |e| format!("{}; path={:?}", e, path.display())))
+                                             |e| format!("{}; path={}", e, path.display())))
     })
 }
 
@@ -605,7 +605,7 @@ pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> {
 
         let result = mkdir(&curpath, mode)
             .update_err("couldn't recursively mkdir",
-                        |e| format!("{}; path={:?}", e, path.display()));
+                        |e| format!("{}; path={}", e, path.display()));
 
         match result {
             Err(mkdir_err) => {
@@ -632,7 +632,7 @@ pub fn rmdir_recursive(path: &Path) -> IoResult<()> {
     rm_stack.push(path.clone());
 
     fn rmdir_failed(err: &IoError, path: &Path) -> String {
-        format!("rmdir_recursive failed; path={:?}; cause={}",
+        format!("rmdir_recursive failed; path={}; cause={}",
                 path.display(), err)
     }
 
@@ -692,14 +692,14 @@ pub fn rmdir_recursive(path: &Path) -> IoResult<()> {
 pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> {
     fs_imp::utime(path, atime, mtime)
            .update_err("couldn't change_file_times", |e|
-               format!("{}; path={:?}", e, path.display()))
+               format!("{}; path={}", e, path.display()))
 }
 
 impl Reader for File {
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         fn update_err<T>(result: IoResult<T>, file: &File) -> IoResult<T> {
             result.update_err("couldn't read file",
-                              |e| format!("{}; path={:?}",
+                              |e| format!("{}; path={}",
                                           e, file.path.display()))
         }
 
@@ -722,7 +722,7 @@ impl Writer for File {
     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         self.fd.write(buf)
             .update_err("couldn't write to file",
-                        |e| format!("{}; path={:?}", e, self.path.display()))
+                        |e| format!("{}; path={}", e, self.path.display()))
     }
 }
 
@@ -730,7 +730,7 @@ impl Seek for File {
     fn tell(&self) -> IoResult<u64> {
         self.fd.tell()
             .update_err("couldn't retrieve file cursor (`tell`)",
-                        |e| format!("{}; path={:?}", e, self.path.display()))
+                        |e| format!("{}; path={}", e, self.path.display()))
     }
 
     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
@@ -743,7 +743,7 @@ impl Seek for File {
             Err(e) => Err(e),
         };
         err.update_err("couldn't seek in file",
-                       |e| format!("{}; path={:?}", e, self.path.display()))
+                       |e| format!("{}; path={}", e, self.path.display()))
     }
 }
 
@@ -906,7 +906,7 @@ mod test {
         if cfg!(unix) {
             error!(result, "no such file or directory");
         }
-        error!(result, format!("path={:?}; mode=open; access=read", filename.display()));
+        error!(result, format!("path={}; mode=open; access=read", filename.display()));
     }
 
     #[test]
@@ -920,7 +920,7 @@ mod test {
         if cfg!(unix) {
             error!(result, "no such file or directory");
         }
-        error!(result, format!("path={:?}", filename.display()));
+        error!(result, format!("path={}", filename.display()));
     }
 
     #[test]
@@ -1188,7 +1188,7 @@ mod test {
         error!(result, "couldn't recursively mkdir");
         error!(result, "couldn't create directory");
         error!(result, "mode=0700");
-        error!(result, format!("path={:?}", file.display()));
+        error!(result, format!("path={}", file.display()));
     }
 
     #[test]
diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs
index ee05a9e5596..e281bd3d7e8 100644
--- a/src/libstd/io/mem.rs
+++ b/src/libstd/io/mem.rs
@@ -432,8 +432,8 @@ mod test {
             writer.write(&[]).unwrap();
             assert_eq!(writer.tell(), Ok(8));
 
-            assert_eq!(writer.write(&[8, 9]).unwrap_err().kind, io::ShortWrite(1));
-            assert_eq!(writer.write(&[10]).unwrap_err().kind, io::EndOfFile);
+            assert_eq!(writer.write(&[8, 9]).err().unwrap().kind, io::ShortWrite(1));
+            assert_eq!(writer.write(&[10]).err().unwrap().kind, io::EndOfFile);
         }
         let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
         assert_eq!(buf, b);
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index dc21416df7b..bc86511165e 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -228,13 +228,12 @@ pub use self::FileAccess::*;
 pub use self::IoErrorKind::*;
 
 use char::CharExt;
-use clone::Clone;
 use default::Default;
-use error::{FromError, Error};
+use error::Error;
 use fmt;
 use int;
 use iter::{Iterator, IteratorExt};
-use marker::{Sized, Send};
+use marker::Sized;
 use mem::transmute;
 use ops::FnOnce;
 use option::Option;
@@ -340,7 +339,8 @@ impl IoError {
     }
 }
 
-impl fmt::String for IoError {
+#[stable]
+impl fmt::Display for IoError {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             IoError { kind: OtherIoError, desc: "unknown error", detail: Some(ref detail) } =>
@@ -354,19 +354,7 @@ impl fmt::String for IoError {
 }
 
 impl Error for IoError {
-    fn description(&self) -> &str {
-        self.desc
-    }
-
-    fn detail(&self) -> Option<String> {
-        self.detail.clone()
-    }
-}
-
-impl FromError<IoError> for Box<Error + Send> {
-    fn from_error(err: IoError) -> Box<Error + Send> {
-        box err
-    }
+    fn description(&self) -> &str { self.desc }
 }
 
 /// A list specifying general categories of I/O error.
@@ -1781,6 +1769,7 @@ pub struct UnstableFileStat {
 bitflags! {
     /// A set of permissions for a file or directory is represented by a set of
     /// flags which are or'd together.
+    #[derive(Show)]
     flags FilePermission: u32 {
         const USER_READ     = 0o400,
         const USER_WRITE    = 0o200,
@@ -1822,13 +1811,8 @@ impl Default for FilePermission {
     fn default() -> FilePermission { FilePermission::empty() }
 }
 
-impl fmt::Show for FilePermission {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::String::fmt(self, f)
-    }
-}
-
-impl fmt::String for FilePermission {
+#[stable]
+impl fmt::Display for FilePermission {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{:04o}", self.bits)
     }
diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs
index adc122ff447..e8e065533e5 100644
--- a/src/libstd/io/net/ip.rs
+++ b/src/libstd/io/net/ip.rs
@@ -38,7 +38,8 @@ pub enum IpAddr {
     Ipv6Addr(u16, u16, u16, u16, u16, u16, u16, u16)
 }
 
-impl fmt::String for IpAddr {
+#[stable]
+impl fmt::Display for IpAddr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             Ipv4Addr(a, b, c, d) =>
@@ -69,7 +70,8 @@ pub struct SocketAddr {
     pub port: Port,
 }
 
-impl fmt::String for SocketAddr {
+#[stable]
+impl fmt::Display for SocketAddr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self.ip {
             Ipv4Addr(..) => write!(f, "{}:{}", self.ip, self.port),
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index 43ca7b13145..7b0a86777f6 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -397,7 +397,7 @@ impl Command {
     }
 }
 
-impl fmt::String for Command {
+impl fmt::Debug for Command {
     /// Format the program and arguments of a Command for display. Any
     /// non-utf8 data is lossily converted using the utf8 replacement
     /// character.
@@ -496,7 +496,7 @@ pub enum StdioContainer {
 
 /// Describes the result of a process after it has terminated.
 /// Note that Windows have no signals, so the result is usually ExitStatus.
-#[derive(PartialEq, Eq, Clone, Copy)]
+#[derive(PartialEq, Eq, Clone, Copy, Show)]
 pub enum ProcessExit {
     /// Normal termination with an exit status.
     ExitStatus(int),
@@ -505,15 +505,8 @@ pub enum ProcessExit {
     ExitSignal(int),
 }
 
-impl fmt::Show for ProcessExit {
-    /// Format a ProcessExit enum, to nicely present the information.
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::String::fmt(self, f)
-    }
-}
-
-
-impl fmt::String for ProcessExit {
+#[stable]
+impl fmt::Display for ProcessExit {
     /// Format a ProcessExit enum, to nicely present the information.
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 648326eee99..9bfc15f1438 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -168,6 +168,7 @@ pub use core::raw;
 pub use core::simd;
 pub use core::result;
 pub use core::option;
+pub use core::error;
 
 #[cfg(not(test))] pub use alloc::boxed;
 pub use alloc::rc;
@@ -228,7 +229,6 @@ pub mod thunk;
 
 /* Common traits */
 
-pub mod error;
 pub mod num;
 
 /* Runtime and platform support */
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index 3432767d6cd..9ced1a7e130 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -16,7 +16,7 @@
 #![stable]
 #![allow(missing_docs)]
 
-#[cfg(test)] use fmt::Show;
+#[cfg(test)] use fmt::Debug;
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
 
 use marker::Copy;
@@ -322,7 +322,7 @@ pub fn test_num<T>(ten: T, two: T) where
     T: PartialEq + NumCast
      + Add<Output=T> + Sub<Output=T>
      + Mul<Output=T> + Div<Output=T>
-     + Rem<Output=T> + Show
+     + Rem<Output=T> + Debug
      + Copy
 {
     assert_eq!(ten.add(two),  cast(12i).unwrap());
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 78db6c158a8..985a8cd32e2 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -855,7 +855,7 @@ pub enum MapOption {
 impl Copy for MapOption {}
 
 /// Possible errors when creating a map.
-#[derive(Copy)]
+#[derive(Copy, Show)]
 pub enum MapError {
     /// # The following are POSIX-specific
     ///
@@ -900,7 +900,8 @@ pub enum MapError {
     ErrMapViewOfFile(uint)
 }
 
-impl fmt::Show for MapError {
+#[stable]
+impl fmt::Display for MapError {
     fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
         let str = match *self {
             ErrFdNotAvail => "fd not available for reading or writing",
@@ -934,13 +935,6 @@ impl fmt::Show for MapError {
 
 impl Error for MapError {
     fn description(&self) -> &str { "memory map error" }
-    fn detail(&self) -> Option<String> { Some(format!("{:?}", self)) }
-}
-
-impl FromError<MapError> for Box<Error + Send> {
-    fn from_error(err: MapError) -> Box<Error + Send> {
-        box err
-    }
 }
 
 // Round up `from` to be divisible by `to`
diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs
index 541f1e77140..ba61d7df915 100644
--- a/src/libstd/path/mod.rs
+++ b/src/libstd/path/mod.rs
@@ -823,13 +823,15 @@ pub struct Display<'a, P:'a> {
     filename: bool
 }
 
-impl<'a, P: GenericPath> fmt::Show for Display<'a, P> {
+#[stable]
+impl<'a, P: GenericPath> fmt::Debug for Display<'a, P> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::String::fmt(self, f)
+        fmt::Debug::fmt(&self.as_cow(), f)
     }
 }
 
-impl<'a, P: GenericPath> fmt::String for Display<'a, P> {
+#[stable]
+impl<'a, P: GenericPath> fmt::Display for Display<'a, P> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.as_cow().fmt(f)
     }
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index aab64639ab5..0edc01063cf 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -57,9 +57,10 @@ pub fn is_sep(c: char) -> bool {
     c == SEP
 }
 
-impl fmt::Show for Path {
+#[stable]
+impl fmt::Debug for Path {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Show::fmt(&self.display(), f)
+        fmt::Debug::fmt(&self.display(), f)
     }
 }
 
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index 3cff1c67be3..59a071e8842 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -85,9 +85,10 @@ pub struct Path {
     sepidx: Option<uint> // index of the final separator in the non-prefix portion of repr
 }
 
-impl fmt::Show for Path {
+#[stable]
+impl fmt::Debug for Path {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Show::fmt(&self.display(), f)
+        fmt::Debug::fmt(&self.display(), f)
     }
 }
 
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index 0ba19b70617..db9251131d1 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -393,7 +393,7 @@ impl<T> !marker::Sync for SyncSender<T> {}
 /// A `send` operation can only fail if the receiving end of a channel is
 /// disconnected, implying that the data could never be received. The error
 /// contains the data being sent as a payload so it can be recovered.
-#[derive(PartialEq, Eq)]
+#[derive(PartialEq, Eq, Show)]
 #[stable]
 pub struct SendError<T>(pub T);
 
@@ -401,13 +401,13 @@ pub struct SendError<T>(pub T);
 ///
 /// The `recv` operation can only fail if the sending half of a channel is
 /// disconnected, implying that no further messages will ever be received.
-#[derive(PartialEq, Eq, Clone, Copy)]
+#[derive(PartialEq, Eq, Clone, Copy, Show)]
 #[stable]
 pub struct RecvError;
 
 /// This enumeration is the list of the possible reasons that try_recv could not
 /// return data when called.
-#[derive(PartialEq, Clone, Copy)]
+#[derive(PartialEq, Clone, Copy, Show)]
 #[stable]
 pub enum TryRecvError {
     /// This channel is currently empty, but the sender(s) have not yet
@@ -423,7 +423,7 @@ pub enum TryRecvError {
 
 /// This enumeration is the list of the possible error outcomes for the
 /// `SyncSender::try_send` method.
-#[derive(PartialEq, Clone)]
+#[derive(PartialEq, Clone, Show)]
 #[stable]
 pub enum TrySendError<T> {
     /// The data could not be sent on the channel because it would require that
@@ -998,13 +998,15 @@ unsafe impl<T:Send> Send for RacyCell<T> { }
 
 unsafe impl<T> Sync for RacyCell<T> { } // Oh dear
 
-impl<T> fmt::Show for SendError<T> {
+#[stable]
+impl<T> fmt::Display for SendError<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         "sending on a closed channel".fmt(f)
     }
 }
 
-impl<T> fmt::Show for TrySendError<T> {
+#[stable]
+impl<T> fmt::Display for TrySendError<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             TrySendError::Full(..) => {
@@ -1017,13 +1019,15 @@ impl<T> fmt::Show for TrySendError<T> {
     }
 }
 
-impl fmt::Show for RecvError {
+#[stable]
+impl fmt::Display for RecvError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         "receiving on a closed channel".fmt(f)
     }
 }
 
-impl fmt::Show for TryRecvError {
+#[stable]
+impl fmt::Display for TryRecvError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             TryRecvError::Empty => {
diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs
index e28c3c37b6f..c97fcf7cefb 100644
--- a/src/libstd/sync/poison.rs
+++ b/src/libstd/sync/poison.rs
@@ -53,6 +53,7 @@ pub struct Guard {
 /// is held. The precise semantics for when a lock is poisoned is documented on
 /// each lock, but once a lock is poisoned then all future acquisitions will
 /// return this error.
+#[derive(Show)]
 #[stable]
 pub struct PoisonError<T> {
     guard: T,
@@ -60,6 +61,7 @@ pub struct PoisonError<T> {
 
 /// An enumeration of possible errors which can occur while calling the
 /// `try_lock` method.
+#[derive(Show)]
 #[stable]
 pub enum TryLockError<T> {
     /// The lock could not be acquired because another task failed while holding
@@ -90,7 +92,8 @@ pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;
 #[stable]
 pub type TryLockResult<Guard> = Result<Guard, TryLockError<Guard>>;
 
-impl<T> fmt::Show for PoisonError<T> {
+#[stable]
+impl<T> fmt::Display for PoisonError<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.description().fmt(f)
     }
@@ -130,7 +133,8 @@ impl<T> FromError<PoisonError<T>> for TryLockError<T> {
     }
 }
 
-impl<T> fmt::Show for TryLockError<T> {
+#[stable]
+impl<T> fmt::Display for TryLockError<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.description().fmt(f)
     }
diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs
index 932556fe1a6..1f181e1fa2a 100644
--- a/src/libstd/thread.rs
+++ b/src/libstd/thread.rs
@@ -519,14 +519,14 @@ mod test {
     fn test_unnamed_thread() {
         Thread::scoped(move|| {
             assert!(Thread::current().name().is_none());
-        }).join().map_err(|_| ()).unwrap();
+        }).join().ok().unwrap();
     }
 
     #[test]
     fn test_named_thread() {
         Builder::new().name("ada lovelace".to_string()).scoped(move|| {
             assert!(Thread::current().name().unwrap() == "ada lovelace".to_string());
-        }).join().map_err(|_| ()).unwrap();
+        }).join().ok().unwrap();
     }
 
     #[test]
@@ -662,7 +662,7 @@ mod test {
             Err(e) => {
                 type T = &'static str;
                 assert!(e.is::<T>());
-                assert_eq!(*e.downcast::<T>().unwrap(), "static string");
+                assert_eq!(*e.downcast::<T>().ok().unwrap(), "static string");
             }
             Ok(()) => panic!()
         }
@@ -676,7 +676,7 @@ mod test {
             Err(e) => {
                 type T = String;
                 assert!(e.is::<T>());
-                assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string());
+                assert_eq!(*e.downcast::<T>().ok().unwrap(), "owned string".to_string());
             }
             Ok(()) => panic!()
         }
@@ -690,9 +690,9 @@ mod test {
             Err(e) => {
                 type T = Box<Any + Send>;
                 assert!(e.is::<T>());
-                let any = e.downcast::<T>().unwrap();
+                let any = e.downcast::<T>().ok().unwrap();
                 assert!(any.is::<u16>());
-                assert_eq!(*any.downcast::<u16>().unwrap(), 413u16);
+                assert_eq!(*any.downcast::<u16>().ok().unwrap(), 413u16);
             }
             Ok(()) => panic!()
         }
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 162c3677168..2d56a8bcddf 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -334,7 +334,8 @@ impl Div<i32> for Duration {
     }
 }
 
-impl fmt::String for Duration {
+#[stable]
+impl fmt::Display for Duration {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         // technically speaking, negative duration is not valid ISO 8601,
         // but we need to print it anyway.