Rollup merge of #97594 - WaffleLapkin:array_tuple_conv, r=ChrisDenton
Implement tuple<->array convertions via `From` This PR adds the following impls that convert between homogeneous tuples and arrays of the corresponding lengths: ```rust impl<T> From<[T; 1]> for (T,) { ... } impl<T> From<[T; 2]> for (T, T) { ... } /* ... */ impl<T> From<[T; 12]> for (T, T, T, T, T, T, T, T, T, T, T, T) { ... } impl<T> From<(T,)> for [T; 1] { ... } impl<T> From<(T, T)> for [T; 2] { ... } /* ... */ impl<T> From<(T, T, T, T, T, T, T, T, T, T, T, T)> for [T; 12] { ... } ``` IMO these are quite uncontroversial but note that they are, just like any other trait impls, insta-stable.
This commit is contained in:
commit
84d8159ebf
5 changed files with 78 additions and 5 deletions
|
@ -610,6 +610,9 @@ mod prim_pointer {}
|
||||||
/// if the element type allows it. As a stopgap, trait implementations are
|
/// if the element type allows it. As a stopgap, trait implementations are
|
||||||
/// statically generated up to size 32.
|
/// statically generated up to size 32.
|
||||||
///
|
///
|
||||||
|
/// Arrays of sizes from 1 to 12 (inclusive) implement [`From<Tuple>`], where `Tuple`
|
||||||
|
/// is a homogenous [prim@tuple] of appropriate length.
|
||||||
|
///
|
||||||
/// Arrays coerce to [slices (`[T]`)][slice], so a slice method may be called on
|
/// Arrays coerce to [slices (`[T]`)][slice], so a slice method may be called on
|
||||||
/// an array. Indeed, this provides most of the API for working with arrays.
|
/// an array. Indeed, this provides most of the API for working with arrays.
|
||||||
///
|
///
|
||||||
|
@ -672,6 +675,13 @@ mod prim_pointer {}
|
||||||
/// move_away(roa);
|
/// move_away(roa);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// Arrays can be created from homogenous tuples of appropriate length:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let tuple: (u32, u32, u32) = (1, 2, 3);
|
||||||
|
/// let array: [u32; 3] = tuple.into();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// # Editions
|
/// # Editions
|
||||||
///
|
///
|
||||||
/// Prior to Rust 1.53, arrays did not implement [`IntoIterator`] by value, so the method call
|
/// Prior to Rust 1.53, arrays did not implement [`IntoIterator`] by value, so the method call
|
||||||
|
@ -774,6 +784,7 @@ mod prim_pointer {}
|
||||||
/// [`Borrow`]: borrow::Borrow
|
/// [`Borrow`]: borrow::Borrow
|
||||||
/// [`BorrowMut`]: borrow::BorrowMut
|
/// [`BorrowMut`]: borrow::BorrowMut
|
||||||
/// [slice pattern]: ../reference/patterns.html#slice-patterns
|
/// [slice pattern]: ../reference/patterns.html#slice-patterns
|
||||||
|
/// [`From<Tuple>`]: convert::From
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_array {}
|
mod prim_array {}
|
||||||
|
|
||||||
|
@ -1000,7 +1011,9 @@ mod prim_str {}
|
||||||
/// * [`Debug`]
|
/// * [`Debug`]
|
||||||
/// * [`Default`]
|
/// * [`Default`]
|
||||||
/// * [`Hash`]
|
/// * [`Hash`]
|
||||||
|
/// * [`From<[T; N]>`][from]
|
||||||
///
|
///
|
||||||
|
/// [from]: convert::From
|
||||||
/// [`Debug`]: fmt::Debug
|
/// [`Debug`]: fmt::Debug
|
||||||
/// [`Hash`]: hash::Hash
|
/// [`Hash`]: hash::Hash
|
||||||
///
|
///
|
||||||
|
@ -1051,6 +1064,13 @@ mod prim_str {}
|
||||||
/// assert_eq!(y, 5);
|
/// assert_eq!(y, 5);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// Homogenous tuples can be created from arrays of appropriate length:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let array: [u32; 3] = [1, 2, 3];
|
||||||
|
/// let tuple: (u32, u32, u32) = array.into();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_tuple {}
|
mod prim_tuple {}
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,26 @@ macro_rules! tuple_impls {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "array_tuple_conv", since = "1.63.0")]
|
||||||
|
impl<T> From<[T; ${count(T)}]> for ($(${ignore(T)} T,)+) {
|
||||||
|
#[inline]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn from(array: [T; ${count(T)}]) -> Self {
|
||||||
|
let [$($T,)+] = array;
|
||||||
|
($($T,)+)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "array_tuple_conv", since = "1.63.0")]
|
||||||
|
impl<T> From<($(${ignore(T)} T,)+)> for [T; ${count(T)}] {
|
||||||
|
#[inline]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn from(tuple: ($(${ignore(T)} T,)+)) -> Self {
|
||||||
|
let ($($T,)+) = tuple;
|
||||||
|
[$($T,)+]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -610,6 +610,9 @@ mod prim_pointer {}
|
||||||
/// if the element type allows it. As a stopgap, trait implementations are
|
/// if the element type allows it. As a stopgap, trait implementations are
|
||||||
/// statically generated up to size 32.
|
/// statically generated up to size 32.
|
||||||
///
|
///
|
||||||
|
/// Arrays of sizes from 1 to 12 (inclusive) implement [`From<Tuple>`], where `Tuple`
|
||||||
|
/// is a homogenous [prim@tuple] of appropriate length.
|
||||||
|
///
|
||||||
/// Arrays coerce to [slices (`[T]`)][slice], so a slice method may be called on
|
/// Arrays coerce to [slices (`[T]`)][slice], so a slice method may be called on
|
||||||
/// an array. Indeed, this provides most of the API for working with arrays.
|
/// an array. Indeed, this provides most of the API for working with arrays.
|
||||||
///
|
///
|
||||||
|
@ -672,6 +675,13 @@ mod prim_pointer {}
|
||||||
/// move_away(roa);
|
/// move_away(roa);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// Arrays can be created from homogenous tuples of appropriate length:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let tuple: (u32, u32, u32) = (1, 2, 3);
|
||||||
|
/// let array: [u32; 3] = tuple.into();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// # Editions
|
/// # Editions
|
||||||
///
|
///
|
||||||
/// Prior to Rust 1.53, arrays did not implement [`IntoIterator`] by value, so the method call
|
/// Prior to Rust 1.53, arrays did not implement [`IntoIterator`] by value, so the method call
|
||||||
|
@ -774,6 +784,7 @@ mod prim_pointer {}
|
||||||
/// [`Borrow`]: borrow::Borrow
|
/// [`Borrow`]: borrow::Borrow
|
||||||
/// [`BorrowMut`]: borrow::BorrowMut
|
/// [`BorrowMut`]: borrow::BorrowMut
|
||||||
/// [slice pattern]: ../reference/patterns.html#slice-patterns
|
/// [slice pattern]: ../reference/patterns.html#slice-patterns
|
||||||
|
/// [`From<Tuple>`]: convert::From
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_array {}
|
mod prim_array {}
|
||||||
|
|
||||||
|
@ -1000,7 +1011,9 @@ mod prim_str {}
|
||||||
/// * [`Debug`]
|
/// * [`Debug`]
|
||||||
/// * [`Default`]
|
/// * [`Default`]
|
||||||
/// * [`Hash`]
|
/// * [`Hash`]
|
||||||
|
/// * [`From<[T; N]>`][from]
|
||||||
///
|
///
|
||||||
|
/// [from]: convert::From
|
||||||
/// [`Debug`]: fmt::Debug
|
/// [`Debug`]: fmt::Debug
|
||||||
/// [`Hash`]: hash::Hash
|
/// [`Hash`]: hash::Hash
|
||||||
///
|
///
|
||||||
|
@ -1051,6 +1064,13 @@ mod prim_str {}
|
||||||
/// assert_eq!(y, 5);
|
/// assert_eq!(y, 5);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// Homogenous tuples can be created from arrays of appropriate length:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let array: [u32; 3] = [1, 2, 3];
|
||||||
|
/// let tuple: (u32, u32, u32) = array.into();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_tuple {}
|
mod prim_tuple {}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,16 @@ LL | Err(5)?;
|
||||||
| ^ the trait `From<{integer}>` is not implemented for `()`
|
| ^ the trait `From<{integer}>` is not implemented for `()`
|
||||||
|
|
|
|
||||||
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
|
||||||
= help: the following other types implement trait `FromResidual<R>`:
|
= help: the following other types implement trait `From<T>`:
|
||||||
<Result<T, F> as FromResidual<Result<Infallible, E>>>
|
<(T, T) as From<[T; 2]>>
|
||||||
<Result<T, F> as FromResidual<Yeet<E>>>
|
<(T, T, T) as From<[T; 3]>>
|
||||||
|
<(T, T, T, T) as From<[T; 4]>>
|
||||||
|
<(T, T, T, T, T) as From<[T; 5]>>
|
||||||
|
<(T, T, T, T, T, T) as From<[T; 6]>>
|
||||||
|
<(T, T, T, T, T, T, T) as From<[T; 7]>>
|
||||||
|
<(T, T, T, T, T, T, T, T) as From<[T; 8]>>
|
||||||
|
<(T, T, T, T, T, T, T, T, T) as From<[T; 9]>>
|
||||||
|
and 4 others
|
||||||
= note: required for `Result<i32, ()>` to implement `FromResidual<Result<Infallible, {integer}>>`
|
= note: required for `Result<i32, ()>` to implement `FromResidual<Result<Infallible, {integer}>>`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
|
@ -6,8 +6,14 @@ LL | let _: &[i8] = data.into();
|
||||||
|
|
|
|
||||||
= help: the following other types implement trait `From<T>`:
|
= help: the following other types implement trait `From<T>`:
|
||||||
<&'input [u8] as From<gimli::read::endian_slice::EndianSlice<'input, Endian>>>
|
<&'input [u8] as From<gimli::read::endian_slice::EndianSlice<'input, Endian>>>
|
||||||
<[T; LANES] as From<Simd<T, LANES>>>
|
<[T; 10] as From<(T, T, T, T, T, T, T, T, T, T)>>
|
||||||
<[bool; LANES] as From<Mask<T, LANES>>>
|
<[T; 11] as From<(T, T, T, T, T, T, T, T, T, T, T)>>
|
||||||
|
<[T; 12] as From<(T, T, T, T, T, T, T, T, T, T, T, T)>>
|
||||||
|
<[T; 1] as From<(T,)>>
|
||||||
|
<[T; 2] as From<(T, T)>>
|
||||||
|
<[T; 3] as From<(T, T, T)>>
|
||||||
|
<[T; 4] as From<(T, T, T, T)>>
|
||||||
|
and 7 others
|
||||||
= note: required for `&[u8]` to implement `Into<&[i8]>`
|
= note: required for `&[u8]` to implement `Into<&[i8]>`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue