Skip to content

Commit 0afce62

Browse files
committed
Move error trait into core
1 parent 4493a0f commit 0afce62

File tree

7 files changed

+1533
-646
lines changed

7 files changed

+1533
-646
lines changed

library/alloc/src/boxed.rs

+281-1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ use core::async_iter::AsyncIterator;
151151
use core::borrow;
152152
use core::cmp::Ordering;
153153
use core::convert::{From, TryFrom};
154+
#[cfg(not(bootstrap))]
155+
use core::error::Error;
154156
use core::fmt;
155157
use core::future::Future;
156158
use core::hash::{Hash, Hasher};
@@ -169,11 +171,13 @@ use core::task::{Context, Poll};
169171
#[cfg(not(no_global_oom_handling))]
170172
use crate::alloc::{handle_alloc_error, WriteCloneIntoRaw};
171173
use crate::alloc::{AllocError, Allocator, Global, Layout};
172-
#[cfg(not(no_global_oom_handling))]
174+
#[cfg(any(not(no_global_oom_handling), not(bootstrap)))]
173175
use crate::borrow::Cow;
174176
use crate::raw_vec::RawVec;
175177
#[cfg(not(no_global_oom_handling))]
176178
use crate::str::from_boxed_utf8_unchecked;
179+
#[cfg(not(bootstrap))]
180+
use crate::string::String;
177181
#[cfg(not(no_global_oom_handling))]
178182
use crate::vec::Vec;
179183

