alloc/boxed/convert.rs
1use core::any::Any;
2#[cfg(not(no_global_oom_handling))]
3use core::clone::TrivialClone;
4use core::error::Error;
5use core::mem;
6use core::pin::Pin;
7#[cfg(not(no_global_oom_handling))]
8use core::{fmt, ptr};
9
10use crate::alloc::Allocator;
11#[cfg(not(no_global_oom_handling))]
12use crate::borrow::Cow;
13use crate::boxed::Box;
14#[cfg(not(no_global_oom_handling))]
15use crate::raw_vec::RawVec;
16#[cfg(not(no_global_oom_handling))]
17use crate::str::from_boxed_utf8_unchecked;
18#[cfg(not(no_global_oom_handling))]
19use crate::string::String;
20#[cfg(not(no_global_oom_handling))]
21use crate::vec::Vec;
22
23#[cfg(not(no_global_oom_handling))]
24#[stable(feature = "from_for_ptrs", since = "1.6.0")]
25impl<T> From<T> for Box<T> {
26 /// Converts a `T` into a `Box<T>`
27 ///
28 /// The conversion allocates on the heap and moves `t`
29 /// from the stack into it.
30 ///
31 /// # Examples
32 ///
33 /// ```rust
34 /// let x = 5;
35 /// let boxed = Box::new(5);
36 ///
37 /// assert_eq!(Box::from(x), boxed);
38 /// ```
39 fn from(t: T) -> Self {
40 Box::new(t)
41 }
42}
43
44#[stable(feature = "pin", since = "1.33.0")]
45impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>>
46where
47 A: 'static,
48{
49 /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
50 /// `*boxed` will be pinned in memory and unable to be moved.
51 ///
52 /// This conversion does not allocate on the heap and happens in place.
53 ///
54 /// This is also available via [`Box::into_pin`].
55 ///
56 /// Constructing and pinning a `Box` with <code><Pin<Box\<T>>>::from([Box::new]\(x))</code>
57 /// can also be written more concisely using <code>[Box::pin]\(x)</code>.
58 /// This `From` implementation is useful if you already have a `Box<T>`, or you are
59 /// constructing a (pinned) `Box` in a different way than with [`Box::new`].
60 fn from(boxed: Box<T, A>) -> Self {
61 Box::into_pin(boxed)
62 }
63}
64
65/// Specialization trait used for `From<&[T]>`.
66#[cfg(not(no_global_oom_handling))]
67trait BoxFromSlice<T> {
68 fn from_slice(slice: &[T]) -> Self;
69}
70
71#[cfg(not(no_global_oom_handling))]
72impl<T: Clone> BoxFromSlice<T> for Box<[T]> {
73 #[inline]
74 default fn from_slice(slice: &[T]) -> Self {
75 slice.to_vec().into_boxed_slice()
76 }
77}
78
79#[cfg(not(no_global_oom_handling))]
80impl<T: TrivialClone> BoxFromSlice<T> for Box<[T]> {
81 #[inline]
82 fn from_slice(slice: &[T]) -> Self {
83 let len = slice.len();
84 let buf = RawVec::with_capacity(len);
85 // SAFETY: since `T` implements `TrivialClone`, this is sound and
86 // equivalent to the above.
87 unsafe {
88 ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len);
89 buf.into_box(slice.len()).assume_init()
90 }
91 }
92}
93
94#[cfg(not(no_global_oom_handling))]
95#[stable(feature = "box_from_slice", since = "1.17.0")]
96impl<T: Clone> From<&[T]> for Box<[T]> {
97 /// Converts a `&[T]` into a `Box<[T]>`
98 ///
99 /// This conversion allocates on the heap
100 /// and performs a copy of `slice` and its contents.
101 ///
102 /// # Examples
103 /// ```rust
104 /// // create a &[u8] which will be used to create a Box<[u8]>
105 /// let slice: &[u8] = &[104, 101, 108, 108, 111];
106 /// let boxed_slice: Box<[u8]> = Box::from(slice);
107 ///
108 /// println!("{boxed_slice:?}");
109 /// ```
110 #[inline]
111 fn from(slice: &[T]) -> Box<[T]> {
112 <Self as BoxFromSlice<T>>::from_slice(slice)
113 }
114}
115
116#[cfg(not(no_global_oom_handling))]
117#[stable(feature = "box_from_mut_slice", since = "1.84.0")]
118impl<T: Clone> From<&mut [T]> for Box<[T]> {
119 /// Converts a `&mut [T]` into a `Box<[T]>`
120 ///
121 /// This conversion allocates on the heap
122 /// and performs a copy of `slice` and its contents.
123 ///
124 /// # Examples
125 /// ```rust
126 /// // create a &mut [u8] which will be used to create a Box<[u8]>
127 /// let mut array = [104, 101, 108, 108, 111];
128 /// let slice: &mut [u8] = &mut array;
129 /// let boxed_slice: Box<[u8]> = Box::from(slice);
130 ///
131 /// println!("{boxed_slice:?}");
132 /// ```
133 #[inline]
134 fn from(slice: &mut [T]) -> Box<[T]> {
135 Self::from(&*slice)
136 }
137}
138
139#[cfg(not(no_global_oom_handling))]
140#[stable(feature = "box_from_cow", since = "1.45.0")]
141impl<T: Clone> From<Cow<'_, [T]>> for Box<[T]> {
142 /// Converts a `Cow<'_, [T]>` into a `Box<[T]>`
143 ///
144 /// When `cow` is the `Cow::Borrowed` variant, this
145 /// conversion allocates on the heap and copies the
146 /// underlying slice. Otherwise, it will try to reuse the owned
147 /// `Vec`'s allocation.
148 #[inline]
149 fn from(cow: Cow<'_, [T]>) -> Box<[T]> {
150 match cow {
151 Cow::Borrowed(slice) => Box::from(slice),
152 Cow::Owned(slice) => Box::from(slice),
153 }
154 }
155}
156
157#[cfg(not(no_global_oom_handling))]
158#[stable(feature = "box_from_slice", since = "1.17.0")]
159impl From<&str> for Box<str> {
160 /// Converts a `&str` into a `Box<str>`
161 ///
162 /// This conversion allocates on the heap
163 /// and performs a copy of `s`.
164 ///
165 /// # Examples
166 ///
167 /// ```rust
168 /// let boxed: Box<str> = Box::from("hello");
169 /// println!("{boxed}");
170 /// ```
171 #[inline]
172 fn from(s: &str) -> Box<str> {
173 unsafe { from_boxed_utf8_unchecked(Box::from(s.as_bytes())) }
174 }
175}
176
177#[cfg(not(no_global_oom_handling))]
178#[stable(feature = "box_from_mut_slice", since = "1.84.0")]
179impl From<&mut str> for Box<str> {
180 /// Converts a `&mut str` into a `Box<str>`
181 ///
182 /// This conversion allocates on the heap
183 /// and performs a copy of `s`.
184 ///
185 /// # Examples
186 ///
187 /// ```rust
188 /// let mut original = String::from("hello");
189 /// let original: &mut str = &mut original;
190 /// let boxed: Box<str> = Box::from(original);
191 /// println!("{boxed}");
192 /// ```
193 #[inline]
194 fn from(s: &mut str) -> Box<str> {
195 Self::from(&*s)
196 }
197}
198
199#[cfg(not(no_global_oom_handling))]
200#[stable(feature = "box_from_cow", since = "1.45.0")]
201impl From<Cow<'_, str>> for Box<str> {
202 /// Converts a `Cow<'_, str>` into a `Box<str>`
203 ///
204 /// When `cow` is the `Cow::Borrowed` variant, this
205 /// conversion allocates on the heap and copies the
206 /// underlying `str`. Otherwise, it will try to reuse the owned
207 /// `String`'s allocation.
208 ///
209 /// # Examples
210 ///
211 /// ```rust
212 /// use std::borrow::Cow;
213 ///
214 /// let unboxed = Cow::Borrowed("hello");
215 /// let boxed: Box<str> = Box::from(unboxed);
216 /// println!("{boxed}");
217 /// ```
218 ///
219 /// ```rust
220 /// # use std::borrow::Cow;
221 /// let unboxed = Cow::Owned("hello".to_string());
222 /// let boxed: Box<str> = Box::from(unboxed);
223 /// println!("{boxed}");
224 /// ```
225 #[inline]
226 fn from(cow: Cow<'_, str>) -> Box<str> {
227 match cow {
228 Cow::Borrowed(s) => Box::from(s),
229 Cow::Owned(s) => Box::from(s),
230 }
231 }
232}
233
234#[stable(feature = "boxed_str_conv", since = "1.19.0")]
235impl<A: Allocator> From<Box<str, A>> for Box<[u8], A> {
236 /// Converts a `Box<str>` into a `Box<[u8]>`
237 ///
238 /// This conversion does not allocate on the heap and happens in place.
239 ///
240 /// # Examples
241 /// ```rust
242 /// // create a Box<str> which will be used to create a Box<[u8]>
243 /// let boxed: Box<str> = Box::from("hello");
244 /// let boxed_str: Box<[u8]> = Box::from(boxed);
245 ///
246 /// // create a &[u8] which will be used to create a Box<[u8]>
247 /// let slice: &[u8] = &[104, 101, 108, 108, 111];
248 /// let boxed_slice = Box::from(slice);
249 ///
250 /// assert_eq!(boxed_slice, boxed_str);
251 /// ```
252 #[inline]
253 fn from(s: Box<str, A>) -> Self {
254 let (raw, alloc) = Box::into_raw_with_allocator(s);
255 unsafe { Box::from_raw_in(raw as *mut [u8], alloc) }
256 }
257}
258
259#[cfg(not(no_global_oom_handling))]
260#[stable(feature = "box_from_array", since = "1.45.0")]
261impl<T, const N: usize> From<[T; N]> for Box<[T]> {
262 /// Converts a `[T; N]` into a `Box<[T]>`
263 ///
264 /// This conversion moves the array to newly heap-allocated memory.
265 ///
266 /// # Examples
267 ///
268 /// ```rust
269 /// let boxed: Box<[u8]> = Box::from([4, 2]);
270 /// println!("{boxed:?}");
271 /// ```
272 fn from(array: [T; N]) -> Box<[T]> {
273 Box::new(array)
274 }
275}
276
277/// Casts a boxed slice to a boxed array.
278///
279/// # Safety
280///
281/// `boxed_slice.len()` must be exactly `N`.
282unsafe fn boxed_slice_as_array_unchecked<T, A: Allocator, const N: usize>(
283 boxed_slice: Box<[T], A>,
284) -> Box<[T; N], A> {
285 debug_assert_eq!(boxed_slice.len(), N);
286
287 let (ptr, alloc) = Box::into_raw_with_allocator(boxed_slice);
288 // SAFETY: Pointer and allocator came from an existing box,
289 // and our safety condition requires that the length is exactly `N`
290 unsafe { Box::from_raw_in(ptr as *mut [T; N], alloc) }
291}
292
293#[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
294impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
295 type Error = Box<[T]>;
296
297 /// Attempts to convert a `Box<[T]>` into a `Box<[T; N]>`.
298 ///
299 /// The conversion occurs in-place and does not require a
300 /// new memory allocation.
301 ///
302 /// # Errors
303 ///
304 /// Returns the old `Box<[T]>` in the `Err` variant if
305 /// `boxed_slice.len()` does not equal `N`.
306 fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
307 if boxed_slice.len() == N {
308 Ok(unsafe { boxed_slice_as_array_unchecked(boxed_slice) })
309 } else {
310 Err(boxed_slice)
311 }
312 }
313}
314
315#[cfg(not(no_global_oom_handling))]
316#[stable(feature = "boxed_array_try_from_vec", since = "1.66.0")]
317impl<T, const N: usize> TryFrom<Vec<T>> for Box<[T; N]> {
318 type Error = Vec<T>;
319
320 /// Attempts to convert a `Vec<T>` into a `Box<[T; N]>`.
321 ///
322 /// Like [`Vec::into_boxed_slice`], this is in-place if `vec.capacity() == N`,
323 /// but will require a reallocation otherwise.
324 ///
325 /// # Errors
326 ///
327 /// Returns the original `Vec<T>` in the `Err` variant if
328 /// `boxed_slice.len()` does not equal `N`.
329 ///
330 /// # Examples
331 ///
332 /// This can be used with [`vec!`] to create an array on the heap:
333 ///
334 /// ```
335 /// let state: Box<[f32; 100]> = vec![1.0; 100].try_into().unwrap();
336 /// assert_eq!(state.len(), 100);
337 /// ```
338 fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
339 if vec.len() == N {
340 let boxed_slice = vec.into_boxed_slice();
341 Ok(unsafe { boxed_slice_as_array_unchecked(boxed_slice) })
342 } else {
343 Err(vec)
344 }
345 }
346}
347
348impl<A: Allocator> Box<dyn Any, A> {
349 /// Attempts to downcast the box to a concrete type.
350 ///
351 /// # Examples
352 ///
353 /// ```
354 /// use std::any::Any;
355 ///
356 /// fn print_if_string(value: Box<dyn Any>) {
357 /// if let Ok(string) = value.downcast::<String>() {
358 /// println!("String ({}): {}", string.len(), string);
359 /// }
360 /// }
361 ///
362 /// let my_string = "Hello World".to_string();
363 /// print_if_string(Box::new(my_string));
364 /// print_if_string(Box::new(0i8));
365 /// ```
366 #[inline]
367 #[stable(feature = "rust1", since = "1.0.0")]
368 pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
369 if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
370 }
371
372 /// Downcasts the box to a concrete type.
373 ///
374 /// For a safe alternative see [`downcast`].
375 ///
376 /// # Examples
377 ///
378 /// ```
379 /// #![feature(downcast_unchecked)]
380 ///
381 /// use std::any::Any;
382 ///
383 /// let x: Box<dyn Any> = Box::new(1_usize);
384 ///
385 /// unsafe {
386 /// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
387 /// }
388 /// ```
389 ///
390 /// # Safety
391 ///
392 /// The contained value must be of type `T`. Calling this method
393 /// with the incorrect type is *undefined behavior*.
394 ///
395 /// [`downcast`]: Self::downcast
396 #[inline]
397 #[unstable(feature = "downcast_unchecked", issue = "90850")]
398 pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
399 debug_assert!(self.is::<T>());
400 unsafe {
401 let (raw, alloc): (*mut dyn Any, _) = Box::into_raw_with_allocator(self);
402 Box::from_raw_in(raw as *mut T, alloc)
403 }
404 }
405}
406
407impl<A: Allocator> Box<dyn Any + Send, A> {
408 /// Attempts to downcast the box to a concrete type.
409 ///
410 /// # Examples
411 ///
412 /// ```
413 /// use std::any::Any;
414 ///
415 /// fn print_if_string(value: Box<dyn Any + Send>) {
416 /// if let Ok(string) = value.downcast::<String>() {
417 /// println!("String ({}): {}", string.len(), string);
418 /// }
419 /// }
420 ///
421 /// let my_string = "Hello World".to_string();
422 /// print_if_string(Box::new(my_string));
423 /// print_if_string(Box::new(0i8));
424 /// ```
425 #[inline]
426 #[stable(feature = "rust1", since = "1.0.0")]
427 pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
428 if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
429 }
430
431 /// Downcasts the box to a concrete type.
432 ///
433 /// For a safe alternative see [`downcast`].
434 ///
435 /// # Examples
436 ///
437 /// ```
438 /// #![feature(downcast_unchecked)]
439 ///
440 /// use std::any::Any;
441 ///
442 /// let x: Box<dyn Any + Send> = Box::new(1_usize);
443 ///
444 /// unsafe {
445 /// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
446 /// }
447 /// ```
448 ///
449 /// # Safety
450 ///
451 /// The contained value must be of type `T`. Calling this method
452 /// with the incorrect type is *undefined behavior*.
453 ///
454 /// [`downcast`]: Self::downcast
455 #[inline]
456 #[unstable(feature = "downcast_unchecked", issue = "90850")]
457 pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
458 debug_assert!(self.is::<T>());
459 unsafe {
460 let (raw, alloc): (*mut (dyn Any + Send), _) = Box::into_raw_with_allocator(self);
461 Box::from_raw_in(raw as *mut T, alloc)
462 }
463 }
464}
465
466impl<A: Allocator> Box<dyn Any + Send + Sync, A> {
467 /// Attempts to downcast the box to a concrete type.
468 ///
469 /// # Examples
470 ///
471 /// ```
472 /// use std::any::Any;
473 ///
474 /// fn print_if_string(value: Box<dyn Any + Send + Sync>) {
475 /// if let Ok(string) = value.downcast::<String>() {
476 /// println!("String ({}): {}", string.len(), string);
477 /// }
478 /// }
479 ///
480 /// let my_string = "Hello World".to_string();
481 /// print_if_string(Box::new(my_string));
482 /// print_if_string(Box::new(0i8));
483 /// ```
484 #[inline]
485 #[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")]
486 pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
487 if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
488 }
489
490 /// Downcasts the box to a concrete type.
491 ///
492 /// For a safe alternative see [`downcast`].
493 ///
494 /// # Examples
495 ///
496 /// ```
497 /// #![feature(downcast_unchecked)]
498 ///
499 /// use std::any::Any;
500 ///
501 /// let x: Box<dyn Any + Send + Sync> = Box::new(1_usize);
502 ///
503 /// unsafe {
504 /// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
505 /// }
506 /// ```
507 ///
508 /// # Safety
509 ///
510 /// The contained value must be of type `T`. Calling this method
511 /// with the incorrect type is *undefined behavior*.
512 ///
513 /// [`downcast`]: Self::downcast
514 #[inline]
515 #[unstable(feature = "downcast_unchecked", issue = "90850")]
516 pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
517 debug_assert!(self.is::<T>());
518 unsafe {
519 let (raw, alloc): (*mut (dyn Any + Send + Sync), _) =
520 Box::into_raw_with_allocator(self);
521 Box::from_raw_in(raw as *mut T, alloc)
522 }
523 }
524}
525
526#[cfg(not(no_global_oom_handling))]
527#[stable(feature = "rust1", since = "1.0.0")]
528impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
529 /// Converts a type of [`Error`] into a box of dyn [`Error`].
530 ///
531 /// # Examples
532 ///
533 /// ```
534 /// use std::error::Error;
535 /// use std::fmt;
536 ///
537 /// #[derive(Debug)]
538 /// struct AnError;
539 ///
540 /// impl fmt::Display for AnError {
541 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
542 /// write!(f, "An error")
543 /// }
544 /// }
545 ///
546 /// impl Error for AnError {}
547 ///
548 /// let an_error = AnError;
549 /// assert!(0 == size_of_val(&an_error));
550 /// let a_boxed_error = Box::<dyn Error>::from(an_error);
551 /// assert!(size_of::<Box<dyn Error>>() == size_of_val(&a_boxed_error))
552 /// ```
553 fn from(err: E) -> Box<dyn Error + 'a> {
554 Box::new(err)
555 }
556}
557
558#[cfg(not(no_global_oom_handling))]
559#[stable(feature = "rust1", since = "1.0.0")]
560impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
561 /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
562 /// dyn [`Error`] + [`Send`] + [`Sync`].
563 ///
564 /// # Examples
565 ///
566 /// ```
567 /// use std::error::Error;
568 /// use std::fmt;
569 ///
570 /// #[derive(Debug)]
571 /// struct AnError;
572 ///
573 /// impl fmt::Display for AnError {
574 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
575 /// write!(f, "An error")
576 /// }
577 /// }
578 ///
579 /// impl Error for AnError {}
580 ///
581 /// unsafe impl Send for AnError {}
582 ///
583 /// unsafe impl Sync for AnError {}
584 ///
585 /// let an_error = AnError;
586 /// assert!(0 == size_of_val(&an_error));
587 /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
588 /// assert!(
589 /// size_of::<Box<dyn Error + Send + Sync>>() == size_of_val(&a_boxed_error))
590 /// ```
591 fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
592 Box::new(err)
593 }
594}
595
596#[cfg(not(no_global_oom_handling))]
597#[stable(feature = "rust1", since = "1.0.0")]
598impl<'a> From<String> for Box<dyn Error + Send + Sync + 'a> {
599 /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
600 ///
601 /// # Examples
602 ///
603 /// ```
604 /// use std::error::Error;
605 ///
606 /// let a_string_error = "a string error".to_string();
607 /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
608 /// assert!(
609 /// size_of::<Box<dyn Error + Send + Sync>>() == size_of_val(&a_boxed_error))
610 /// ```
611 #[inline]
612 fn from(err: String) -> Box<dyn Error + Send + Sync + 'a> {
613 struct StringError(String);
614
615 impl Error for StringError {}
616
617 impl fmt::Display for StringError {
618 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
619 fmt::Display::fmt(&self.0, f)
620 }
621 }
622
623 // Purposefully skip printing "StringError(..)"
624 impl fmt::Debug for StringError {
625 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
626 fmt::Debug::fmt(&self.0, f)
627 }
628 }
629
630 Box::new(StringError(err))
631 }
632}
633
634#[cfg(not(no_global_oom_handling))]
635#[stable(feature = "string_box_error", since = "1.6.0")]
636impl<'a> From<String> for Box<dyn Error + 'a> {
637 /// Converts a [`String`] into a box of dyn [`Error`].
638 ///
639 /// # Examples
640 ///
641 /// ```
642 /// use std::error::Error;
643 ///
644 /// let a_string_error = "a string error".to_string();
645 /// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
646 /// assert!(size_of::<Box<dyn Error>>() == size_of_val(&a_boxed_error))
647 /// ```
648 fn from(str_err: String) -> Box<dyn Error + 'a> {
649 let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
650 let err2: Box<dyn Error> = err1;
651 err2
652 }
653}
654
655#[cfg(not(no_global_oom_handling))]
656#[stable(feature = "rust1", since = "1.0.0")]
657impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
658 /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
659 ///
660 /// [`str`]: prim@str
661 ///
662 /// # Examples
663 ///
664 /// ```
665 /// use std::error::Error;
666 ///
667 /// let a_str_error = "a str error";
668 /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
669 /// assert!(
670 /// size_of::<Box<dyn Error + Send + Sync>>() == size_of_val(&a_boxed_error))
671 /// ```
672 #[inline]
673 fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
674 From::from(String::from(err))
675 }
676}
677
678#[cfg(not(no_global_oom_handling))]
679#[stable(feature = "string_box_error", since = "1.6.0")]
680impl<'a> From<&str> for Box<dyn Error + 'a> {
681 /// Converts a [`str`] into a box of dyn [`Error`].
682 ///
683 /// [`str`]: prim@str
684 ///
685 /// # Examples
686 ///
687 /// ```
688 /// use std::error::Error;
689 ///
690 /// let a_str_error = "a str error";
691 /// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
692 /// assert!(size_of::<Box<dyn Error>>() == size_of_val(&a_boxed_error))
693 /// ```
694 fn from(err: &str) -> Box<dyn Error + 'a> {
695 From::from(String::from(err))
696 }
697}
698
699#[cfg(not(no_global_oom_handling))]
700#[stable(feature = "cow_box_error", since = "1.22.0")]
701impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
702 /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
703 ///
704 /// # Examples
705 ///
706 /// ```
707 /// use std::error::Error;
708 /// use std::borrow::Cow;
709 ///
710 /// let a_cow_str_error = Cow::from("a str error");
711 /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
712 /// assert!(
713 /// size_of::<Box<dyn Error + Send + Sync>>() == size_of_val(&a_boxed_error))
714 /// ```
715 fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
716 From::from(String::from(err))
717 }
718}
719
720#[cfg(not(no_global_oom_handling))]
721#[stable(feature = "cow_box_error", since = "1.22.0")]
722impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + 'a> {
723 /// Converts a [`Cow`] into a box of dyn [`Error`].
724 ///
725 /// # Examples
726 ///
727 /// ```
728 /// use std::error::Error;
729 /// use std::borrow::Cow;
730 ///
731 /// let a_cow_str_error = Cow::from("a str error");
732 /// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
733 /// assert!(size_of::<Box<dyn Error>>() == size_of_val(&a_boxed_error))
734 /// ```
735 fn from(err: Cow<'b, str>) -> Box<dyn Error + 'a> {
736 From::from(String::from(err))
737 }
738}
739
740impl dyn Error {
741 /// Attempts to downcast the box to a concrete type.
742 #[inline]
743 #[stable(feature = "error_downcast", since = "1.3.0")]
744 #[rustc_allow_incoherent_impl]
745 pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {
746 if self.is::<T>() {
747 unsafe {
748 let raw: *mut dyn Error = Box::into_raw(self);
749 Ok(Box::from_raw(raw as *mut T))
750 }
751 } else {
752 Err(self)
753 }
754 }
755}
756
757impl dyn Error + Send {
758 /// Attempts to downcast the box to a concrete type.
759 #[inline]
760 #[stable(feature = "error_downcast", since = "1.3.0")]
761 #[rustc_allow_incoherent_impl]
762 pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
763 let err: Box<dyn Error> = self;
764 <dyn Error>::downcast(err).map_err(|s| unsafe {
765 // Reapply the `Send` marker.
766 mem::transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
767 })
768 }
769}
770
771impl dyn Error + Send + Sync {
772 /// Attempts to downcast the box to a concrete type.
773 #[inline]
774 #[stable(feature = "error_downcast", since = "1.3.0")]
775 #[rustc_allow_incoherent_impl]
776 pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
777 let err: Box<dyn Error> = self;
778 <dyn Error>::downcast(err).map_err(|s| unsafe {
779 // Reapply the `Send + Sync` markers.
780 mem::transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
781 })
782 }
783}