rollup merge of #23919: alexcrichton/stabilize-io-error
Conflicts: src/libstd/fs/tempdir.rs src/libstd/io/error.rs
This commit is contained in:
commit
50b3ecf3bc
@ -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(),
|
||||
})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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))]
|
||||
|
@ -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)[..]))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,6 @@
|
||||
#![feature(collections)]
|
||||
#![feature(core)]
|
||||
#![feature(old_fs)]
|
||||
#![feature(io)]
|
||||
#![feature(old_io)]
|
||||
#![feature(old_path)]
|
||||
#![feature(rustc_private)]
|
||||
|
@ -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[..]))
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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
|
||||
|
@ -34,7 +34,6 @@
|
||||
#![feature(unsafe_destructor)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(exit_status)]
|
||||
#![feature(io)]
|
||||
#![feature(set_stdio)]
|
||||
#![feature(unicode)]
|
||||
|
||||
|
@ -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)[..])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)),
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -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")
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -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")),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,7 +456,6 @@ impl Child {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"invalid argument: can't kill an exited process",
|
||||
None
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user