Skip to content

Commit 22c581b

Browse files
committed
Implement TryFrom for array box types
This commit serves to provide the same benefits as PR #44764 except for boxes that refer to owned arrays allocated in the heap.
1 parent b65f0be commit 22c581b

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/liballoc/boxed.rs

+61
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ use raw_vec::RawVec;
6161
use core::any::Any;
6262
use core::borrow;
6363
use core::cmp::Ordering;
64+
use core::convert::TryFrom;
6465
use core::fmt;
6566
use core::hash::{self, Hash, Hasher};
6667
use core::iter::FusedIterator;
@@ -623,6 +624,66 @@ impl From<Box<str>> for Box<[u8]> {
623624
}
624625
}
625626

627+
/// The error type returned when a conversion from a boxed slice to a boxed
628+
/// array fails.
629+
#[unstable(feature = "try_from", issue = "33417")]
630+
#[derive(Debug, Copy, Clone)]
631+
pub struct TryFromSliceError<T>(Box<[T]>);
632+
633+
impl<T> fmt::Display for TryFromSliceError<T> {
634+
#[inline]
635+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
636+
fmt::Display::fmt(self.__description(), f)
637+
}
638+
}
639+
640+
impl<T> TryFromSliceError<T> {
641+
#[unstable(feature = "array_error_internals",
642+
reason = "available through Error trait and this method should not \
643+
be exposed publicly",
644+
issue = "0")]
645+
#[inline]
646+
#[doc(hidden)]
647+
pub fn __description(&self) -> &str {
648+
"could not convert boxed slice to boxed array"
649+
}
650+
651+
/// Returns the boxed slice that was attempted to convert to a boxed array.
652+
///
653+
/// This method is meant to avoid allocation. It will consume the error,
654+
/// moving out the boxed slice, so that a copy of the slice does not need to
655+
/// be made.
656+
#[inline]
657+
pub fn into_boxed_slice(self) -> Box<[T]> {
658+
self.0
659+
}
660+
}
661+
662+
macro_rules! array_impls {
663+
($($N:expr)+) => {
664+
#[unstable(feature = "try_from", issue = "33417")]
665+
impl<T> TryFrom<Box<[T]>> for Box<[T; $N]> {
666+
type Error = TryFromSliceError<T>;
667+
668+
fn try_from(slice: Box<[T]>) -> Result<Box<[T; $N]>, TryFromSliceError<T>> {
669+
if slice.len() == $N {
670+
let ptr = Box::into_raw(slice) as *mut [T; $N];
671+
unsafe { Ok(Box::from_raw(ptr)) }
672+
} else {
673+
Err(TryFromSliceError(slice))
674+
}
675+
}
676+
}
677+
}
678+
}
679+
680+
array_impls! {
681+
0 1 2 3 4 5 6 7 8 9
682+
10 11 12 13 14 15 16 17 18 19
683+
20 21 22 23 24 25 26 27 28 29
684+
30 31 32
685+
}
686+
626687
impl Box<Any> {
627688
#[inline]
628689
#[stable(feature = "rust1", since = "1.0.0")]

src/libstd/error.rs

+7
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,13 @@ impl Error for array::TryFromSliceError {
290290
}
291291
}
292292

293+
#[unstable(feature = "try_from", issue = "33417")]
294+
impl<T> Error for boxed::TryFromSliceError<T> {
295+
fn description(&self) -> &str {
296+
self.__description()
297+
}
298+
}
299+
293300
#[stable(feature = "rust1", since = "1.0.0")]
294301
impl Error for num::ParseFloatError {
295302
fn description(&self) -> &str {

0 commit comments

Comments
 (0)