rollup merge of #23919: alexcrichton/stabilize-io-error

Conflicts:
	src/libstd/fs/tempdir.rs
	src/libstd/io/error.rs
This commit is contained in:
Alex Crichton 2015-03-31 16:18:55 -07:00
commit 50b3ecf3bc
22 changed files with 108 additions and 72 deletions

View File

@ -56,8 +56,10 @@ use core::fmt;
use core::hash::{self, Hash};
use core::mem;
use core::ops::{Deref, DerefMut};
use core::ptr::Unique;
use core::raw::TraitObject;
use core::ptr::{self, Unique};
use core::raw::{TraitObject, Slice};
use heap;
/// A value that represents the heap. This is the default place that the `box`
/// keyword allocates into when no place is supplied.
@ -313,3 +315,43 @@ impl<'a, E: Error + 'a> From<E> for 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(Box<str>);
impl Error for StringError {
fn description(&self) -> &str { &self.0 }
}
impl fmt::Display for StringError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
// Unfortunately `String` is located in libcollections, so we construct
// a `Box<str>` manually here.
unsafe {
let alloc = if err.len() == 0 {
0 as *mut u8
} else {
let ptr = heap::allocate(err.len(), 1);
if ptr.is_null() { ::oom(); }
ptr as *mut u8
};
ptr::copy(err.as_bytes().as_ptr(), alloc, err.len());
Box::new(StringError(mem::transmute(Slice {
data: alloc,
len: err.len(),
})))
}
}
}

View File

@ -78,6 +78,7 @@
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(core)]
#![feature(unique)]
#![feature(convert)]
#![cfg_attr(test, feature(test, alloc, rustc_private))]
#![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")),
feature(libc))]

View File

@ -862,8 +862,8 @@ pub mod writer {
} else if 0x100 <= n && n < NUM_TAGS {
w.write_all(&[0xf0 | (n >> 8) as u8, n as u8])
} else {
Err(io::Error::new(io::ErrorKind::Other, "invalid tag",
Some(n.to_string())))
Err(io::Error::new(io::ErrorKind::Other,
&format!("invalid tag: {}", n)[..]))
}
}
@ -876,7 +876,7 @@ pub mod writer {
4 => w.write_all(&[0x10 | ((n >> 24) as u8), (n >> 16) as u8,
(n >> 8) as u8, n as u8]),
_ => Err(io::Error::new(io::ErrorKind::Other,
"isize too big", Some(n.to_string())))
&format!("isize too big: {}", n)[..]))
}
}
@ -885,8 +885,8 @@ pub mod writer {
if n < 0x4000 { return write_sized_vuint(w, n, 2); }
if n < 0x200000 { return write_sized_vuint(w, n, 3); }
if n < 0x10000000 { return write_sized_vuint(w, n, 4); }
Err(io::Error::new(io::ErrorKind::Other, "isize too big",
Some(n.to_string())))
Err(io::Error::new(io::ErrorKind::Other,
&format!("isize too big: {}", n)[..]))
}
impl<'a> Encoder<'a> {
@ -1077,8 +1077,8 @@ pub mod writer {
self.wr_tagged_raw_u32(EsSub32 as usize, v)
} else {
Err(io::Error::new(io::ErrorKind::Other,
"length or variant id too big",
Some(v.to_string())))
&format!("length or variant id too big: {}",
v)[..]))
}
}

View File

@ -21,9 +21,7 @@ pub fn realpath(original: &Path) -> io::Result<PathBuf> {
let old = old_path::Path::new(original.to_str().unwrap());
match old_realpath(&old) {
Ok(p) => Ok(PathBuf::from(p.as_str().unwrap())),
Err(e) => Err(io::Error::new(io::ErrorKind::Other,
"realpath error",
Some(e.to_string())))
Err(e) => Err(io::Error::new(io::ErrorKind::Other, e))
}
}

View File

@ -36,7 +36,6 @@
#![feature(collections)]
#![feature(core)]
#![feature(old_fs)]
#![feature(io)]
#![feature(old_io)]
#![feature(old_path)]
#![feature(rustc_private)]

View File

@ -47,9 +47,10 @@ pub fn get_sdk_root(sdk_name: &str) -> String {
Ok(String::from_utf8(output.stdout).unwrap())
} else {
let error = String::from_utf8(output.stderr);
let error = format!("process exit with error: {}",
error.unwrap());
Err(io::Error::new(io::ErrorKind::Other,
"process exit with error",
error.ok()))
&error[..]))
}
});

View File

@ -67,8 +67,7 @@ impl TempDir {
}
Err(Error::new(ErrorKind::AlreadyExists,
"too many temporary directories already exist",
None))
"too many temporary directories already exist"))
}
/// Attempts to make a temporary directory inside of `env::temp_dir()` whose

View File

@ -34,7 +34,6 @@
#![feature(unsafe_destructor)]
#![feature(staged_api)]
#![feature(exit_status)]
#![feature(io)]
#![feature(set_stdio)]
#![feature(unicode)]

View File

