std: Stabilize last bits of io::Error

This commit stabilizes a few remaining bits of the `io::Error` type:

* The `Error::new` method is now stable. The last `detail` parameter was removed
  and the second `desc` parameter was generalized to `E: Into<Box<Error>>` to
  allow creating an I/O error from any form of error. Currently there is no form
  of downcasting, but this will be added in time.

* An implementation of `From<&str> for Box<Error>` was added to liballoc to
  allow construction of errors from raw strings.

* The `Error::raw_os_error` method was stabilized as-is.

* Trait impls for `Clone`, `Eq`, and `PartialEq` were removed from `Error` as it
  is not possible to use them with trait objects.

This is a breaking change due to the modification of the `new` method as well as
the removal of the trait implementations for the `Error` type.

[breaking-change]
This commit is contained in:
Alex Crichton
2015-03-31 16:01:03 -07:00
parent 80bf31dd51
commit ac77392f8a
23 changed files with 109 additions and 96 deletions

View File

@@ -9,12 +9,12 @@
// except according to those terms.
use boxed::Box;
use clone::Clone;
use convert::Into;
use error;
use fmt;
use marker::Send;
use option::Option::{self, Some, None};
use result;
use string::String;
use sys;
/// A type for results generated by I/O related functions where the `Err` type
@@ -31,23 +31,22 @@ pub type Result<T> = result::Result<T, Error>;
/// Errors mostly originate from the underlying OS, but custom instances of
/// `Error` can be created with crafted error messages and a particular value of
/// `ErrorKind`.
#[derive(PartialEq, Eq, Clone, Debug)]
#[derive(Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Error {
repr: Repr,
}
#[derive(PartialEq, Eq, Clone, Debug)]
#[derive(Debug)]
enum Repr {
Os(i32),
Custom(Box<Custom>),
}
#[derive(PartialEq, Eq, Clone, Debug)]
#[derive(Debug)]
struct Custom {
kind: ErrorKind,
desc: &'static str,
detail: Option<String>
error: Box<error::Error+Send>,
}
/// A list specifying general categories of I/O error.
@@ -125,18 +124,34 @@ pub enum ErrorKind {
}
impl Error {
/// Creates a new custom error from a specified kind/description/detail.
#[unstable(feature = "io", reason = "the exact makeup of an Error may
change to include `Box<Error>` for \
example")]
pub fn new(kind: ErrorKind,
description: &'static str,
detail: Option<String>) -> Error {
/// Creates a new I/O error from a known kind of error as well as an
/// arbitrary error payload.
///
/// This function is used to generically create I/O errors which do not
/// originate from the OS itself. The `error` argument is an arbitrary
/// payload which will be contained in this `Error`. Accessors as well as
/// downcasting will soon be added to this type as well to access the custom
/// information.
///
/// # Examples
///
/// ```
/// use std::io::{Error, ErrorKind};
///
/// // errors can be created from strings
/// let custom_error = Error::new(ErrorKind::Other, "oh no!");
///
/// // errors can also be created from other errors
/// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<E>(kind: ErrorKind, error: E) -> Error
where E: Into<Box<error::Error+Send>>
{
Error {
repr: Repr::Custom(Box::new(Custom {
kind: kind,
desc: description,
detail: detail,
error: error.into(),
}))
}
}
@@ -162,8 +177,7 @@ impl Error {
///
/// If this `Error` was constructed via `last_os_error` then this function
/// will return `Some`, otherwise it will return `None`.
#[unstable(feature = "io", reason = "function was just added and the return \
type may become an abstract OS error")]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn raw_os_error(&self) -> Option<i32> {
match self.repr {
Repr::Os(i) => Some(i),
@@ -179,27 +193,6 @@ impl Error {
Repr::Custom(ref c) => c.kind,
}
}
/// Returns a short description for this error message
#[unstable(feature = "io")]
#[deprecated(since = "1.0.0", reason = "use the Error trait's description \
method instead")]
pub fn description(&self) -> &str {
match self.repr {
Repr::Os(..) => "os error",
Repr::Custom(ref c) => c.desc,
}
}
/// Returns a detailed error message for this error (if one is available)
#[unstable(feature = "io")]
#[deprecated(since = "1.0.0", reason = "use the to_string() method instead")]
pub fn detail(&self) -> Option<String> {
match self.repr {
Repr::Os(code) => Some(sys::os::error_string(code)),
Repr::Custom(ref s) => s.detail.clone(),
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -210,21 +203,7 @@ impl fmt::Display for Error {
let detail = sys::os::error_string(code);
write!(fmt, "{} (os error {})", detail, code)
}
Repr::Custom(ref c) => {
match **c {
Custom {
kind: ErrorKind::Other,
desc: "unknown error",
detail: Some(ref detail)
} => {
write!(fmt, "{}", detail)
}
Custom { detail: None, desc, .. } =>
write!(fmt, "{}", desc),
Custom { detail: Some(ref detail), desc, .. } =>
write!(fmt, "{} ({})", desc, detail)
}
}
Repr::Custom(ref c) => c.error.fmt(fmt),
}
}
}
@@ -234,7 +213,7 @@ impl error::Error for Error {
fn description(&self) -> &str {
match self.repr {
Repr::Os(..) => "os error",
Repr::Custom(ref c) => c.desc,
Repr::Custom(ref c) => c.error.description(),
}
}
}