-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use const generics for array Default
impl
#61415
Comments
As I noted in #60466 (comment) and #60466 (comment) I will not sign off on using const generics in stable Rust until such time that const generics are stable. However, we can provide unstable wrapper types meanwhile. |
We can probably both keep the exact observable behavior (impls for 0-32) and reduce metadata bloat by using a trick similar to #60466 (comment) (an empty marker trait implemented using macros + the real impl using const generics and a This way const generics would be an implementation detail, so their stabilization wouldn't be required. |
The results from the crater run and perf run for using const generics for array impls are in (#60466).
I think there's good reason to go with @petrochenkov's suggestion (#61415 (comment)) and potentially consider lifting the restriction for array sizes. |
does T-compiler actually need to be tagged on this issue? Unless its exposing bugs for const generics themselves, I would think this is solely a T-libs issue, maybe T-lang, but not T-compiler? |
This libs team discussed this yesterday and agreed that we do not want to expand the stable surface API of the standard library, but changing implementaitons to use const generics seems fine so long as it doesn't expand the surface area of what's exposed (e.g. via @petrochenkov's idea) |
The @rust-lang/lang team discussed this and we agree with the libs team. =) |
No-expanded-surface area (#61415 (comment)) PR up at #62435 |
Use const generics for array impls [part 1] Part 1 of #61415, following the plan in #61415 (comment) Found a way that works 🙃
Turns out using const generics inside the actual code (which currently only |
@RalfJung Can you trigger that from CTFE, or does it require runtime features? |
ICE from Miri is easy: use std::convert::TryFrom;
fn main() {
const N: usize = 16;
type Array = [u8; N];
let array: Array = [0; N];
let slice: &[u8] = &array[..];
let result = <&Array>::try_from(slice);
assert_eq!(&array, result.unwrap());
} Here is a self-contained version. |
If I try to make error: const parameters are not permitted in `const fn` So I'd suggest fixing that first (seems like an unnecessary limitation while const generics are unstable - worst case it can just get its own feature gate). After that, the entire repro is this: #![feature(const_generics)]
const fn len<T, const N: usize>(_: [T; N]) -> usize { N }
const FOO: usize = len([0]); My guess is that miri isn't monomorphizing ("substituting"?) |
Indeed, and I have a patch for that but it ICEs. See #61041 (comment). |
@RalfJung I left a comment, you shouldn't be able to trigger that ICE that easily. |
In which we constantly improve the Vec(Deque) array PartialEq impls Use the same approach as in #62435 as sanctioned by #61415 (comment). r? @scottmcm
TL;DR there are two problems with my PR:
|
This increases the minimum supported Rust version to 1.51.0. I sadly had to introduce another unsafe statement, because: * `Default` is only implemented for array lengths up to 32 (rust-lang/rust#61415) * arr_macro doesn't support const generics (JoshMcguigan/arr_macro#2) * Direct initialization via [T; N] adds a trait bound BinRead: Copy
This increases the minimum supported Rust version to 1.51.0. I sadly had to introduce another unsafe statement, because: * `Default` is only implemented for array lengths up to 32 (rust-lang/rust#61415) * arr_macro doesn't support const generics (JoshMcguigan/arr_macro#2) * Direct initialization via [T; N] adds a trait bound `BinRead: Copy`
This increases the minimum supported Rust version to 1.51.0. I sadly had to introduce another unsafe statement, because: * `Default` is only implemented for array lengths up to 32 (rust-lang/rust#61415) * arr_macro doesn't support const generics (JoshMcguigan/arr_macro#2) * Direct initialization via [T; N] adds a trait bound `BinRead: Copy`
@oli-obk @rust-lang/wg-const-eval @rust-lang/types Is there any potential future change on the horizon that would allow handling "either T: Default or N == 0" without needing full overlapping implementations? |
Not that I know of. Though I would love to be able to specify patterns like in matches to restrict const generic impls to something that we already know how to check for overlap (or lack thereof) |
Default
impl
dumb question. Can this be fixed for the edition 2024? |
I think the problem of the overlapping impl where impl <T> Default for [T; 0] {...}
impl <T, const N: usize> Default for [T; N] {...} |
Currently, we generate array impls for every size up to 32 manually using macros, but with const generics at a suitable level of implementation, we can switch to properly parameterising over all lengths.
Default
impl with const generic impl (more difficult due to Switch libcore array implementations to const generics. #60466 (comment)).rust/src/libcore/array.rs
Lines 221 to 227 in 7840a0b
rust/src/liballoc/vec.rs
Lines 2199 to 2204 in bfdfa85
The text was updated successfully, but these errors were encountered: