Closed withoutboats closed 2 years ago
Is there a subset of const generics that doesn't hit lazy normalization and doesn't have many bugs and papercuts, but which can express a good amount of useful code? I notice that std's impls of many traits for arrays seem to work just fine. Maybe there's a narrowing that would allow other crates to write the kind of impls we have in std for their own traits, even though they don't support all the fancier functionality?
We're now more than halfway through the year, so I'll briefly summarise the work that has been going on. There have been lots of people involved in improving const generics support in the last 6 months, so thank you to everyone who's helped in some way! I especially want to thank @skinny121 and @lcnr, who have both tackled some large features that const generics has been lacking for a while: lazy normalisation for constants and const argument support in method calls, as well as fixing numerous difficult bugs. Their efforts are evident from the summary below.
Const generics is now being used in several places throughout the compiler, and there's already experimentation with traits and functions making use of const generics, e.g. slice::array_chunks
and IntoIterator
and FromIterator
for [T; N]
(https://github.com/rust-lang/rust/pull/65819, https://github.com/rust-lang/rust/pull/69985). The length 32 restriction for array trait implementations is also finally being prepped for removal.
We're currently discussing stabilising a subset of const generics that should cover a wide range of use cases (though there are still some issues left to address before const generics can be fully stabilised).
unused_braces
(https://github.com/rust-lang/rust/pull/70081)dyn Trait
for const generic parameters (https://github.com/rust-lang/rust/pull/71038)While const generics has already come a long way, there are still bugs and sharp edges. If you're interested in tackling any of the remaining issues, feel free to ping me, @lcnr or @eddyb on the issue, or on Zulip, for pointers on getting started. Thank you!
Now that we're looking to stabilize #![feature(min_const_generics)]
in #79135 let's once again summarize all the amazing work that's been going on since the last update. A lot of new people have come and helped out with getting #![feature(min_const_generics)]
ready for stabilization as well as improving other parts of const generics. A huge thanks to everyone who spend their valuable time helping out here, no matter how small your contributions might have been!
I want to use this comment to especially highlight and thank @varkor! They not only fixed some large and complicated issues but also do a lot of less visible work by mentoring and helping others as well as collecting and triaging the remaining issues. While so many amazing people are responsible for where we are now, I do not believe this would have been possible without @varkor.
On other news, with #74060 now being merged, many traits are now implemented for arrays of any size, greatly improving the experience of working with them. This is available on stable since version 1.47 :tada:
fn array_windows
(#75026)array
lang item and fn map
to arrays (#75212)min_const_generics
(#75322)min_const_generics
(#75165, #75166, #78428)min_const_generics
(#76514, #76599)min_const_generics
(#75938)LengthAtMost32
bound on array impls (#74060)min_const_generics
(#76739)Index
and IndexMut
for arrays (#74989)bool
in symbol mangling (#77452)ConstKind::Placeholder
(#78463)char
(#77554)impl Trait
, added tests (#77439)min_const_generics
restrictions (#74877, #74487, #76195, #78224)fn array_chunks
(#74373)While they have not opened any pull requests themselves since the last update, I also want to thank @petrochenkov, @nikomatsakis and @oli-obk for reviewing and helping with many of the more complicated changes seen above.
While we have come a long way over the last 3 years, this is still far from over. Even just for #![feature(min_const_generics)]
there will always be diagnostics to add, bugs to fix and performances to improve. Looking a bit further into the future, there is even more work to do, some of which is explored in the future work section of #79135. If you are interested in helping out with any of this, feel free to either join the project group on zulip, comment on the relevant issues or directly reach out to either me or @varkor.
A year has passed and we're finally stabilizing the next feature related to const generics:
✨ feature(const_generics_defaults)
✨
With this, I am going to once again summarize the progress made here. This summary was written by @lcnr and therefore overrepresents parts I have been involved with while not giving other areas the focus they deserve.
Soon after the stabilization of feature(min_const_generics)
we started to focus on supporting generic expressions as const arguments. While doing so, we encountered quite a few major obstacles, because of which @rust-lang/project-const-generics started to have some weekly meetings in February. The current status can be tested using #![feature(generic_const_exprs)]
.
While we believe that we now know most of the remaining blockers, we also know that these are sadly very difficult to deal with.
Because of this, feature(generic_const_exprs)
is still really far away from stabilization. @BoxyUwU and I recently discussed a potential #[feature(min_generic_const_exprs)]
which can be more easily stabilized while still allowing computations in generic const arguments.
We still have to take these ideas to the rest of @rust-lang/project-const-generics, but there should hopefully be some news about this during the next year.
as the work on this feature has been greatly influenced by me experiencing burnout, here's a quick reminder that you should take regular breaks from any open source work you might do. always being available is incredibly unhealthy and is not desirable or praiseworthy
Right now, constant values used as arguments for const parameters are represented using "allocations", this makes checking them for equality somewhat difficult, as comparing allocations directly does not consider two different &3
to be equal to each other and causes some other annoyances.
To deal with this, we (mostly @oli-obk and @RalfJung) introduced the concept of valtrees, which represents constant values in the type system as simple trees with integer leaves. Checking equality of valtrees is fairly trivial and using them avoids some other, more subtle issues as well. @oli-obk started to implement this in #82936 and while progress has recently stalled due to a lack of time, this is definitely something to look forward to.
In #75384 @JulianKnodt began implementing const parameter defaults, with the initial PR taking more than 7 months and racking up a total of over 200 comments. Using this as a starting point, fixing the remaining issues was fairly straightforward, allowing us to stabilize this feature in #90207.
After stabilizing feature(min_const_generics)
in #79135, @CraftSpider opened #80531, showing that specifying the argument for const parameters in patterns is not supported. To my knowledge, nobody noticed this before, which is especially worrying considering that const generics was already stable on nightly at that time. The PR which fixed this is #80551.
match Some(Default::default()) {
Some::<u8>(a) => assert_eq!(a, 0),
None => {}
}
The same issue also existed for trait methods with incorrect const parameter types which has been fixed in #86843.
This shows that even though const generics has been used a lot while unstable and we took a lot of effort to improve our test coverage before stabilizing feature(min_const_generics)
, there were still some pretty simple bugs we've missed.
Finally, an overview of most pull requests related to const generics which have been merged since the last update. As const generics is now stable and "infects" large parts of the compiler, and const parameters are fairly frequently used, there are many changes related to const generics which I did not mention here.
The decisions on which PRs to mention and which ones to ignore were made in mere seconds and are not well thought out. There are also changes I've simply missed while searching for them. If you see a pull request which should be mentioned here please either edit this comment yourself or pm me on zulip.
While this does highlight people working with and on const generics, there are many people whose contribution to const generics is not reflected below. Thank you to everyone who contributed.
Thanks to @lcnr for the ongoing excellent summaries!
All remaining const generics features are tracked in separate issues:
For more than 2 years now this issue has been pretty much exclusively used for update posts by either @varkor or myself. I intend to keep posting these updates but don't think this issue is necessarily the right place for them. I currently intend to post them to the Inside Rust blog, but I will try to link to the first of these posts here once the time has come.
Once again a huge thanks to everyone who has contributed to const generics over the last 5 years.
Tracking issue for rust-lang/rfcs#2000
Updates:
If you want to help out, take a look at the open const generics issues and feel free to ping @varkor, @eddyb, @yodaldevoid, @oli-obk or @lcnr for help in getting started!
Blocking stabilization:
Remaining implementation issues:
FIXME(const_generics)
comments.FIXME(const_generics_defaults)
).has_infer_types
.{X * 2}
.