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
This commit is contained in:
Alex Crichton 2015-01-20 15:45:07 -08:00
parent 29bd9a06ef
commit 3cb9fa26ef
136 changed files with 763 additions and 706 deletions

View file

@ -34,11 +34,11 @@
//! use runtime reflection instead.
//!
//! ```rust
//! use std::fmt::Show;
//! use std::fmt::Debug;
//! use std::any::Any;
//!
//! // Logger function for any type that implements Show.
//! fn log<T: Any+Show>(value: &T) {
//! // Logger function for any type that implements Debug.
//! fn log<T: Any + Debug>(value: &T) {
//! let value_any = value as &Any;
//!
//! // try to convert our value to a String. If successful, we want to
@ -55,7 +55,7 @@
//! }
//!
//! // This function wants to log its parameter out prior to doing work with it.
//! fn do_work<T: Show+'static>(value: &T) {
//! fn do_work<T: Debug + 'static>(value: &T) {
//! log(value);
//! // ...do some other work
//! }

View file

@ -39,10 +39,10 @@ macro_rules! array_impls {
}
}
#[unstable = "waiting for Show to stabilize"]
impl<T:fmt::Show> fmt::Show for [T; $N] {
#[stable]
impl<T: fmt::Debug> fmt::Debug for [T; $N] {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Show::fmt(&&self[], f)
fmt::Debug::fmt(&&self[], f)
}
}

View file

@ -133,7 +133,6 @@ impl<T> ToOwned<T> for T where T: Clone {
/// }
/// }
/// ```
#[derive(Show)]
pub enum Cow<'a, T, B: ?Sized + 'a> where B: ToOwned<T> {
/// Borrowed data.
Borrowed(&'a B),
@ -239,14 +238,27 @@ impl<'a, T, B: ?Sized> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwne
}
#[stable]
impl<'a, T, B: ?Sized> fmt::String for Cow<'a, T, B> where
B: fmt::String + ToOwned<T>,
T: fmt::String,
impl<'a, T, B: ?Sized> fmt::Debug for Cow<'a, T, B> where
B: fmt::Debug + ToOwned<T>,
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Borrowed(ref b) => fmt::String::fmt(b, f),
Owned(ref o) => fmt::String::fmt(o, f),
Borrowed(ref b) => fmt::Debug::fmt(b, f),
Owned(ref o) => fmt::Debug::fmt(o, f),
}
}
}
#[stable]
impl<'a, T, B: ?Sized> fmt::Display for Cow<'a, T, B> where
B: fmt::Display + ToOwned<T>,
T: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Borrowed(ref b) => fmt::Display::fmt(b, f),
Owned(ref o) => fmt::Display::fmt(o, f),
}
}
}

110
src/libcore/error.rs Normal file
View file

@ -0,0 +1,110 @@
// 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.
//!
//! # 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::*;
use fmt::Display;
/// Base functionality for all errors in Rust.
#[unstable = "the exact API of this trait may change"]
pub trait Error: Display {
/// A short description of the error; usually a static string.
fn description(&self) -> &str;
/// 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
}
}

View file

