Skip to content

Commit 19d3dab

Browse files
committedApr 1, 2015
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.
1 parent 15b58fe commit 19d3dab

File tree

8 files changed

+175
-157
lines changed

8 files changed

+175
-157
lines changed
 

‎src/liballoc/boxed.rs

+2-51
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,12 @@ use core::prelude::*;
5151
use core::any::Any;
5252
use core::cmp::Ordering;
5353
use core::default::Default;
54-
use core::error::Error;
5554
use core::fmt;
5655
use core::hash::{self, Hash};
5756
use core::mem;
5857
use core::ops::{Deref, DerefMut};
59-
use core::ptr::{self, Unique};
60-
use core::raw::{TraitObject, Slice};
61-
62-
use heap;
58+
use core::ptr::{Unique};
59+
use core::raw::{TraitObject};
6360

6461
/// A value that represents the heap. This is the default place that the `box`
6562
/// keyword allocates into when no place is supplied.
@@ -303,49 +300,3 @@ impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
303300
#[stable(feature = "rust1", since = "1.0.0")]
304301
impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}
305302

306-
#[stable(feature = "rust1", since = "1.0.0")]
307-
impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
308-
fn from(err: E) -> Box<Error + 'a> {
309-
Box::new(err)
310-
}
311-
}
312-
313-
#[stable(feature = "rust1", since = "1.0.0")]
314-
impl<'a, E: Error + Send + 'a> From<E> for Box<Error + Send + 'a> {
315-
fn from(err: E) -> Box<Error + Send + 'a> {
316-
Box::new(err)
317-
}
318-
}
319-
320-
#[stable(feature = "rust1", since = "1.0.0")]
321-
impl<'a, 'b> From<&'b str> for Box<Error + Send + 'a> {
322-
fn from(err: &'b str) -> Box<Error + Send + 'a> {
323-
#[derive(Debug)]
324-
struct StringError(Box<str>);
325-
impl Error for StringError {
326-
fn description(&self) -> &str { &self.0 }
327-
}
328-
impl fmt::Display for StringError {
329-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
330-
self.0.fmt(f)
331-
}
332-
}
333-
334-
// Unfortunately `String` is located in libcollections, so we construct
335-
// a `Box<str>` manually here.
336-
unsafe {
337-
let alloc = if err.len() == 0 {
338-
0 as *mut u8
339-
} else {
340-
let ptr = heap::allocate(err.len(), 1);
341-
if ptr.is_null() { ::oom(); }
342-
ptr as *mut u8
343-
};
344-
ptr::copy(err.as_bytes().as_ptr(), alloc, err.len());
345-
Box::new(StringError(mem::transmute(Slice {
346-
data: alloc,
347-
len: err.len(),
348-
})))
349-
}
350-
}
351-
}

‎src/libcollections/string.rs

-11
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use core::prelude::*;
1818

1919
use core::default::Default;
20-
use core::error::Error;
2120
use core::fmt;
2221
use core::hash;
2322
use core::iter::{IntoIterator, FromIterator};
@@ -723,23 +722,13 @@ impl fmt::Display for FromUtf8Error {
723722
}
724723
}
725724

726-
#[stable(feature = "rust1", since = "1.0.0")]
727-
impl Error for FromUtf8Error {
728-
fn description(&self) -> &str { "invalid utf-8" }
729-
}
730-
731725
#[stable(feature = "rust1", since = "1.0.0")]
732726
impl fmt::Display for FromUtf16Error {
733727
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
734728
fmt::Display::fmt("invalid utf-16: lone surrogate found", f)
735729
}
736730
}
737731

