Skip to content

Commit bf7611d

Browse files
committed
Move error trait into core
1 parent e0dc8d7 commit bf7611d

File tree

25 files changed

+1264
-226
lines changed

25 files changed

+1264
-226
lines changed

Diff for: library/alloc/src/boxed.rs

+306
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};
@@ -174,6 +176,9 @@ 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+
#[cfg(not(no_global_oom_handling))]
181+
use crate::string::String;
177182
#[cfg(not(no_global_oom_handling))]
178183
use crate::vec::Vec;
179184

@@ -2085,3 +2090,304 @@ 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+
#[cfg(not(no_global_oom_handling))]
2144+
#[stable(feature = "rust1", since = "1.0.0")]
2145+
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
2146+
/// Converts a type of [`Error`] into a box of dyn [`Error`].
2147+
///
2148+
/// # Examples
2149+
///
2150+
/// ```
2151+
/// use std::error::Error;
2152+
/// use std::fmt;
2153+
/// use std::mem;
2154+
///
2155+
/// #[derive(Debug)]
2156+
/// struct AnError;
2157+
///
2158+
/// impl fmt::Display for AnError {
2159+
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2160+
/// write!(f, "An error")
2161+
/// }
2162+
/// }
2163+
///
2164+
/// impl Error for AnError {}
2165+
///
2166+
/// let an_error = AnError;
2167+
/// assert!(0 == mem::size_of_val(&an_error));
2168+
/// let a_boxed_error = Box::<dyn Error>::from(an_error);
2169+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
2170+
/// ```
2171+
fn from(err: E) -> Box<dyn Error + 'a> {
2172+
Box::new(err)
2173+
}
2174+
}
2175+
2176+
#[cfg(not(bootstrap))]
2177+
#[cfg(not(no_global_oom_handling))]
2178+
#[stable(feature = "rust1", since = "1.0.0")]
2179+
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
2180+
/// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
2181+
/// dyn [`Error`] + [`Send`] + [`Sync`].
2182+
///
2183+
/// # Examples
2184+
///
2185+
/// ```
2186+
/// use std::error::Error;
2187+
/// use std::fmt;
2188+
/// use std::mem;
2189+
///
2190+
/// #[derive(Debug)]
2191+
/// struct AnError;
2192+
///
2193+
/// impl fmt::Display for AnError {
2194+
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2195+
/// write!(f, "An error")
2196+
/// }
2197+
/// }
2198+
///
2199+
/// impl Error for AnError {}
2200+
///
2201+
/// unsafe impl Send for AnError {}
2202+
///
2203+
/// unsafe impl Sync for AnError {}
2204+
///
2205+
/// let an_error = AnError;
2206+
/// assert!(0 == mem::size_of_val(&an_error));
2207+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
2208+
/// assert!(
2209+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
2210+
/// ```
2211+
fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
2212+
Box::new(err)
2213+
}
2214+
}
2215+
2216+
#[cfg(not(bootstrap))]
2217+
#[cfg(not(no_global_oom_handling))]
2218+
#[stable(feature = "rust1", since = "1.0.0")]
2219+
impl From<String> for Box<dyn Error + Send + Sync> {
2220+
/// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
2221+
///
2222+
/// # Examples
2223+
///
2224+
/// ```
2225+
/// use std::error::Error;
2226+
/// use std::mem;
2227+
///
2228+
/// let a_string_error = "a string error".to_string();
2229+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
2230+
/// assert!(
2231+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
2232+
/// ```
2233+
#[inline]
2234+
fn from(err: String) -> Box<dyn Error + Send + Sync> {
2235+
struct StringError(String);
2236+
2237+
impl Error for StringError {
2238+
#[allow(deprecated)]
2239+
fn description(&self) -> &str {
2240+
&self.0
2241+
}
2242+
}
2243+
2244+
impl fmt::Display for StringError {
2245+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2246+
fmt::Display::fmt(&self.0, f)
2247+
}
2248+
}
2249+
2250+
// Purposefully skip printing "StringError(..)"
2251+
impl fmt::Debug for StringError {
2252+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2253+
fmt::Debug::fmt(&self.0, f)
2254+
}
2255+
}
2256+
2257+
Box::new(StringError(err))
2258+
}
2259+
}
2260+
2261+
#[cfg(not(bootstrap))]
2262+
#[cfg(not(no_global_oom_handling))]
2263+
#[stable(feature = "string_box_error", since = "1.6.0")]
2264+
impl From<String> for Box<dyn Error> {
2265+
/// Converts a [`String`] into a box of dyn [`Error`].
2266+
///
2267+
/// # Examples
2268+
///
2269+
/// ```
2270+
/// use std::error::Error;
2271+
/// use std::mem;
2272+
///
2273+
/// let a_string_error = "a string error".to_string();
2274+
/// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
2275+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
2276+
/// ```
2277+
fn from(str_err: String) -> Box<dyn Error> {
2278+
let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
2279+
let err2: Box<dyn Error> = err1;
2280+
err2
2281+
}
2282+
}
2283+
2284+
#[cfg(not(bootstrap))]
2285+
#[cfg(not(no_global_oom_handling))]
2286+
#[stable(feature = "rust1", since = "1.0.0")]
2287+
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
2288+
/// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
2289+
///
2290+
/// [`str`]: prim@str
2291+
///
2292+
/// # Examples
2293+
///
2294+
/// ```
2295+
/// use std::error::Error;
2296+
/// use std::mem;
2297+
///
2298+
/// let a_str_error = "a str error";
2299+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
2300+
/// assert!(
2301+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
2302+
/// ```
2303+
#[inline]
2304+
fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
2305+
From::from(String::from(err))
2306+
}
2307+
}
2308+
2309+
#[cfg(not(bootstrap))]
2310+
#[cfg(not(no_global_oom_handling))]
2311+
#[stable(feature = "string_box_error", since = "1.6.0")]
2312+
impl From<&str> for Box<dyn Error> {
2313+
/// Converts a [`str`] into a box of dyn [`Error`].
2314+
///
2315+
/// [`str`]: prim@str
2316+
///
2317+
/// # Examples
2318+
///
2319+
/// ```
2320+
/// use std::error::Error;
2321+
/// use std::mem;
2322+
///
2323+
/// let a_str_error = "a str error";
2324+
/// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
2325+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
2326+
/// ```
2327+
fn from(err: &str) -> Box<dyn Error> {
2328+
From::from(String::from(err))
2329+
}
2330+
}
2331+
2332+
#[cfg(not(bootstrap))]
2333+
#[cfg(not(no_global_oom_handling))]
2334+
#[stable(feature = "cow_box_error", since = "1.22.0")]
2335+
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
2336+
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
2337+
///
2338+
/// # Examples
2339+
///
2340+
/// ```
2341+
/// use std::error::Error;
2342+
/// use std::mem;
2343+
/// use std::borrow::Cow;
2344+
///
2345+
/// let a_cow_str_error = Cow::from("a str error");
2346+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
2347+
/// assert!(
2348+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
2349+
/// ```
2350+
fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
2351+
From::from(String::from(err))
2352+
}
2353+
}
2354+
2355+
#[cfg(not(bootstrap))]
2356+
#[cfg(not(no_global_oom_handling))]
2357+
#[stable(feature = "cow_box_error", since = "1.22.0")]
2358+
impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
2359+
/// Converts a [`Cow`] into a box of dyn [`Error`].
2360+
///
2361+
/// # Examples
2362+
///
2363+
/// ```
2364+
/// use std::error::Error;
2365+
/// use std::mem;
2366+
/// use std::borrow::Cow;
2367+
///
2368+
/// let a_cow_str_error = Cow::from("a str error");
2369+
/// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
2370+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
2371+
/// ```
2372+
fn from(err: Cow<'a, str>) -> Box<dyn Error> {
2373+
From::from(String::from(err))
2374+
}
2375+
}
2376+
2377+
#[cfg(not(bootstrap))]
2378+
#[stable(feature = "box_error", since = "1.8.0")]
2379+
impl<T: core::error::Error> core::error::Error for Box<T> {
2380+
#[allow(deprecated, deprecated_in_future)]
2381+
fn description(&self) -> &str {
2382+
core::error::Error::description(&**self)
2383+
}
2384+
2385+
#[allow(deprecated)]
2386+
fn cause(&self) -> Option<&dyn core::error::Error> {
2387+
core::error::Error::cause(&**self)
2388+
}
2389+
2390+
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
2391+
core::error::Error::source(&**self)
2392+
}
2393+
}

