Open bjoernager opened 15 hours ago
If we are adding a dedicated conversion function I think flipping the order turning it into an inherent method of the slice is more convenient to the users
impl<T> [T] {
pub const fn as_array_exact<const N: usize>(&self) -> Result<&[T; N], TryFromSliceError>;
}
I'm not sure why the ACP proposed &[T] -> [T; N]
thus requiring T: Copy
. Dereferencing a &[T; N]
is allowed in const context.
I see your point, although I feel it would be confusing to have the error type named TryFromSliceError
when returned from a function with a slightly different intention and scope. Defining a new type AsArrayExactError
would be clearer but also result in mostly duplicate code.
As for your second concern, I'm not quite sure I understand what the problem is. The semantics proposed in this ACP are basically the same as the preexisting; the logic has just been moved from TryFrom
to a global function, using the same infrastructure. This approach is minimally different from status quo.
impl<T> [T] { pub const fn as_array_exact<const N: usize>(&self) -> Result<&[T; N], TryFromSliceError>; }
I think as_array
is clear enough, _exact
isn't needed.
also, const fn
supports &mut
now, so there should also be an as_array_mut
function.
For what it's worth, in the meantime this works in a const context, though only on nightly for now:
if let ([a], []) = s.as_chunks() {
Some(a)
} else {
None
}
impl<T> [T] {
pub const fn as_array<const N: usize>(&self) -> Option<&[T; N]>;
pub const fn as_array_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>;
}
seems pretty reasonable to me.
Would be convenient to have it in const, and the TryFrom
impl can use it with a .ok_or(TryFromSliceError)
.
(I don't think it needs to return a Result, because the error can't say anything meaningful -- just like how NonZero::new
returns an Option
, rather than having a IsNotZeroError
.)
I'm personally content with that solution.
Proposal
Problem statement
In Rust, you can convert a slice
&[T]
to an array[T; N]
using<[T; N] as TryFrom<&[T]>>::try_from
. The main issue with this is that it depends on a trait function, and trait functions are not allowed in constant expressions (e.g.const fn
).I propose adding a
try_from_slice
function to thecore::array
module for this scenario. The module in question already defines other constructors such asfrom_fn
andfrom_ref
.Solution sketch
The following function should be added to the standard library:
Alternatives
The main alternative to adding this feature (with regard to
const
) would be to allow trait functions in constant expressions. This is already covered byconst_trait_impl
.I still do believe adding this function can improve clarity in some code. Other areas of the standard library already define similar patterns, e.g.
String
implementsInto<Box<str>>
whilst also defining theinto_boxed_str
destructor.Links and related work
Initial, unstable implementation: #133439