738-
#[stable(feature = "rust1", since = "1.0.0")]
739-
impl Error for FromUtf16Error {
740-
fn description(&self) -> &str { "invalid utf-16" }
741-
}
742-
743732
#[stable(feature = "rust1", since = "1.0.0")]
744733
impl FromIterator<char> for String {
745734
fn from_iter<I: IntoIterator<Item=char>>(iter: I) -> String {

‎src/libcore/error.rs

-56
This file was deleted.

‎src/libcore/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ pub mod slice;
147147
pub mod str;
148148
pub mod hash;
149149
pub mod fmt;
150-
pub mod error;
151150

152151
#[doc(primitive = "bool")]
153152
mod bool {

‎src/libcore/num/mod.rs

+20-21
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use self::wrapping::{OverflowingOps, WrappingOps};
2020
use char::CharExt;
2121
use clone::Clone;
2222
use cmp::{PartialEq, Eq, PartialOrd, Ord};
23-
use error::Error;
2423
use fmt;
2524
use intrinsics;
2625
use iter::Iterator;
@@ -2948,16 +2947,9 @@ enum IntErrorKind {
29482947
Underflow,
29492948
}
29502949

2951-
#[stable(feature = "rust1", since = "1.0.0")]
2952-
impl fmt::Display for ParseIntError {
2953-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2954-
self.description().fmt(f)
2955-
}
2956-
}
2957-
2958-
#[stable(feature = "rust1", since = "1.0.0")]
2959-
impl Error for ParseIntError {
2960-
fn description(&self) -> &str {
2950+
impl ParseIntError {
2951+
#[unstable(feature = "core", reason = "available through Error trait")]
2952+
pub fn description(&self) -> &str {
29612953
match self.kind {
29622954
IntErrorKind::Empty => "cannot parse integer from empty string",
29632955
IntErrorKind::InvalidDigit => "invalid digit found in string",
@@ -2967,6 +2959,13 @@ impl Error for ParseIntError {
29672959
}
29682960
}
29692961

2962+
#[stable(feature = "rust1", since = "1.0.0")]
2963+
impl fmt::Display for ParseIntError {
2964+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2965+
self.description().fmt(f)
2966+
}
2967+
}
2968+
29702969
/// An error which can be returned when parsing a float.
29712970
#[derive(Debug, Clone, PartialEq)]
29722971
#[stable(feature = "rust1", since = "1.0.0")]
@@ -2978,19 +2977,19 @@ enum FloatErrorKind {
29782977
Invalid,
29792978
}
29802979

2981-
#[stable(feature = "rust1", since = "1.0.0")]
2982-
impl fmt::Display for ParseFloatError {
2983-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2984-
self.description().fmt(f)
2985-
}
2986-
}
2987-
2988-
#[stable(feature = "rust1", since = "1.0.0")]
2989-
impl Error for ParseFloatError {
2990-
fn description(&self) -> &str {
2980+
impl ParseFloatError {
2981+
#[unstable(feature = "core", reason = "available through Error trait")]
2982+
pub fn description(&self) -> &str {
29912983
match self.kind {
29922984
FloatErrorKind::Empty => "cannot parse float from empty string",
29932985
FloatErrorKind::Invalid => "invalid float literal",
29942986
}
29952987
}
29962988
}
2989+
2990+
#[stable(feature = "rust1", since = "1.0.0")]
2991+
impl fmt::Display for ParseFloatError {
2992+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2993+
self.description().fmt(f)
2994+
}
2995+
}

‎src/libcore/str/mod.rs

-16
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use char::CharExt;
2222
use clone::Clone;
2323
use cmp::{self, Eq};
2424
use default::Default;
25-
use error::Error;
2625
use fmt;
2726
use iter::ExactSizeIterator;
2827
use iter::{Map, Iterator, DoubleEndedIterator};
@@ -192,11 +191,6 @@ impl fmt::Display for ParseBoolError {
192191
}
193192
}
194193

195-
#[stable(feature = "rust1", since = "1.0.0")]
196-
impl Error for ParseBoolError {
197-
fn description(&self) -> &str { "failed to parse bool" }
198-
}
199-
200194
/*
201195
Section: Creating a string
202196
*/
@@ -241,16 +235,6 @@ pub unsafe fn from_utf8_unchecked<'a>(v: &'a [u8]) -> &'a str {
241235
mem::transmute(v)
242236
}
243237

244-
#[stable(feature = "rust1", since = "1.0.0")]
245-
impl Error for Utf8Error {
246-
fn description(&self) -> &str {
247-
match *self {
248-
Utf8Error::TooShort => "invalid utf-8: not enough bytes",
249-
Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
250-
}
251-
}
252-
}
253-
254238
#[stable(feature = "rust1", since = "1.0.0")]
255239
impl fmt::Display for Utf8Error {
256240
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

‎src/libstd/error.rs

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Traits for working with Errors.
12+
//!
13+
//! # The `Error` trait
14+
//!
15+
//! `Error` is a trait representing the basic expectations for error values,
16+
//! i.e. values of type `E` in `Result<T, E>`. At a minimum, errors must provide
17+
//! a description, but they may optionally provide additional detail (via
18+
//! `Display`) and cause chain information:
19+
//!
20+
//! ```
21+
//! use std::fmt::Display;
22+
//!
23+
//! trait Error: Display {
24+
//! fn description(&self) -> &str;
25+
//!
26+
//! fn cause(&self) -> Option<&Error> { None }
27+
//! }
28+
//! ```
29+
//!
30+
//! The `cause` method is generally used when errors cross "abstraction
31+
//! boundaries", i.e. when a one module must report an error that is "caused"
32+
//! by an error from a lower-level module. This setup makes it possible for the
33+
//! high-level module to provide its own errors that do not commit to any
34+
//! particular implementation, but also reveal some of its implementation for
35+
//! debugging via `cause` chains.
36+
37+
#![stable(feature = "rust1", since = "1.0.0")]
38+
39+
// A note about crates and the facade:
40+
//
41+
// Originally, the `Error` trait was defined in libcore, and the impls
42+
// were scattered about. However, coherence objected to this
43+
// arrangement, because to create the blanket impls for `Box` required
44+
// knowing that `&str: !Error`, and we have no means to deal with that
45+
// sort of conflict just now. Therefore, for the time being, we have
46+
// moved the `Error` trait into libstd. As we evolve a sol'n to the
47+
// coherence challenge (e.g., specialization, neg impls, etc) we can
48+
// reconsider what crate these items belong in.
49+
50+
use boxed::Box;
51+
use convert::From;
52+
use fmt::{self, Debug, Display};
53+
use marker::Send;
54+
use num;
55+
use option::Option;
56+
use option::Option::None;
57+
use str;
58+
use string::{self, String};
59+
60+
/// Base functionality for all errors in Rust.
61+
#[stable(feature = "rust1", since = "1.0.0")]
62+
pub trait Error: Debug + Display {
63+
/// A short description of the error.
64+
///
65+
/// The description should not contain newlines or sentence-ending
66+
/// punctuation, to facilitate embedding in larger user-facing
67+
/// strings.
68+
#[stable(feature = "rust1", since = "1.0.0")]
69+
fn description(&self) -> &str;
70+
71+
/// The lower-level cause of this error, if any.
72+
#[stable(feature = "rust1", since = "1.0.0")]
73+
fn cause(&self) -> Option<&Error> { None }
74+
}
75+
76+
#[stable(feature = "rust1", since = "1.0.0")]
77+
impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
78+
fn from(err: E) -> Box<Error + 'a> {
79+
Box::new(err)
80+
}
81+
}
82+
83+
#[stable(feature = "rust1", since = "1.0.0")]
84+
impl<'a, E: Error + Send + 'a> From<E> for Box<Error + Send + 'a> {
85+
fn from(err: E) -> Box<Error + Send + 'a> {
86+
Box::new(err)
87+
}
88+
}
89+
90+
#[stable(feature = "rust1", since = "1.0.0")]
91+
impl<'a, 'b> From<&'b str> for Box<Error + Send + 'a> {
92+
fn from(err: &'b str) -> Box<Error + Send + 'a> {
93+
#[derive(Debug)]
94+
struct StringError(String);
95+
96+
impl Error for StringError {
97+
fn description(&self) -> &str { &self.0 }
98+
}
99+
100+
impl Display for StringError {
101+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102+
Display::fmt(&self.0, f)
103+
}
104+
}
105+
106+
Box::new(StringError(String::from_str(err)))
107+
}
108+
}
109+
110+
#[stable(feature = "rust1", since = "1.0.0")]
111+
impl Error for str::ParseBoolError {
112+
fn description(&self) -> &str { "failed to parse bool" }
113+
}
114+
115+
#[stable(feature = "rust1", since = "1.0.0")]
116+
impl Error for str::Utf8Error {
117+
fn description(&self) -> &str {
118+
match *self {
119+
str::Utf8Error::TooShort => "invalid utf-8: not enough bytes",
120+
str::Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
121+
}
122+
}
123+
}
124+
125+
#[stable(feature = "rust1", since = "1.0.0")]
126+
impl Error for num::ParseIntError {
127+
fn description(&self) -> &str {
128+
self.description()
129+
}
130+
}
131+
132+
#[stable(feature = "rust1", since = "1.0.0")]
133+
impl Error for num::ParseFloatError {
134+
fn description(&self) -> &str {
135+
self.description()
136+
}
137+
}
138+
139+
#[stable(feature = "rust1", since = "1.0.0")]
140+
impl Error for string::FromUtf8Error {
141+
fn description(&self) -> &str {
142+
"invalid utf-8"
143+
}
144+
}
145+
146+
#[stable(feature = "rust1", since = "1.0.0")]
147+
impl Error for string::FromUtf16Error {
148+
fn description(&self) -> &str {
149+
"invalid utf-16"
150+
}
151+
}
152+

‎src/libstd/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ pub use core::raw;
183183
pub use core::simd;
184184
pub use core::result;
185185
pub use core::option;
186-
pub use core::error;
186+
pub mod error;
187187

188188
#[cfg(not(test))] pub use alloc::boxed;
189189
pub use alloc::rc;

0 commit comments

Comments
 (0)
Please sign in to comment.