This feels like a logical generalization of dyn, and is a great utility for the simple case of a wrapper type around a slice.

If I’m not mistaken, this would make, for the `!Sized`

std types,

`dyn (Bounds) <=> dyn<T: (Bounds)> T`

`[T] <=> dyn<const N: usize> [T; N]`

- (
`str`

is still a primitive, but could at some point in the future be `str([u8])`

*maybe*)
- (
`CStr`

is still `CStr([c_char])`

until it can actually be `\0`

-terminated)

This is basically a way of describing fat pointers within the language, as the `dyn<..>`

data is what’s in the pointer “extras”.

For cases wrapping arrays, this is invaluable as a way to get `!Sized`

versions for free. See ndarray’s `IxDyn`

for an example. With being able to “forget”/“outline” the const variable, `Dim`

could theoretically just be (if you forget about `Dim<Vec<_>>`

) `Dim<const N>`

and `Dim<IxDyn>`

becomes `dyn<const N> Dim<N>`

.

More concretely, a type that wraps `[_; N]`

gets the unsized variant in `dyn<const N>`

, and we gain the ability to do `dyn<const N, M> [[_; N]; M]`

where it didn’t exist before. Fewer types need to create a `TRef`

type.

Whatever scheme this takes needs to be sure not to accidentally allow observing `CStr`

's incorrect implementation. This is simple, and required to work with further unsized types beyond just forgetting a const variable: only allow forgetting const parameters which are actually listed.

Here’s a sketch of what this could look like, in guide-level explanation form:

## Unsized types

…

### Unsizing const parameters

The most common way to obtain an unsized type is to “forget” const parameters of a type. Let’s consider the case of a function to sum an array:

```
fn sum<const N: usize>(arr: &[f64; N]) {
let acc = 0;
for n in arr {
acc += n;
}
acc
}
```

This is the generic, monomorphized, statically dispatched version. To instead work with arrays of unknown length until runtime (such as vectors), we can be dynamic over the length:

```
fn sum(arr: &dyn<const N: usize> [f64; N]) {
let acc = 0;
for n in arr {
acc += n;
}
acc
}
```

This puts the length of the array on the stack with the reference, such that this single function works for any length of array.

This concept is so important that we give these a dedicated name – slices – and syntax – `&[T]`

.