Skip to content

Commit 136140b

Browse files
committed
RFC: Extend and stabilize the FixedSizeArray trait
1 parent b23226f commit 136140b

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

text/0000-array-trait.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
- Feature Name: array-trait
2+
- Start Date: 2017-02-21
3+
- RFC PR:
4+
- Rust Issue:
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
Extend and stabilize the `FixedSizeArray` trait,
10+
as a stop-gap solution for integer parameters in generics.
11+
12+
13+
# Motivation
14+
[motivation]: #motivation
15+
16+
One of Rust’s basic families of types is fixed-size arrays:
17+
`[T; N]` where `T` is any (statically-sized) type, and `N` is an (`usize`) integer.
18+
Arrays with the same `T` item type but of different sizes are themselves different types.
19+
20+
A [long-standing](https://github.com/rust-lang/rfcs/pull/884)
21+
feature [request](https://github.com/rust-lang/rfcs/issues/1038)
22+
it the ability to write code that is generic over the size of an array.
23+
The solution typically proposed for this it “type-level integers”,
24+
where generic items can have integers as a new *kind* of type-level parameters,
25+
in addition to lifetime parameters and type parameters.
26+
27+
This by itself introduce it’s share of complexity.
28+
Even so, such proposals are often extended to cover arbitrary type levels (not just integers),
29+
or even dependent types.
30+
As a result, every RFC on the subject so far has been postponed:
31+
[1](https://github.com/rust-lang/rfcs/pull/884),
32+
[2](https://github.com/rust-lang/rfcs/pull/1062),
33+
[3](https://github.com/rust-lang/rfcs/pull/1520),
34+
[4](https://github.com/rust-lang/rfcs/issues/1557),
35+
[5](https://github.com/rust-lang/rfcs/pull/1657).
36+
37+
This RFC propose an addition to the language that,
38+
although less theoretically pleasing,
39+
is much smaller and therefore hopefully more likely to be accepted.
40+
Additionally, it does not prevent a more general solution from also happening in the future.
41+
42+
Arrays are the only case where integers occur in types, in current Rust.
43+
Therefore a solution specifically for arrays
44+
covers many (most? all?) of the use cases for type-level integers.
45+
46+
47+
# Detailed design
48+
[design]: #detailed-design
49+
50+
The `core::array` module currently contains a `FixedSizeArray` trait.
51+
Both are unstable.
52+
This RFC proposes three changes:
53+
54+
* Extend the `FixedSizeArray`. (This is optional, see alternatives.)
55+
* Reexport the module as `std::array`.
56+
* Stabilize both the module an the trait.
57+
58+
The current definition of the trait is:
59+
60+
```rust
61+
pub unsafe trait FixedSizeArray<T> {
62+
/// Converts the array to immutable slice
63+
fn as_slice(&self) -> &[T];
64+
/// Converts the array to mutable slice
65+
fn as_mut_slice(&mut self) -> &mut [T];
66+
}
67+
68+
unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
69+
#[inline]
70+
fn as_slice(&self) -> &[T] {
71+
self
72+
}
73+
#[inline]
74+
fn as_mut_slice(&mut self) -> &mut [T] {
75+
self
76+
}
77+
}
78+
```
79+
80+
A single `impl` applies to array of all sizes, thanks to the `Unsize` trait.
81+
That trait is also unstable.
82+
It exists to support for [DST coercions](https://github.com/rust-lang/rust/issues/27732),
83+
itself a somewhat complex feature that might take some time to stabilize.
84+
85+
This trait is already useful as-is,
86+
but it would be nice to extend it to include the array’s length and item type
87+
as an associated constant
88+
and an associated type (which replaces the type parameter):
89+
90+
```rust
91+
pub unsafe trait FixedSizeArray {
92+
// Added:
93+
type Item;
94+
const LENGTH: usize;
95+
96+
// Unchanged:
97+
fn as_slice(&self) -> &[Self::Item];
98+
fn as_mut_slice(&mut self) -> &mut [Self::Item];
99+
}
100+
```
101+
102+
However these can not be provided by in `impl` based on `Unsize<[T]>` like the current one.
103+
Instead, this RFC proposes that all array types implement the trait through “compiler magic”.
104+
There would be no corresponding `impl` block in libcore or other library crates,
105+
the existence of these implementations would be part of the definition of the Rust language.
106+
There is precedent for such “magic” implementations in the language of other traits:
107+
108+
* `Unsize`
109+
* `Sized`
110+
* `Fn`, `FnMut`, `FnMove` (for closures types, which are very magical themselves)
111+
* `Copy`, `Drop` (not implemented implicitly, but `impl`s have “magical” requirements)
112+
113+
114+
# How We Teach This
115+
[how-we-teach-this]: #how-we-teach-this
116+
117+
The `array` module and `FixedSizeArray` trait already have rustdoc documentation
118+
that seems appropriate.
119+
120+
The trait could be mentioned in the *Primitive Types* or *Generics* chapter of the book.
121+
122+
123+
# Drawbacks
124+
[drawbacks]: #drawbacks
125+
126+
Doing this “shouldn’t” be necessary if we assume that Rust is going to have
127+
type-level integers / type-level constants / dependent types (take your pick) eventually.
128+
However, shipping imperfect features are arguably superior to
129+
“better” features that haven’t been happening for several years already
130+
with no significant progress in sight.
131+
132+
133+
# Alternatives
134+
[alternatives]: #alternatives
135+
136+
* Stabilize the `FixedSizeArray` trait as-is
137+
(without an associated type or associated constant, with a type parameter).
138+
139+
* Figure out type-level integers, and deprecate / remove the `FixedSizeArray` trait.
140+
141+
142+
# Unresolved questions
143+
[unresolved]: #unresolved-questions
144+
145+
* To extend or not to extend. (See [Alternatives](#alternatives).)
146+
147+
* Should the compiler prevent other implementations of the trait?
148+
There is precedent for that with the `Unsize` trait and error number E0328.
149+
150+
* Rename `FixedSizeArray` to `Array`?
151+
All arrays in Rust are fixed-size.
152+
The things similar to arrays that are not fixed-size are called slices or vectors.

0 commit comments

Comments
 (0)