Diff for: library/alloc/src/boxed/thin.rs

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// https://github.com/matthieu-m/rfc2580/blob/b58d1d3cba0d4b5e859d3617ea2d0943aaa31329/examples/thin.rs
33
// by matthieu-m
44
use crate::alloc::{self, Layout, LayoutError};
5+
#[cfg(not(bootstrap))]
6+
use core::error::Error;
57
use core::fmt::{self, Debug, Display, Formatter};
68
use core::marker::PhantomData;
79
#[cfg(not(no_global_oom_handling))]
@@ -271,3 +273,11 @@ impl<H> WithHeader<H> {
271273
Layout::new::<H>().extend(value_layout)
272274
}
273275
}
276+
277+
#[cfg(not(bootstrap))]
278+
#[unstable(feature = "thin_box", issue = "92791")]
279+
impl<T: ?Sized + Error> Error for ThinBox<T> {
280+
fn source(&self) -> Option<&(dyn Error + 'static)> {
281+
self.deref().source()
282+
}
283+
}

Diff for: library/alloc/src/collections/btree/map/entry.rs

+11
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ impl<'a, K: Debug + Ord, V: Debug, A: Allocator + Clone> fmt::Display
133133
}
134134
}
135135

136+
#[cfg(not(bootstrap))]
137+
#[unstable(feature = "map_try_insert", issue = "82766")]
138+
impl<'a, K: core::fmt::Debug + Ord, V: core::fmt::Debug> core::error::Error
139+
for crate::collections::btree_map::OccupiedError<'a, K, V>
140+
{
141+
#[allow(deprecated)]
142+
fn description(&self) -> &str {
143+
"key already exists"
144+
}
145+
}
146+
136147
impl<'a, K: Ord, V, A: Allocator + Clone> Entry<'a, K, V, A> {
137148
/// Ensures a value is in the entry by inserting the default if empty, and returns
138149
/// a mutable reference to the value in the entry.

Diff for: library/alloc/src/collections/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,7 @@ trait SpecExtend<I: IntoIterator> {
152152
/// Extends `self` with the contents of the given iterator.
153153
fn spec_extend(&mut self, iter: I);
154154
}
155+
156+
#[cfg(not(bootstrap))]
157+
#[stable(feature = "try_reserve", since = "1.57.0")]
158+
impl core::error::Error for TryReserveError {}

0 commit comments

Comments
 (0)