@@ -188,6 +192,7 @@ mod thin;
188192
#[lang = "owned_box"]
189193
#[fundamental]
190194
#[stable(feature = "rust1", since = "1.0.0")]
195+
// #[rustc_strict_coherence]
191196
// The declaration of the `Box` struct must be kept in sync with the
192197
// `alloc::alloc::box_free` function or ICEs will happen. See the comment
193198
// on `box_free` for more details.
@@ -2085,3 +2090,278 @@ impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for Box<S> {
20852090
(**self).size_hint()
20862091
}
20872092
}
2093+
2094+
#[cfg(not(bootstrap))]
2095+
impl dyn Error {
2096+
#[inline]
2097+
#[stable(feature = "error_downcast", since = "1.3.0")]
2098+
#[rustc_allow_incoherent_impl]
2099+
/// Attempts to downcast the box to a concrete type.
2100+
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {
2101+
if self.is::<T>() {
2102+
unsafe {
2103+
let raw: *mut dyn Error = Box::into_raw(self);
2104+
Ok(Box::from_raw(raw as *mut T))
2105+
}
2106+
} else {
2107+
Err(self)
2108+
}
2109+
}
2110+
}
2111+
2112+
#[cfg(not(bootstrap))]
2113+
impl dyn Error + Send {
2114+
#[inline]
2115+
#[stable(feature = "error_downcast", since = "1.3.0")]
2116+
#[rustc_allow_incoherent_impl]
2117+
/// Attempts to downcast the box to a concrete type.
2118+
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
2119+
let err: Box<dyn Error> = self;
2120+
<dyn Error>::downcast(err).map_err(|s| unsafe {
2121+
// Reapply the `Send` marker.
2122+
mem::transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
2123+
})
2124+
}
2125+
}
2126+
2127+
#[cfg(not(bootstrap))]
2128+
impl dyn Error + Send + Sync {
2129+
#[inline]
2130+
#[stable(feature = "error_downcast", since = "1.3.0")]
2131+
#[rustc_allow_incoherent_impl]
2132+
/// Attempts to downcast the box to a concrete type.
2133+
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
2134+
let err: Box<dyn Error> = self;
2135+
<dyn Error>::downcast(err).map_err(|s| unsafe {
2136+
// Reapply the `Send + Sync` marker.
2137+
mem::transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
2138+
})
2139+
}
2140+
}
2141+
2142+
#[cfg(not(bootstrap))]
2143+
#[stable(feature = "rust1", since = "1.0.0")]
2144+
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
2145+
/// Converts a type of [`Error`] into a box of dyn [`Error`].
2146+
///
2147+
/// # Examples
2148+
///
2149+
/// ```
2150+
/// use std::error::Error;
2151+
/// use std::fmt;
2152+
/// use std::mem;
2153+
///
2154+
/// #[derive(Debug)]
2155+
/// struct AnError;
2156+
///
2157+
/// impl fmt::Display for AnError {
2158+
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2159+
/// write!(f, "An error")
2160+
/// }
2161+
/// }
2162+
///
2163+
/// impl Error for AnError {}
2164+
///
2165+
/// let an_error = AnError;
2166+
/// assert!(0 == mem::size_of_val(&an_error));
2167+
/// let a_boxed_error = Box::<dyn Error>::from(an_error);
2168+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
2169+
/// ```
2170+
fn from(err: E) -> Box<dyn Error + 'a> {
2171+
Box::new(err)
2172+
}
2173+
}
2174+
2175+
#[cfg(not(bootstrap))]
2176+
#[stable(feature = "rust1", since = "1.0.0")]
2177+
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
2178+
/// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
2179+
/// dyn [`Error`] + [`Send`] + [`Sync`].
2180+
///
2181+
/// # Examples
2182+
///
2183+
/// ```
2184+
/// use std::error::Error;
2185+
/// use std::fmt;
2186+
/// use std::mem;
2187+
///
2188+
/// #[derive(Debug)]
2189+
/// struct AnError;
2190+
///
2191+
/// impl fmt::Display for AnError {
2192+
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2193+
/// write!(f, "An error")
2194+
/// }
2195+
/// }
2196+
///
2197+
/// impl Error for AnError {}
2198+
///
2199+
/// unsafe impl Send for AnError {}
2200+
///
2201+
/// unsafe impl Sync for AnError {}
2202+
///
2203+
/// let an_error = AnError;
2204+
/// assert!(0 == mem::size_of_val(&an_error));
2205+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
2206+
/// assert!(
2207+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
2208+
/// ```
2209+
fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
2210+
Box::new(err)
2211+
}
2212+
}
2213+
2214+
#[cfg(not(bootstrap))]
2215+
#[stable(feature = "rust1", since = "1.0.0")]
2216+
impl From<String> for Box<dyn Error + Send + Sync> {
2217+
/// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
2218+
///
2219+
/// # Examples
2220+
///
2221+
/// ```
2222+
/// use std::error::Error;
2223+
/// use std::mem;
2224+
///
2225+
/// let a_string_error = "a string error".to_string();
2226+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
2227+
/// assert!(
2228+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
2229+
/// ```
2230+
#[inline]
2231+
fn from(err: String) -> Box<dyn Error + Send + Sync> {
2232+
struct StringError(String);
2233+
2234+
impl Error for StringError {
2235+
#[allow(deprecated)]
2236+
fn description(&self) -> &str {
2237+
&self.0
2238+
}
2239+
}
2240+
2241+
impl fmt::Display for StringError {
2242+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2243+
fmt::Display::fmt(&self.0, f)
2244+
}
2245+
}
2246+
2247+
// Purposefully skip printing "StringError(..)"
2248+
impl fmt::Debug for StringError {
2249+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2250+
fmt::Debug::fmt(&self.0, f)
2251+
}
2252+
}
2253+
2254+
Box::new(StringError(err))
2255+
}
2256+
}
2257+
2258+
#[cfg(not(bootstrap))]
2259+
#[stable(feature = "string_box_error", since = "1.6.0")]
2260+
impl From<String> for Box<dyn Error> {
2261+
/// Converts a [`String`] into a box of dyn [`Error`].
2262+
///
2263+
/// # Examples
2264+
///
2265+
/// ```
2266+
/// use std::error::Error;
2267+
/// use std::mem;
2268+
///
2269+
/// let a_string_error = "a string error".to_string();
2270+
/// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
2271+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
2272+
/// ```
2273+
fn from(str_err: String) -> Box<dyn Error> {
2274+
let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
2275+
let err2: Box<dyn Error> = err1;
2276+
err2
2277+
}
2278+
}
2279+
2280+
#[cfg(not(bootstrap))]
2281+
#[stable(feature = "rust1", since = "1.0.0")]
2282+
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
2283+
/// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
2284+
///
2285+
/// [`str`]: prim@str
2286+
///
2287+
/// # Examples
2288+
///
2289+
/// ```
2290+
/// use std::error::Error;
2291+
/// use std::mem;
2292+
///
2293+
/// let a_str_error = "a str error";
2294+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
2295+
/// assert!(
2296+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
2297+
/// ```
2298+
#[inline]
2299+
fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
2300+
From::from(String::from(err))
2301+
}
2302+
}
2303+
2304+
#[cfg(not(bootstrap))]
2305+
#[stable(feature = "string_box_error", since = "1.6.0")]
2306+
impl From<&str> for Box<dyn Error> {
2307+
/// Converts a [`str`] into a box of dyn [`Error`].
2308+
///
2309+
/// [`str`]: prim@str
2310+
///
2311+
/// # Examples
2312+
///
2313+
/// ```
2314+
/// use std::error::Error;
2315+
/// use std::mem;
2316+
///
2317+
/// let a_str_error = "a str error";
2318+
/// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
2319+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
2320+
/// ```
2321+
fn from(err: &str) -> Box<dyn Error> {
2322+
From::from(String::from(err))
2323+
}
2324+
}
2325+
2326+
#[cfg(not(bootstrap))]
2327+
#[stable(feature = "cow_box_error", since = "1.22.0")]
2328+
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
2329+
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
2330+
///
2331+
/// # Examples
2332+
///
2333+
/// ```
2334+
/// use std::error::Error;
2335+
/// use std::mem;
2336+
/// use std::borrow::Cow;
2337+
///
2338+
/// let a_cow_str_error = Cow::from("a str error");
2339+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
2340+
/// assert!(
2341+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
2342+
/// ```
2343+
fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
2344+
From::from(String::from(err))
2345+
}
2346+
}
2347+
2348+
#[cfg(not(bootstrap))]
2349+
#[stable(feature = "cow_box_error", since = "1.22.0")]
2350+
impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
2351+
/// Converts a [`Cow`] into a box of dyn [`Error`].
2352+
///
2353+
/// # Examples
2354+
///
2355+
/// ```
2356+
/// use std::error::Error;
2357+
/// use std::mem;
2358+
/// use std::borrow::Cow;
2359+
///
2360+
/// let a_cow_str_error = Cow::from("a str error");
2361+
/// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
2362+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
2363+
/// ```
2364+
fn from(err: Cow<'a, str>) -> Box<dyn Error> {
2365+
From::from(String::from(err))
2366+
}
2367+
}

library/alloc/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
#![feature(const_pin)]
112112
#![feature(cstr_from_bytes_until_nul)]
113113
#![feature(dispatch_from_dyn)]
114+
#![cfg_attr(not(bootstrap), feature(error_in_core))]
114115
#![feature(exact_size_is_empty)]
115116
#![feature(extend_one)]
116117
#![feature(fmt_internals)]
@@ -178,6 +179,7 @@
178179
#![feature(unboxed_closures)]
179180
#![feature(unsized_fn_params)]
180181
#![feature(c_unwind)]
182+
#![feature(with_negative_coherence)]
181183
//
182184
// Rustdoc features:
183185
#![feature(doc_cfg)]

0 commit comments

Comments
 (0)