diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 7bdf9eaccc323..ef1c68bb6c7b6 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -68,6 +68,7 @@ use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace}; use core::ptr::{self, Unique}; use core::raw::TraitObject; use core::convert::From; +use core::error::Error; /// A value that represents the heap. This is the default place that the `box` /// keyword allocates into when no place is supplied. @@ -641,3 +642,112 @@ impl AsMut for Box { &mut **self } } + + + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, E: Error + 'a> From for Box { + fn from(err: E) -> Box { + Box::new(err) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, E: Error + Send + Sync + 'a> From for Box { + fn from(err: E) -> Box { + Box::new(err) + } +} + +impl Box { + fn new_box_str(s: &str) -> Box { + let len = s.len(); + let buf = RawVec::with_capacity(len); + unsafe { + ptr::copy_nonoverlapping(s.as_ptr(), buf.ptr(), len); + mem::transmute(buf.into_box()) // bytes to str ~magic + } + } +} + +#[unstable(feature="error_box_str",issue="0")] +impl Error for Box { + fn description(&self) -> &str { + self + } +} + +impl Box { + #[inline] + #[stable(feature = "error_downcast", since = "1.3.0")] + /// Attempt to downcast the box to a concrete type. + pub fn downcast(self) -> Result, Box> { + if self.is::() { + unsafe { + // Get the raw representation of the trait object + let raw = Box::into_raw(self); + let to: TraitObject = + mem::transmute::<*mut Error, TraitObject>(raw); + + // Extract the data pointer + Ok(Box::from_raw(to.data as *mut T)) + } + } else { + Err(self) + } + } +} + +impl Box { + #[inline] + #[stable(feature = "error_downcast", since = "1.3.0")] + /// Attempt to downcast the box to a concrete type. + pub fn downcast(self) + -> Result, Box> { + let err: Box = self; + >::downcast(err).map_err(|s| unsafe { + // reapply the Send marker + mem::transmute::, Box>(s) + }) + } +} + +impl Box { + #[inline] + #[stable(feature = "error_downcast", since = "1.3.0")] + /// Attempt to downcast the box to a concrete type. + pub fn downcast(self) + -> Result, Self> { + let err: Box = self; + >::downcast(err).map_err(|s| unsafe { + // reapply the Send+Sync marker + mem::transmute::, Box>(s) + }) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b> From<&'b str> for Box { + fn from(err: &'b str) -> Box { + From::from(Box::new_box_str(err)) + } +} + +#[stable(feature = "string_box_error", since = "1.7.0")] +impl<'a> From<&'a str> for Box { + fn from(err: &'a str) -> Box { + From::from(Box::new_box_str(err)) + } +} + +#[stable(feature = "box_error", since = "1.7.0")] +impl Error for Box { + fn description(&self) -> &str { + Error::description(&**self) + } + + fn cause(&self) -> Option<&Error> { + Error::cause(&**self) + } +} + diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 306fad2328b62..5d99898ae2be0 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -62,6 +62,7 @@ use core::mem; use core::ops::{self, Add, Index, IndexMut}; use core::ptr; use core::str::pattern::Pattern; +use core::error::Error; use rustc_unicode::char::{decode_utf16, REPLACEMENT_CHARACTER}; use rustc_unicode::str as unicode_str; @@ -1897,3 +1898,56 @@ impl<'a> DoubleEndedIterator for Drain<'a> { self.iter.next_back() } } + + + +#[stable(feature = "rust1", since = "1.0.0")] +impl From for Box { + fn from(err: String) -> Box { + #[derive(Debug)] + struct StringError(String); + + impl Error for StringError { + fn description(&self) -> &str { &self.0 } + } + + impl fmt::Display for StringError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.0, f) + } + } + + Box::new(StringError(err)) + } +} + +#[stable(feature = "string_box_error", since = "1.7.0")] +impl From for Box { + fn from(str_err: String) -> Box { + let err1: Box = From::from(str_err); + let err2: Box = err1; + err2 + } +} + + +#[stable(feature = "rust1", since = "1.0.0")] +impl Error for FromUtf8Error { + fn description(&self) -> &str { + "invalid utf-8" + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Error for FromUtf16Error { + fn description(&self) -> &str { + "invalid utf-16" + } +} + +#[stable(feature = "str_parse_error2", since = "1.8.0")] +impl Error for ParseError { + fn description(&self) -> &str { + match *self {} + } +} diff --git a/src/libstd/error.rs b/src/libcore/error.rs similarity index 65% rename from src/libstd/error.rs rename to src/libcore/error.rs index 35cd4a5ec5292..31c6192d3cdfa 100644 --- a/src/libstd/error.rs +++ b/src/libcore/error.rs @@ -48,18 +48,17 @@ // reconsider what crate these items belong in. use any::TypeId; -use boxed::Box; -use char; -use fmt::{self, Debug, Display}; +use fmt::{Debug, Display}; use marker::{Send, Sync, Reflect}; use mem::transmute; use num; use raw::TraitObject; use str; -use string::{self, String}; +use option::Option::{self, Some, None}; /// Base functionality for all errors in Rust. #[stable(feature = "rust1", since = "1.0.0")] +#[fundamental] pub trait Error: Debug + Display + Reflect { /// A short description of the error. /// @@ -83,63 +82,6 @@ pub trait Error: Debug + Display + Reflect { } } -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, E: Error + 'a> From for Box { - fn from(err: E) -> Box { - Box::new(err) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, E: Error + Send + Sync + 'a> From for Box { - fn from(err: E) -> Box { - Box::new(err) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl From for Box { - fn from(err: String) -> Box { - #[derive(Debug)] - struct StringError(String); - - impl Error for StringError { - fn description(&self) -> &str { &self.0 } - } - - impl Display for StringError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&self.0, f) - } - } - - Box::new(StringError(err)) - } -} - -#[stable(feature = "string_box_error", since = "1.7.0")] -impl From for Box { - fn from(str_err: String) -> Box { - let err1: Box = From::from(str_err); - let err2: Box = err1; - err2 - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b> From<&'b str> for Box { - fn from(err: &'b str) -> Box { - From::from(String::from(err)) - } -} - -#[stable(feature = "string_box_error", since = "1.7.0")] -impl<'a> From<&'a str> for Box { - fn from(err: &'a str) -> Box { - From::from(String::from(err)) - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl Error for str::ParseBoolError { fn description(&self) -> &str { "failed to parse bool" } @@ -166,45 +108,6 @@ impl Error for num::ParseFloatError { } } -#[stable(feature = "rust1", since = "1.0.0")] -impl Error for string::FromUtf8Error { - fn description(&self) -> &str { - "invalid utf-8" - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Error for string::FromUtf16Error { - fn description(&self) -> &str { - "invalid utf-16" - } -} - -#[stable(feature = "str_parse_error2", since = "1.8.0")] -impl Error for string::ParseError { - fn description(&self) -> &str { - match *self {} - } -} - -#[stable(feature = "decode_utf16", since = "1.9.0")] -impl Error for char::DecodeUtf16Error { - fn description(&self) -> &str { - "unpaired surrogate found" - } -} - -#[stable(feature = "box_error", since = "1.7.0")] -impl Error for Box { - fn description(&self) -> &str { - Error::description(&**self) - } - - fn cause(&self) -> Option<&Error> { - Error::cause(&**self) - } -} - // copied from any.rs impl Error + 'static { /// Returns true if the boxed type is the same as `T` @@ -304,55 +207,6 @@ impl Error + 'static + Send + Sync { } } -impl Error { - #[inline] - #[stable(feature = "error_downcast", since = "1.3.0")] - /// Attempt to downcast the box to a concrete type. - pub fn downcast(self: Box) -> Result, Box> { - if self.is::() { - unsafe { - // Get the raw representation of the trait object - let raw = Box::into_raw(self); - let to: TraitObject = - transmute::<*mut Error, TraitObject>(raw); - - // Extract the data pointer - Ok(Box::from_raw(to.data as *mut T)) - } - } else { - Err(self) - } - } -} - -impl Error + Send { - #[inline] - #[stable(feature = "error_downcast", since = "1.3.0")] - /// Attempt to downcast the box to a concrete type. - pub fn downcast(self: Box) - -> Result, Box> { - let err: Box = self; - ::downcast(err).map_err(|s| unsafe { - // reapply the Send marker - transmute::, Box>(s) - }) - } -} - -impl Error + Send + Sync { - #[inline] - #[stable(feature = "error_downcast", since = "1.3.0")] - /// Attempt to downcast the box to a concrete type. - pub fn downcast(self: Box) - -> Result, Box> { - let err: Box = self; - ::downcast(err).map_err(|s| unsafe { - // reapply the Send+Sync marker - transmute::, Box>(s) - }) - } -} - #[cfg(test)] mod tests { use prelude::v1::*; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index fa5e90562d80e..8a20eb4ec81e6 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -152,5 +152,7 @@ pub mod str; pub mod hash; pub mod fmt; +pub mod error; + // note: does not need to be public mod tuple; diff --git a/src/librustc_unicode/char.rs b/src/librustc_unicode/char.rs index 863cada5b8809..b1d70240f9df2 100644 --- a/src/librustc_unicode/char.rs +++ b/src/librustc_unicode/char.rs @@ -754,6 +754,13 @@ pub struct DecodeUtf16Error { code: u16, } +#[stable(feature = "decode_utf16", since = "1.9.0")] +impl ::core::error::Error for DecodeUtf16Error { + fn description(&self) -> &str { + "unpaired surrogate found" + } +} + /// Create an iterator over the UTF-16 encoded code points in `iter`, /// returning unpaired surrogates as `Err`s. /// diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index 9a605fc7bbff4..1261baceac716 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -10,7 +10,7 @@ use boxed::Box; use convert::Into; -use error; +use core::error; use fmt; use marker::{Send, Sync}; use option::Option::{self, Some, None}; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e14a31453d381..f2833157340ab 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -341,13 +341,14 @@ pub use core::result; #[stable(feature = "rust1", since = "1.0.0")] pub use core::option; -pub mod error; - #[stable(feature = "rust1", since = "1.0.0")] pub use alloc::boxed; #[stable(feature = "rust1", since = "1.0.0")] pub use alloc::rc; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::error; + #[stable(feature = "rust1", since = "1.0.0")] pub use core_collections::borrow; #[stable(feature = "rust1", since = "1.0.0")]