@ -699,8 +699,8 @@ fn print_flowgraph<W: Write>(variants: Vec<borrowck_dot::Variant>,
fn expand_err_details(r: io::Result<()>) -> io::Result<()> {
r.map_err(|ioerr| {
io::Error::new(io::ErrorKind::Other, "graphviz::render failed",
Some(ioerr.to_string()))
io::Error::new(io::ErrorKind::Other,
&format!("graphviz::render failed: {}", ioerr)[..])
})
}
}

View File

@ -241,7 +241,7 @@ impl fmt::Display for NulError {
impl From<NulError> for io::Error {
fn from(_: NulError) -> io::Error {
io::Error::new(io::ErrorKind::InvalidInput,
"data provided contains a nul byte", None)
"data provided contains a nul byte")
}
}

View File

@ -576,8 +576,7 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
let to = to.as_ref();
if !from.is_file() {
return Err(Error::new(ErrorKind::InvalidInput,
"the source path is not an existing file",
None))
"the source path is not an existing file"))
}
let mut reader = try!(File::open(from));

View File

@ -165,7 +165,7 @@ impl<W: Write> BufWriter<W> {
match self.inner.as_mut().unwrap().write(&self.buf[written..]) {
Ok(0) => {
ret = Err(Error::new(ErrorKind::WriteZero,
"failed to write the buffered data", None));
"failed to write the buffered data"));
break;
}
Ok(n) => written += n,

View File

@ -75,8 +75,7 @@ macro_rules! seek {
if pos < 0 {
Err(Error::new(ErrorKind::InvalidInput,
"invalid seek to a negative position",
None))
"invalid seek to a negative position"))
} else {
self.pos = pos as u64;
Ok(self.pos)

View File

@ -9,11 +9,12 @@
// except according to those terms.
use boxed::Box;
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
@ -30,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.
@ -124,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(),
}))
}
}
@ -161,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),
@ -188,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),
}
}
}
@ -212,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(),
}
}
}

View File

@ -180,7 +180,7 @@ impl<'a> Write for &'a mut [u8] {
if try!(self.write(data)) == data.len() {
Ok(())
} else {
Err(Error::new(ErrorKind::WriteZero, "failed to write whole buffer", None))
Err(Error::new(ErrorKind::WriteZero, "failed to write whole buffer"))
}
}

View File

@ -83,7 +83,7 @@ fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
if str::from_utf8(&g.s[g.len..]).is_err() {
ret.and_then(|_| {
Err(Error::new(ErrorKind::InvalidInput,
"stream did not contain valid UTF-8", None))
"stream did not contain valid UTF-8"))
})
} else {
g.len = g.s.len();
@ -359,8 +359,7 @@ pub trait Write {
while buf.len() > 0 {
match self.write(buf) {
Ok(0) => return Err(Error::new(ErrorKind::WriteZero,
"failed to write whole buffer",
None)),
"failed to write whole buffer")),
Ok(n) => buf = &buf[n..],
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
@ -782,7 +781,7 @@ pub struct Chars<R> {
/// An enumeration of possible errors that can be generated from the `Chars`
/// adapter.
#[derive(PartialEq, Clone, Debug)]
#[derive(Debug)]
#[unstable(feature = "io", reason = "awaiting stability of Read::chars")]
pub enum CharsError {
/// Variant representing that the underlying stream was read successfully

View File

@ -435,7 +435,7 @@ impl ToSocketAddrs for str {
match $e {
Some(r) => r,
None => return Err(io::Error::new(io::ErrorKind::InvalidInput,
$msg, None)),
$msg)),
}
)
}

View File

@ -72,7 +72,7 @@ fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
}
Err(last_err.unwrap_or_else(|| {
Error::new(ErrorKind::InvalidInput,
"could not resolve to any addresses", None)
"could not resolve to any addresses")
}))
}

View File

@ -76,7 +76,7 @@ impl UdpSocket {
match try!(addr.to_socket_addrs()).next() {
Some(addr) => self.0.send_to(buf, &addr),
None => Err(Error::new(ErrorKind::InvalidInput,
"no addresses to send data to", None)),
"no addresses to send data to")),
}
}

View File

@ -456,7 +456,6 @@ impl Child {
return Err(Error::new(
ErrorKind::InvalidInput,
"invalid argument: can't kill an exited process",
None
))
}

View File

@ -75,7 +75,7 @@ fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
})))
}
_ => {
Err(Error::new(ErrorKind::InvalidInput, "invalid argument", None))
Err(Error::new(ErrorKind::InvalidInput, "invalid argument"))
}
}
}
@ -158,8 +158,7 @@ pub fn lookup_addr(addr: &IpAddr) -> io::Result<String> {
match from_utf8(data.to_bytes()) {
Ok(name) => Ok(name.to_string()),
Err(_) => Err(io::Error::new(io::ErrorKind::Other,
"failed to lookup address information",
Some("invalid host name".to_string())))
"failed to lookup address information"))
}
}

View File

@ -35,7 +35,8 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
.to_string()
};
Err(io::Error::new(io::ErrorKind::Other,
"failed to lookup address information", Some(detail)))
&format!("failed to lookup address information: {}",
detail)[..]))
}
impl Socket {