Collect the definition of the Error
trait into libstd
for now. This
sidesteps a coherence difficulty where `liballoc` had to prove that `&str: !Error`, which didn't involve any local types.
This commit is contained in:
parent
15b58fedca
commit
19d3dab31b
@ -51,15 +51,12 @@ use core::prelude::*;
|
||||
use core::any::Any;
|
||||
use core::cmp::Ordering;
|
||||
use core::default::Default;
|
||||
use core::error::Error;
|
||||
use core::fmt;
|
||||
use core::hash::{self, Hash};
|
||||
use core::mem;
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use core::ptr::{self, Unique};
|
||||
use core::raw::{TraitObject, Slice};
|
||||
|
||||
use heap;
|
||||
use core::ptr::{Unique};
|
||||
use core::raw::{TraitObject};
|
||||
|
||||
/// A value that represents the heap. This is the default place that the `box`
|
||||
/// keyword allocates into when no place is supplied.
|
||||
@ -303,49 +300,3 @@ impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
|
||||
fn from(err: E) -> 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(),
|
||||
})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
use core::prelude::*;
|
||||
|
||||
use core::default::Default;
|
||||
use core::error::Error;
|
||||
use core::fmt;
|
||||
use core::hash;
|
||||
use core::iter::{IntoIterator, FromIterator};
|
||||
@ -723,11 +722,6 @@ impl fmt::Display for FromUtf8Error {
|
||||
}
|
||||
}
|
||||
|
||||
#[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 fmt::Display for FromUtf16Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@ -735,11 +729,6 @@ impl fmt::Display for FromUtf16Error {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Error for FromUtf16Error {
|
||||
fn description(&self) -> &str { "invalid utf-16" }
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl FromIterator<char> for String {
|
||||
fn from_iter<I: IntoIterator<Item=char>>(iter: I) -> String {
|
||||
|
@ -1,56 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use prelude::*;
|
||||
use fmt::{Debug, Display};
|
||||
|
||||
/// Base functionality for all errors in Rust.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Error: Debug + Display {
|
||||
/// A short description of the error.
|
||||
///
|
||||
/// The description should not contain newlines or sentence-ending
|
||||
/// punctuation, to facilitate embedding in larger user-facing
|
||||
/// strings.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn description(&self) -> &str;
|
||||
|
||||
/// The lower-level cause of this error, if any.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn cause(&self) -> Option<&Error> { None }
|
||||
}
|
@ -147,7 +147,6 @@ pub mod slice;
|
||||
pub mod str;
|
||||
pub mod hash;
|
||||
pub mod fmt;
|
||||
pub mod error;
|
||||
|
||||
#[doc(primitive = "bool")]
|
||||
mod bool {
|
||||
|
@ -20,7 +20,6 @@ use self::wrapping::{OverflowingOps, WrappingOps};
|
||||
use char::CharExt;
|
||||
use clone::Clone;
|
||||
use cmp::{PartialEq, Eq, PartialOrd, Ord};
|
||||
use error::Error;
|
||||
use fmt;
|
||||
use intrinsics;
|
||||
use iter::Iterator;
|
||||
@ -2948,16 +2947,9 @@ enum IntErrorKind {
|
||||
Underflow,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl fmt::Display for ParseIntError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.description().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Error for ParseIntError {
|
||||
fn description(&self) -> &str {
|
||||
impl ParseIntError {
|
||||
#[unstable(feature = "core", reason = "available through Error trait")]
|
||||
pub fn description(&self) -> &str {
|
||||
match self.kind {
|
||||
IntErrorKind::Empty => "cannot parse integer from empty string",
|
||||
IntErrorKind::InvalidDigit => "invalid digit found in string",
|
||||
@ -2967,6 +2959,13 @@ impl Error for ParseIntError {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl fmt::Display for ParseIntError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.description().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// An error which can be returned when parsing a float.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -2978,19 +2977,19 @@ enum FloatErrorKind {
|
||||
Invalid,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl fmt::Display for ParseFloatError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.description().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Error for ParseFloatError {
|
||||
fn description(&self) -> &str {
|
||||
impl ParseFloatError {
|
||||
#[unstable(feature = "core", reason = "available through Error trait")]
|
||||
pub fn description(&self) -> &str {
|
||||
match self.kind {
|
||||
FloatErrorKind::Empty => "cannot parse float from empty string",
|
||||
FloatErrorKind::Invalid => "invalid float literal",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl fmt::Display for ParseFloatError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.description().fmt(f)
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ use char::CharExt;
|
||||
use clone::Clone;
|
||||
use cmp::{self, Eq};
|
||||
use default::Default;
|
||||
use error::Error;
|
||||
use fmt;
|
||||
use iter::ExactSizeIterator;
|
||||
use iter::{Map, Iterator, DoubleEndedIterator};
|
||||
@ -192,11 +191,6 @@ impl fmt::Display for ParseBoolError {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Error for ParseBoolError {
|
||||
fn description(&self) -> &str { "failed to parse bool" }
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Creating a string
|
||||
*/
|
||||
@ -241,16 +235,6 @@ pub unsafe fn from_utf8_unchecked<'a>(v: &'a [u8]) -> &'a str {
|
||||
mem::transmute(v)
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
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(feature = "rust1", since = "1.0.0")]
|
||||
impl fmt::Display for Utf8Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
152
src/libstd/error.rs
Normal file
152
src/libstd/error.rs
Normal file
@ -0,0 +1,152 @@
|
||||
// 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.
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
// A note about crates and the facade:
|
||||
//
|
||||
// Originally, the `Error` trait was defined in libcore, and the impls
|
||||
// were scattered about. However, coherence objected to this
|
||||
// arrangement, because to create the blanket impls for `Box` required
|
||||
// knowing that `&str: !Error`, and we have no means to deal with that
|
||||
// sort of conflict just now. Therefore, for the time being, we have
|
||||
// moved the `Error` trait into libstd. As we evolve a sol'n to the
|
||||
// coherence challenge (e.g., specialization, neg impls, etc) we can
|
||||
// reconsider what crate these items belong in.
|
||||
|
||||
use boxed::Box;
|
||||
use convert::From;
|
||||
use fmt::{self, Debug, Display};
|
||||
use marker::Send;
|
||||
use num;
|
||||
use option::Option;
|
||||
use option::Option::None;
|
||||
use str;
|
||||
use string::{self, String};
|
||||
|
||||
/// Base functionality for all errors in Rust.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Error: Debug + Display {
|
||||
/// A short description of the error.
|
||||
///
|
||||
/// The description should not contain newlines or sentence-ending
|
||||
/// punctuation, to facilitate embedding in larger user-facing
|
||||
/// strings.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn description(&self) -> &str;
|
||||
|
||||
/// The lower-level cause of this error, if any.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn cause(&self) -> Option<&Error> { None }
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
|
||||
fn from(err: E) -> 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(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(String::from_str(err)))
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Error for str::ParseBoolError {
|
||||
fn description(&self) -> &str { "failed to parse bool" }
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Error for str::Utf8Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
str::Utf8Error::TooShort => "invalid utf-8: not enough bytes",
|
||||
str::Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Error for num::ParseIntError {
|
||||
fn description(&self) -> &str {
|
||||
self.description()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Error for num::ParseFloatError {
|
||||
fn description(&self) -> &str {
|
||||
self.description()
|
||||
}
|
||||
}
|
||||
|
||||
#[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"
|
||||
}
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ pub use core::raw;
|
||||
pub use core::simd;
|
||||
pub use core::result;
|
||||
pub use core::option;
|
||||
pub use core::error;
|
||||
pub mod error;
|
||||
|
||||
#[cfg(not(test))] pub use alloc::boxed;
|
||||
pub use alloc::rc;
|
||||
|
Loading…
Reference in New Issue
Block a user