@ -26,12 +26,15 @@ use ops::{Deref, FnOnce};
use result;
use slice::SliceExt;
use slice;
use str::{self, StrExt, Utf8Error};
use str::{self, StrExt};
pub use self::num::radix;
pub use self::num::Radix;
pub use self::num::RadixFmt;
#[cfg(stage0)] pub use self::Debug as Show;
#[cfg(stage0)] pub use self::Display as String;
mod num;
mod float;
pub mod rt;
@ -46,7 +49,7 @@ pub type Result = result::Result<(), Error>;
/// occurred. Any extra information must be arranged to be transmitted through
/// some other means.
#[unstable = "core and I/O reconciliation may alter this definition"]
#[derive(Copy)]
#[derive(Copy, Show)]
pub struct Error;
/// A collection of methods that are required to format a message into a stream.
@ -133,7 +136,7 @@ pub struct Argument<'a> {
impl<'a> Argument<'a> {
#[inline(never)]
fn show_uint(x: &uint, f: &mut Formatter) -> Result {
Show::fmt(x, f)
Display::fmt(x, f)
}
fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter) -> Result) -> Argument<'b> {
@ -214,14 +217,15 @@ pub struct Arguments<'a> {
args: &'a [Argument<'a>],
}
impl<'a> Show for Arguments<'a> {
#[stable]
impl<'a> Debug for Arguments<'a> {
fn fmt(&self, fmt: &mut Formatter) -> Result {
String::fmt(self, fmt)
Display::fmt(self, fmt)
}
}
#[stable]
impl<'a> String for Arguments<'a> {
impl<'a> Display for Arguments<'a> {
fn fmt(&self, fmt: &mut Formatter) -> Result {
write(fmt.buf, *self)
}
@ -229,20 +233,49 @@ impl<'a> String for Arguments<'a> {
/// Format trait for the `:?` format. Useful for debugging, most all types
/// should implement this.
#[unstable = "I/O and core have yet to be reconciled"]
#[deprecated = "renamed to Debug"]
#[cfg(not(stage0))]
pub trait Show {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
/// Format trait for the `:?` format. Useful for debugging, most all types
/// should implement this.
#[unstable = "I/O and core have yet to be reconciled"]
pub trait Debug {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
#[cfg(not(stage0))]
impl<T: Show + ?Sized> Debug for T {
#[allow(deprecated)]
fn fmt(&self, f: &mut Formatter) -> Result { Show::fmt(self, f) }
}
/// When a value can be semantically expressed as a String, this trait may be
/// used. It corresponds to the default format, `{}`.
#[deprecated = "renamed to Display"]
#[cfg(not(stage0))]
pub trait String {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
/// When a value can be semantically expressed as a String, this trait may be
/// used. It corresponds to the default format, `{}`.
#[unstable = "I/O and core have yet to be reconciled"]
pub trait String {
pub trait Display {
/// Formats the value using the given formatter.
fn fmt(&self, &mut Formatter) -> Result;
}
#[cfg(not(stage0))]
impl<T: String + ?Sized> Display for T {
#[allow(deprecated)]
fn fmt(&self, f: &mut Formatter) -> Result { String::fmt(self, f) }
}
/// Format trait for the `o` character
#[unstable = "I/O and core have yet to be reconciled"]
@ -583,9 +616,10 @@ impl<'a> Formatter<'a> {
pub fn precision(&self) -> Option<uint> { self.precision }
}
impl Show for Error {
#[stable]
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result {
String::fmt("an error occurred when formatting an argument", f)
Display::fmt("an error occurred when formatting an argument", f)
}
}
@ -611,9 +645,11 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
macro_rules! fmt_refs {
($($tr:ident),*) => {
$(
#[stable]
impl<'a, T: ?Sized + $tr> $tr for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) }
}
#[stable]
impl<'a, T: ?Sized + $tr> $tr for &'a mut T {
fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) }
}
@ -621,22 +657,24 @@ macro_rules! fmt_refs {
}
}
fmt_refs! { Show, String, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp }
fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp }
impl Show for bool {
#[stable]
impl Debug for bool {
fn fmt(&self, f: &mut Formatter) -> Result {
String::fmt(self, f)
Display::fmt(self, f)
}
}
#[stable]
impl String for bool {
impl Display for bool {
fn fmt(&self, f: &mut Formatter) -> Result {
String::fmt(if *self { "true" } else { "false" }, f)
Display::fmt(if *self { "true" } else { "false" }, f)
}
}
impl Show for str {
#[stable]
impl Debug for str {
fn fmt(&self, f: &mut Formatter) -> Result {
try!(write!(f, "\""));
for c in self.chars().flat_map(|c| c.escape_default()) {
@ -647,13 +685,14 @@ impl Show for str {
}
#[stable]
impl String for str {
impl Display for str {
fn fmt(&self, f: &mut Formatter) -> Result {
f.pad(self)
}
}
impl Show for char {
#[stable]
impl Debug for char {
fn fmt(&self, f: &mut Formatter) -> Result {
use char::CharExt;
try!(write!(f, "'"));
@ -665,15 +704,16 @@ impl Show for char {
}
#[stable]
impl String for char {
impl Display for char {
fn fmt(&self, f: &mut Formatter) -> Result {
let mut utf8 = [0u8; 4];
let amt = self.encode_utf8(&mut utf8).unwrap_or(0);
let s: &str = unsafe { mem::transmute(&utf8[..amt]) };
String::fmt(s, f)
Display::fmt(s, f)
}
}
#[stable]
impl<T> Pointer for *const T {
fn fmt(&self, f: &mut Formatter) -> Result {
f.flags |= 1 << (rt::FlagAlternate as uint);
@ -683,18 +723,21 @@ impl<T> Pointer for *const T {
}
}
#[stable]
impl<T> Pointer for *mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
Pointer::fmt(&(*self as *const T), f)
}
}
#[stable]
impl<'a, T> Pointer for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result {
Pointer::fmt(&(*self as *const T), f)
}
}
#[stable]
impl<'a, T> Pointer for &'a mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
Pointer::fmt(&(&**self as *const T), f)
@ -703,15 +746,15 @@ impl<'a, T> Pointer for &'a mut T {
macro_rules! floating { ($ty:ident) => {
impl Show for $ty {
#[stable]
impl Debug for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
try!(String::fmt(self, fmt));
fmt.write_str(stringify!($ty))
Display::fmt(self, fmt)
}
}
#[stable]
impl String for $ty {
impl Display for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::Float;
@ -732,6 +775,7 @@ macro_rules! floating { ($ty:ident) => {
}
}
#[stable]
impl LowerExp for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::Float;
@ -753,6 +797,7 @@ macro_rules! floating { ($ty:ident) => {
}
}
#[stable]
impl UpperExp for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::Float;
@ -777,12 +822,14 @@ macro_rules! floating { ($ty:ident) => {
floating! { f32 }
floating! { f64 }
// Implementation of Show for various core types
// Implementation of Display/Debug for various core types
impl<T> Show for *const T {
#[stable]
impl<T> Debug for *const T {
fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
}
impl<T> Show for *mut T {
#[stable]
impl<T> Debug for *mut T {
fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
}
@ -793,7 +840,8 @@ macro_rules! peel {
macro_rules! tuple {
() => ();
( $($name:ident,)+ ) => (
impl<$($name:Show),*> Show for ($($name,)*) {
#[stable]
impl<$($name:Debug),*> Debug for ($($name,)*) {
#[allow(non_snake_case, unused_assignments)]
fn fmt(&self, f: &mut Formatter) -> Result {
try!(write!(f, "("));
@ -818,11 +866,13 @@ macro_rules! tuple {
tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
impl<'a> Show for &'a (any::Any+'a) {
#[stable]
impl<'a> Debug for &'a (any::Any+'a) {
fn fmt(&self, f: &mut Formatter) -> Result { f.pad("&Any") }
}
impl<T: Show> Show for [T] {
#[stable]
impl<T: Debug> Debug for [T] {
fn fmt(&self, f: &mut Formatter) -> Result {
if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
try!(write!(f, "["));
@ -843,20 +893,22 @@ impl<T: Show> Show for [T] {
}
}
impl Show for () {
#[stable]
impl Debug for () {
fn fmt(&self, f: &mut Formatter) -> Result {
f.pad("()")
}
}
impl<T: Copy + Show> Show for Cell<T> {
#[stable]
impl<T: Copy + Debug> Debug for Cell<T> {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "Cell {{ value: {:?} }}", self.get())
}
}
#[unstable]
impl<T: Show> Show for RefCell<T> {
#[stable]
impl<T: Debug> Debug for RefCell<T> {
fn fmt(&self, f: &mut Formatter) -> Result {
match self.try_borrow() {
Some(val) => write!(f, "RefCell {{ value: {:?} }}", val),
@ -865,29 +917,17 @@ impl<T: Show> Show for RefCell<T> {
}
}
impl<'b, T: Show> Show for Ref<'b, T> {
#[stable]
impl<'b, T: Debug> Debug for Ref<'b, T> {
fn fmt(&self, f: &mut Formatter) -> Result {
Show::fmt(&**self, f)
}
}
impl<'b, T: Show> Show for RefMut<'b, T> {
fn fmt(&self, f: &mut Formatter) -> Result {
Show::fmt(&*(self.deref()), f)
Debug::fmt(&**self, f)
}
}
#[stable]
impl String for Utf8Error {
impl<'b, T: Debug> Debug for RefMut<'b, T> {
fn fmt(&self, f: &mut Formatter) -> Result {
match *self {
Utf8Error::InvalidByte(n) => {
write!(f, "invalid utf-8: invalid byte at index {}", n)
}
Utf8Error::TooShort => {
write!(f, "invalid utf-8: byte slice too short")
}
}
Debug::fmt(&*(self.deref()), f)
}
}

View file

@ -154,13 +154,14 @@ pub fn radix<T>(x: T, base: u8) -> RadixFmt<T, Radix> {
macro_rules! radix_fmt {
($T:ty as $U:ty, $fmt:ident, $S:expr) => {
impl fmt::Show for RadixFmt<$T, Radix> {
#[stable]
impl fmt::Debug for RadixFmt<$T, Radix> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(fmt::String::fmt(self, f));
f.write_str($S)
fmt::Display::fmt(self, f)
}
}
impl fmt::String for RadixFmt<$T, Radix> {
#[stable]
impl fmt::Display for RadixFmt<$T, Radix> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { RadixFmt(ref x, radix) => radix.$fmt(*x as $U, f) }
}
@ -169,6 +170,7 @@ macro_rules! radix_fmt {
}
macro_rules! int_base {
($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => {
#[stable]
impl fmt::$Trait for $T {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
$Radix.fmt_int(*self as $U, f)
@ -179,10 +181,10 @@ macro_rules! int_base {
macro_rules! show {
($T:ident with $S:expr) => {
impl fmt::Show for $T {
#[stable]
impl fmt::Debug for $T {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(fmt::String::fmt(self, f));
f.write_str($S)
fmt::Display::fmt(self, f)
}
}
}
@ -192,7 +194,7 @@ macro_rules! integer {
integer! { $Int, $Uint, stringify!($Int), stringify!($Uint) }
};
($Int:ident, $Uint:ident, $SI:expr, $SU:expr) => {
int_base! { String for $Int as $Int -> Decimal }
int_base! { Display for $Int as $Int -> Decimal }
int_base! { Binary for $Int as $Uint -> Binary }
int_base! { Octal for $Int as $Uint -> Octal }
int_base! { LowerHex for $Int as $Uint -> LowerHex }
@ -200,7 +202,7 @@ macro_rules! integer {
radix_fmt! { $Int as $Int, fmt_int, $SI }
show! { $Int with $SI }
int_base! { String for $Uint as $Uint -> Decimal }
int_base! { Display for $Uint as $Uint -> Decimal }
int_base! { Binary for $Uint as $Uint -> Binary }
int_base! { Octal for $Uint as $Uint -> Octal }
int_base! { LowerHex for $Uint as $Uint -> LowerHex }

View file

@ -136,6 +136,7 @@ pub mod slice;
pub mod str;
pub mod hash;
pub mod fmt;
pub mod error;
// note: does not need to be public
mod tuple;

View file

@ -885,10 +885,10 @@ pub trait IndexMut<Index: ?Sized> {
#[unstable = "API still in development"]
pub struct FullRange;
#[unstable = "API still in development"]
impl fmt::Show for FullRange {
#[stable]
impl fmt::Debug for FullRange {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt::Show::fmt("..", fmt)
fmt::Debug::fmt("..", fmt)
}
}
@ -944,8 +944,8 @@ impl<Idx: Clone + Step> DoubleEndedIterator for Range<Idx> {
#[unstable = "API still in development"]
impl<Idx: Clone + Step> ExactSizeIterator for Range<Idx> {}
#[unstable = "API still in development"]
impl<Idx: fmt::Show> fmt::Show for Range<Idx> {
#[stable]
impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{:?}..{:?}", self.start, self.end)
}
@ -973,8 +973,8 @@ impl<Idx: Clone + Step> Iterator for RangeFrom<Idx> {
}
}
#[unstable = "API still in development"]
impl<Idx: fmt::Show> fmt::Show for RangeFrom<Idx> {
#[stable]
impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{:?}..", self.start)
}
@ -989,8 +989,8 @@ pub struct RangeTo<Idx> {
pub end: Idx,
}
#[unstable = "API still in development"]
impl<Idx: fmt::Show> fmt::Show for RangeTo<Idx> {
#[stable]
impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "..{:?}", self.end)
}

View file

@ -229,7 +229,7 @@
use self::Result::{Ok, Err};
use clone::Clone;
use fmt::Show;
use fmt::Display;
use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator};
use ops::{FnMut, FnOnce};
use option::Option::{self, None, Some};
@ -714,7 +714,7 @@ impl<T, E> Result<T, E> {
}
#[stable]
impl<T, E: Show> Result<T, E> {
impl<T, E: Display> Result<T, E> {
/// Unwraps a result, yielding the content of an `Ok`.
///
/// # Panics
@ -739,13 +739,13 @@ impl<T, E: Show> Result<T, E> {
match self {
Ok(t) => t,
Err(e) =>
panic!("called `Result::unwrap()` on an `Err` value: {:?}", e)
panic!("called `Result::unwrap()` on an `Err` value: {}", e)
}
}
}
#[stable]
impl<T: Show, E> Result<T, E> {
impl<T: Display, E> Result<T, E> {
/// Unwraps a result, yielding the content of an `Err`.
///
/// # Panics
@ -769,7 +769,7 @@ impl<T: Show, E> Result<T, E> {
pub fn unwrap_err(self) -> E {
match self {
Ok(t) =>
panic!("called `Result::unwrap_err()` on an `Ok` value: {:?}", t),
panic!("called `Result::unwrap_err()` on an `Ok` value: {}", t),
Err(e) => e
}
}

View file

@ -20,8 +20,10 @@ use self::Searcher::{Naive, TwoWay, TwoWayLong};
use cmp::{self, Eq};
use default::Default;
use iter::range;
use error::Error;
use fmt;
use iter::ExactSizeIterator;
use iter::range;
use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator};
use marker::Sized;
use mem;
@ -242,6 +244,30 @@ impl<'a> CharEq for &'a [char] {
}
}
#[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",
}
}
}
#[stable]
impl fmt::Display for Utf8Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Utf8Error::InvalidByte(n) => {
write!(f, "invalid utf-8: invalid byte at index {}", n)
}
Utf8Error::TooShort => {
write!(f, "invalid utf-8: byte slice too short")
}
}
}
}
/*
Section: Iterators
*/