Skip to content

SmallVec should implement From<[T; N]> (gated by cfg(feature = "const_generics")). #272

Closed
@eddyb

Description

@eddyb

The Rust standard library contains these impls:

(click to expand search results for From<[...; N]>)
$ rg -B1 'From<\[.*; N\]' library/
library/std/src/collections/hash/set.rs
1010-// See also the equivalent impl on HashMap.
1011:impl<T, const N: usize> From<[T; N]> for HashSet<T, RandomState>

library/std/src/collections/hash/map.rs
1174-// See also the equivalent impl on HashSet.
1175:impl<K, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, RandomState>

library/alloc/src/collections/linked_list.rs
1954-#[stable(feature = "std_collections_from_array", since = "1.56.0")]
1955:impl<T, const N: usize> From<[T; N]> for LinkedList<T> {

library/alloc/src/collections/btree/set.rs
1093-#[stable(feature = "std_collections_from_array", since = "1.56.0")]
1094:impl<T: Ord, const N: usize> From<[T; N]> for BTreeSet<T> {

library/alloc/src/collections/binary_heap.rs
1491-#[stable(feature = "std_collections_from_array", since = "1.56.0")]
1492:impl<T: Ord, const N: usize> From<[T; N]> for BinaryHeap<T> {

library/alloc/src/collections/btree/map.rs
2048-#[stable(feature = "std_collections_from_array", since = "1.56.0")]
2049:impl<K: Ord, V, const N: usize> From<[(K, V); N]> for BTreeMap<K, V> {

library/alloc/src/vec/mod.rs
2909-#[stable(feature = "vec_from_array", since = "1.44.0")]
2910:impl<T, const N: usize> From<[T; N]> for Vec<T> {

library/alloc/src/collections/vec_deque/mod.rs
3050-#[stable(feature = "std_collections_from_array", since = "1.56.0")]
3051:impl<T, const N: usize> From<[T; N]> for VecDeque<T> {

library/alloc/src/boxed.rs
1481-#[stable(feature = "box_from_array", since = "1.45.0")]
1482:impl<T, const N: usize> From<[T; N]> for Box<[T]> {

While most are pretty recent (1.56.0), the Vec one is quite older (1.44.0), but either way, std has been clearly moving to more by-value array functionality, and I think SmallVec should follow this trend.

As a concrete usecase, I'm working on a codebase that uses SmallVec throughout, and a lot of them are created with [...].into_iter().collect(), which would be nicer to spell as just [...].into().

I already am locked into requiring a Rust version new enough to have stable const generics, and AFAICT the const_generics feature of smallvec could be used to opt into a new From impl, but this existing one may be a small issue:

impl<A: Array> From<A> for SmallVec<A> {

That is, that pre-existing impl requires an array as long as the inline capacity of the SmallVec, and while it could be swapped out with the more general one with #[cfg(feature = "const_generics")], the extra flexibility could make inference ambiguous (if anyone has relied on it somehow).

Then again, I don't think syntax like [T; _] (literally an underscore for the length, to allow it to be inferred) is stable yet, and something like SmallVec::from(Default::default()) is too ambiguous anyway, so it would take SmallVec::from(make_array_of_const_generic_len(...)) to be able to cause an issue.

Of course, with a smallvec 2.0 (#240), such compatibility issues (however implausible) wouldn't matter, but I'm not sure if that rewrite is coming any time soon.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions