Add implementations for converting boxed slices into boxed arrays
This mirrors the implementations of reference slices into arrays.
This commit is contained in:
parent
4be0675589
commit
32324d22c3
@ -76,9 +76,10 @@
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use core::any::Any;
|
||||
use core::array::LengthAtMost32;
|
||||
use core::borrow;
|
||||
use core::cmp::Ordering;
|
||||
use core::convert::From;
|
||||
use core::convert::{From, TryFrom};
|
||||
use core::fmt;
|
||||
use core::future::Future;
|
||||
use core::hash::{Hash, Hasher};
|
||||
@ -612,6 +613,22 @@ impl From<Box<str>> for Box<[u8]> {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "boxed_slice_try_from", issue = "0")]
|
||||
impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]>
|
||||
where
|
||||
[T; N]: LengthAtMost32,
|
||||
{
|
||||
type Error = Box<[T]>;
|
||||
|
||||
fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
|
||||
if boxed_slice.len() == N {
|
||||
Ok(unsafe { Box::from_raw(Box::into_raw(boxed_slice) as *mut [T; N]) })
|
||||
} else {
|
||||
Err(boxed_slice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Box<dyn Any> {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -82,9 +82,9 @@
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cfg_target_has_atomic)]
|
||||
#![feature(coerce_unsized)]
|
||||
#![cfg_attr(not(bootstrap), feature(const_in_array_repeat_expressions))]
|
||||
#![feature(const_generic_impls_guard)]
|
||||
#![feature(const_generics)]
|
||||
#![cfg_attr(not(bootstrap), feature(const_in_array_repeat_expressions))]
|
||||
#![feature(dispatch_from_dyn)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(dropck_eyepatch)]
|
||||
|
@ -232,6 +232,7 @@ use crate::boxed::Box;
|
||||
use std::boxed::Box;
|
||||
|
||||
use core::any::Any;
|
||||
use core::array::LengthAtMost32;
|
||||
use core::borrow;
|
||||
use core::cell::Cell;
|
||||
use core::cmp::Ordering;
|
||||
@ -245,7 +246,7 @@ use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn};
|
||||
use core::pin::Pin;
|
||||
use core::ptr::{self, NonNull};
|
||||
use core::slice::{self, from_raw_parts_mut};
|
||||
use core::convert::From;
|
||||
use core::convert::{From, TryFrom};
|
||||
use core::usize;
|
||||
|
||||
use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error};
|
||||
@ -1257,6 +1258,22 @@ impl<T> From<Vec<T>> for Rc<[T]> {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "boxed_slice_try_from", issue = "0")]
|
||||
impl<T, const N: usize> TryFrom<Rc<[T]>> for Rc<[T; N]>
|
||||
where
|
||||
[T; N]: LengthAtMost32,
|
||||
{
|
||||
type Error = Rc<[T]>;
|
||||
|
||||
fn try_from(boxed_slice: Rc<[T]>) -> Result<Self, Self::Error> {
|
||||
if boxed_slice.len() == N {
|
||||
Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) })
|
||||
} else {
|
||||
Err(boxed_slice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "shared_from_iter", since = "1.37.0")]
|
||||
impl<T> iter::FromIterator<T> for Rc<[T]> {
|
||||
/// Takes each element in the `Iterator` and collects it into an `Rc<[T]>`.
|
||||
|
@ -6,7 +6,7 @@ use std::option::Option::{self, None, Some};
|
||||
use std::result::Result::{Err, Ok};
|
||||
use std::mem::drop;
|
||||
use std::clone::Clone;
|
||||
use std::convert::From;
|
||||
use std::convert::{From, TryInto};
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
@ -425,3 +425,15 @@ fn test_downcast() {
|
||||
assert!(r2str.is_ok());
|
||||
assert_eq!(r2str.unwrap(), Rc::new("abc"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_from_slice() {
|
||||
let v = vec![1, 2, 3];
|
||||
let r: Rc<[u32]> = Rc::from(v);
|
||||
|
||||
let a: Result<Rc<[u32; 3]>, _> = r.clone().try_into();
|
||||
assert!(a.is_ok());
|
||||
|
||||
let a: Result<Rc<[u32; 2]>, _> = r.clone().try_into();
|
||||
assert!(a.is_err());
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
//! [arc]: struct.Arc.html
|
||||
|
||||
use core::any::Any;
|
||||
use core::array::LengthAtMost32;
|
||||
use core::sync::atomic;
|
||||
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
|
||||
use core::borrow;
|
||||
@ -21,7 +22,7 @@ use core::ptr::{self, NonNull};
|
||||
use core::marker::{Unpin, Unsize, PhantomData};
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::{isize, usize};
|
||||
use core::convert::From;
|
||||
use core::convert::{From, TryFrom};
|
||||
use core::slice::{self, from_raw_parts_mut};
|
||||
|
||||
use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error};
|
||||
@ -1826,6 +1827,22 @@ impl<T> From<Vec<T>> for Arc<[T]> {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "boxed_slice_try_from", issue = "0")]
|
||||
impl<T, const N: usize> TryFrom<Arc<[T]>> for Arc<[T; N]>
|
||||
where
|
||||
[T; N]: LengthAtMost32,
|
||||
{
|
||||
type Error = Arc<[T]>;
|
||||
|
||||
fn try_from(boxed_slice: Arc<[T]>) -> Result<Self, Self::Error> {
|
||||
if boxed_slice.len() == N {
|
||||
Ok(unsafe { Arc::from_raw(Arc::into_raw(boxed_slice) as *mut [T; N]) })
|
||||
} else {
|
||||
Err(boxed_slice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "shared_from_iter", since = "1.37.0")]
|
||||
impl<T> iter::FromIterator<T> for Arc<[T]> {
|
||||
/// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`.
|
||||
|
@ -9,7 +9,7 @@ use std::option::Option::{self, None, Some};
|
||||
use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}};
|
||||
use std::thread;
|
||||
use std::sync::Mutex;
|
||||
use std::convert::From;
|
||||
use std::convert::{From, TryInto};
|
||||
|
||||
use crate::vec::Vec;
|
||||
|
||||
@ -478,3 +478,15 @@ fn test_downcast() {
|
||||
assert!(r2str.is_ok());
|
||||
assert_eq!(r2str.unwrap(), Arc::new("abc"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_from_slice() {
|
||||
let v = vec![1, 2, 3];
|
||||
let r: Arc<[u32]> = Arc::from(v);
|
||||
|
||||
let a: Result<Arc<[u32; 3]>, _> = r.clone().try_into();
|
||||
assert!(a.is_ok());
|
||||
|
||||
let a: Result<Arc<[u32; 2]>, _> = r.clone().try_into();
|
||||
assert!(a.is_err());
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! Test for `boxed` mod.
|
||||
|
||||
use core::any::Any;
|
||||
use core::convert::TryInto;
|
||||
use core::ops::Deref;
|
||||
use core::result::Result::{Err, Ok};
|
||||
use core::clone::Clone;
|
||||
@ -138,3 +139,15 @@ fn boxed_slice_from_iter() {
|
||||
assert_eq!(boxed.len(), 100);
|
||||
assert_eq!(boxed[7], 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_from_slice() {
|
||||
let v = vec![1, 2, 3];
|
||||
let r: Box<[u32]> = v.into_boxed_slice();
|
||||
|
||||
let a: Result<Box<[u32; 3]>, _> = r.clone().try_into();
|
||||
assert!(a.is_ok());
|
||||
|
||||
let a: Result<Box<[u32; 2]>, _> = r.clone().try_into();
|
||||
assert!(a.is_err());
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
// ignore-tidy-linelength
|
||||
|
||||
use std::{convert::TryFrom, rc::Rc, sync::Arc};
|
||||
|
||||
pub fn no_box() {
|
||||
let boxed_slice = Box::new([0; 33]) as Box<[i32]>;
|
||||
let boxed_array = <Box<[i32; 33]>>::try_from(boxed_slice);
|
||||
//~^ ERROR the trait bound `std::boxed::Box<[i32; 33]>: std::convert::From<std::boxed::Box<[i32]>>` is not satisfied
|
||||
//~^^ ERROR the trait bound `std::boxed::Box<[i32; 33]>: std::convert::TryFrom<std::boxed::Box<[i32]>>` is not satisfied
|
||||
}
|
||||
|
||||
pub fn no_rc() {
|
||||
let boxed_slice = Rc::new([0; 33]) as Rc<[i32]>;
|
||||
let boxed_array = <Rc<[i32; 33]>>::try_from(boxed_slice);
|
||||
//~^ ERROR the trait bound `std::rc::Rc<[i32; 33]>: std::convert::From<std::rc::Rc<[i32]>>` is not satisfied
|
||||
//~^^ ERROR the trait bound `std::rc::Rc<[i32; 33]>: std::convert::TryFrom<std::rc::Rc<[i32]>>` is not satisfied
|
||||
}
|
||||
|
||||
pub fn no_arc() {
|
||||
let boxed_slice = Arc::new([0; 33]) as Arc<[i32]>;
|
||||
let boxed_array = <Arc<[i32; 33]>>::try_from(boxed_slice);
|
||||
//~^ ERROR the trait bound `std::sync::Arc<[i32; 33]>: std::convert::From<std::sync::Arc<[i32]>>` is not satisfied
|
||||
//~^^ ERROR the trait bound `std::sync::Arc<[i32; 33]>: std::convert::TryFrom<std::sync::Arc<[i32]>>` is not satisfied
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,75 @@
|
||||
error[E0277]: the trait bound `std::boxed::Box<[i32; 33]>: std::convert::From<std::boxed::Box<[i32]>>` is not satisfied
|
||||
--> $DIR/alloc-types-no-impls-length-33.rs:7:23
|
||||
|
|
||||
LL | let boxed_array = <Box<[i32; 33]>>::try_from(boxed_slice);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<std::boxed::Box<[i32]>>` is not implemented for `std::boxed::Box<[i32; 33]>`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<std::boxed::Box<(dyn std::error::Error + 'a)> as std::convert::From<E>>
|
||||
<std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<&str>>
|
||||
<std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<std::borrow::Cow<'a, str>>>
|
||||
<std::boxed::Box<(dyn std::error::Error + 'static)> as std::convert::From<std::string::String>>
|
||||
and 16 others
|
||||
= note: required because of the requirements on the impl of `std::convert::Into<std::boxed::Box<[i32; 33]>>` for `std::boxed::Box<[i32]>`
|
||||
= note: required because of the requirements on the impl of `std::convert::TryFrom<std::boxed::Box<[i32]>>` for `std::boxed::Box<[i32; 33]>`
|
||||
|
||||
error[E0277]: the trait bound `std::boxed::Box<[i32; 33]>: std::convert::TryFrom<std::boxed::Box<[i32]>>` is not satisfied
|
||||
--> $DIR/alloc-types-no-impls-length-33.rs:7:23
|
||||
|
|
||||
LL | let boxed_array = <Box<[i32; 33]>>::try_from(boxed_slice);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom<std::boxed::Box<[i32]>>` is not implemented for `std::boxed::Box<[i32; 33]>`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<std::boxed::Box<[T; _]> as std::convert::TryFrom<std::boxed::Box<[T]>>>
|
||||
|
||||
error[E0277]: the trait bound `std::rc::Rc<[i32; 33]>: std::convert::From<std::rc::Rc<[i32]>>` is not satisfied
|
||||
--> $DIR/alloc-types-no-impls-length-33.rs:14:23
|
||||
|
|
||||
LL | let boxed_array = <Rc<[i32; 33]>>::try_from(boxed_slice);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<std::rc::Rc<[i32]>>` is not implemented for `std::rc::Rc<[i32; 33]>`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<std::rc::Rc<T> as std::convert::From<T>>
|
||||
<std::rc::Rc<T> as std::convert::From<std::boxed::Box<T>>>
|
||||
<std::rc::Rc<[T]> as std::convert::From<&[T]>>
|
||||
<std::rc::Rc<[T]> as std::convert::From<std::vec::Vec<T>>>
|
||||
and 8 others
|
||||
= note: required because of the requirements on the impl of `std::convert::Into<std::rc::Rc<[i32; 33]>>` for `std::rc::Rc<[i32]>`
|
||||
= note: required because of the requirements on the impl of `std::convert::TryFrom<std::rc::Rc<[i32]>>` for `std::rc::Rc<[i32; 33]>`
|
||||
|
||||
error[E0277]: the trait bound `std::rc::Rc<[i32; 33]>: std::convert::TryFrom<std::rc::Rc<[i32]>>` is not satisfied
|
||||
--> $DIR/alloc-types-no-impls-length-33.rs:14:23
|
||||
|
|
||||
LL | let boxed_array = <Rc<[i32; 33]>>::try_from(boxed_slice);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom<std::rc::Rc<[i32]>>` is not implemented for `std::rc::Rc<[i32; 33]>`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<std::rc::Rc<[T; _]> as std::convert::TryFrom<std::rc::Rc<[T]>>>
|
||||
|
||||
error[E0277]: the trait bound `std::sync::Arc<[i32; 33]>: std::convert::From<std::sync::Arc<[i32]>>` is not satisfied
|
||||
--> $DIR/alloc-types-no-impls-length-33.rs:21:23
|
||||
|
|
||||
LL | let boxed_array = <Arc<[i32; 33]>>::try_from(boxed_slice);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<std::sync::Arc<[i32]>>` is not implemented for `std::sync::Arc<[i32; 33]>`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<std::sync::Arc<T> as std::convert::From<T>>
|
||||
<std::sync::Arc<T> as std::convert::From<std::boxed::Box<T>>>
|
||||
<std::sync::Arc<[T]> as std::convert::From<&[T]>>
|
||||
<std::sync::Arc<[T]> as std::convert::From<std::vec::Vec<T>>>
|
||||
and 8 others
|
||||
= note: required because of the requirements on the impl of `std::convert::Into<std::sync::Arc<[i32; 33]>>` for `std::sync::Arc<[i32]>`
|
||||
= note: required because of the requirements on the impl of `std::convert::TryFrom<std::sync::Arc<[i32]>>` for `std::sync::Arc<[i32; 33]>`
|
||||
|
||||
error[E0277]: the trait bound `std::sync::Arc<[i32; 33]>: std::convert::TryFrom<std::sync::Arc<[i32]>>` is not satisfied
|
||||
--> $DIR/alloc-types-no-impls-length-33.rs:21:23
|
||||
|
|
||||
LL | let boxed_array = <Arc<[i32; 33]>>::try_from(boxed_slice);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom<std::sync::Arc<[i32]>>` is not implemented for `std::sync::Arc<[i32; 33]>`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<std::sync::Arc<[T; _]> as std::convert::TryFrom<std::sync::Arc<[T]>>>
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user