提交 a3f62737 编写于 作者: A Alex Crichton

rollup merge of #23867: nikomatsakis/issue-23086-take-3

This PR implements rust-lang/rfcs#1023. In the process it fixes #23086 and #23516. A few impls in libcore had to be updated, but the impact is generally pretty minimal. Most of the fallout is in the tests that probed the limits of today's coherence.

I tested and we were able to build the most popular crates along with iron (modulo errors around errors being sendable).

Fixes #23918.
......@@ -51,15 +51,12 @@
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 @@ fn next_back(&mut self) -> Option<I::Item> { (**self).next_back() }
#[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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
#[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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
#[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 {
......
......@@ -147,7 +147,6 @@
pub mod str;
pub mod hash;
pub mod fmt;
pub mod error;
#[doc(primitive = "bool")]
mod bool {
......
......@@ -20,7 +20,6 @@
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 @@ fn description(&self) -> &str {
}
}
#[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 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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
#[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 {
......
......@@ -36,8 +36,26 @@
#![stable(feature = "rust1", since = "1.0.0")]
use prelude::*;
use fmt::{Debug, Display};
// 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")]
......@@ -54,3 +72,81 @@ pub trait Error: Debug + Display {
#[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::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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册