Skip to content

Tracking issue for const generics (RFC 2000) #44580

@withoutboats

Description

@withoutboats
Contributor

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:

  • Design:
    • Resolving ordering of const and type parameters, with default parameters
    • Decide what the best UX / implementation cost balance is for unifying abstract const expressions.
    • How we determine well formedness of const expressions.
  • Implementation
  • Documentation
    • rustc guide

Remaining implementation issues:

  • Resolve various FIXME(const_generics) comments.
    Resolve concerns with canonicalisation / lazy normalisation.
    Investigate handling of const parameters in patterns.
    Add more tests.
    Implement defaults for const parameters (FIXME(const_generics_defaults)).
    Audit uses of has_infer_types.
    Forbid complex expressions for const arguments involving parameters (for now), e.g. {X * 2}.

Activity

added
B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.
C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
T-langRelevant to the language team
on Sep 14, 2017
eddyb

eddyb commented on Sep 15, 2017

@eddyb
Member

#44275 added a ConstEvaluatable predicate, and WF([T; expr]) now requires ConstEvaluatable(expr), as expr is lazily evaluated (even if it's just an integer literal). Fulfilling this predicate requires the expression to evaluate successfully, while normalization ignores the error and simply leaves the Unevaluated expression it found, untouched, which is more or less what happens with associated type projections. I expect the same system to scale to const generics.

@EpicatSupercell has expressed interest in working on this, I'll mentor them through the initial implementation. However, we can't go too far because of the limitations described in #44275.

That is, we need @nikomatsakis' lazy normalization to allow constant expressions embedded in types to observe the bounds in scope (from the function / type definition / impl / etc. item they're in), without producing cyclic dependencies half the time.

eddyb

eddyb commented on Sep 18, 2017

@eddyb
Member

Implementation waypoints (for more direct mentoring, seek @eddyb on Gitter or eddyb on IRC):

  • Declaration / Syntax:
  • Declaration / Semantics
    • Data structures: ty::Generics - add const parameters alongside type ones
    • Conversion from HIR: generics_of - create ty::ConstParameterDef from hir::ConstParam
  • Use / Name Resolution
    • Data structures: Def - add a variant for const parameters
    • Name resolution pass: with_type_parameter_rib - support both type and const generics
  • Use / Semantics
    • ConstVal - add Param variant akin to ty::TyParam
    • Conversion from HIR: TyArray with a length that's an ExprPath that resolved to Def::ConstParam should use ConstVal::Param instead of ConstVal::Unevaluated - in a similar fashion to how Def::TyParam turns into ty::TyParam
    • subst::Kind - support &ty::Const and check as_const as well in where places where as_type and as_region are checked
  • Inference

Note that all of this should allow impl<T, const N: usize> Trait for [T; N] {...}, but not actually passing a constant expression to a type/function, e.g. ArrayVec<T, 3>.

added
E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
on Sep 18, 2017
self-assigned this
on Sep 18, 2017
jplatte

jplatte commented on Sep 18, 2017

@jplatte
Contributor

I'd like to take a stab at this :)

264 remaining items

bstrie

bstrie commented on Oct 20, 2019

@bstrie
Contributor

I would like to request that we reserve the discussion of such a significant syntactic change for either a thread on internals or an issue (or amending PR) on the RFCs repo. This issue's comment section is already quite long and the syntax in question seems unnecessary for a usable MVP of const generics.

eddyb

eddyb commented on Oct 20, 2019

@eddyb
Member

If we could move comments we probably would. We might want to lock the issue to @rust-lang team members and hide all the offtopic comments?

All design discussion should happen on the RFC repo and all bug reports should be in separate issues.

cc @rust-lang/moderation Is there precedent for doing this?

locked as off topic and limited conversation to collaborators on Oct 20, 2019
Manishearth

Manishearth commented on Oct 20, 2019

@Manishearth
Member

You can convert a comment to an issue, but not move comments. Locking is fine, and i'd just hide off topic comments.

varkor

varkor commented on Jan 2, 2020

@varkor
Contributor

With the start of the new year, I thought it would be good to give another update on where we are now with const generics. It's been a little over 2 years since the const generics RFC was accepted. In the first year (roughly 2018), a series of large refactoring efforts were undertaken to facilitate const generics by improving the handling of generic parameters generally throughout the compiler. In the second year (roughly 2019), work began on implementing const generics itself: first by getting the bare minimum working, and then by slowing improving the integrity of the feature. People also started to experiment with using const generics in the compiler itself. More detailed descriptions of these efforts are in the first two update posts: [1], [2].


There's been good progress in the last couple of months since the last update.

A big thanks to everyone who has been helping out with const generics!


What's next? The biggest blocker for const generics at the moment is lazy normalisation, which is required for certain kinds of const generic bounds (such as in arrays). @Skinny121 is currently investigating lazy normalisation, continuing their fantastic efforts taking down the big bugs in const generics. This would address many of the present issues with const generics.

Lazy normalisation aside, there are still a sizeable number of bugs and papercuts we'd like to address. If you're interested in tackling any of the remaining issues, feel free to ping me on the issue, or on Discord or Zulip for pointers on getting started. I'm confident we can make good headway in 2020 and hopefully approach a point where stabilisation becomes a viable discussion!

withoutboats

withoutboats commented on Jul 5, 2020

@withoutboats
ContributorAuthor

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?

varkor

varkor commented on Jul 22, 2020

@varkor
Contributor

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] (#65819, #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).



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!

lcnr

lcnr commented on Nov 17, 2020

@lcnr
Contributor

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 🎉


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.

self-assigned this
on Dec 18, 2020
lcnr

lcnr commented on Dec 11, 2021

@lcnr
Contributor

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.

Generic const arguments

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

Valtrees

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.

Const parameter defaults

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.

Generic arguments in patterns

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.

Pull Requests

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.

joshtriplett

joshtriplett commented on Feb 9, 2022

@joshtriplett
Member

Thanks to @lcnr for the ongoing excellent summaries!

lcnr

lcnr commented on Mar 21, 2022

@lcnr
Contributor

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.

added
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)
on Dec 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-const-genericsArea: const generics (parameters and arguments)A-type-systemArea: Type systemB-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCF-const_generics`#![feature(const_generics)]`S-tracking-impl-incompleteStatus: The implementation is incomplete.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamrequires-nightlyThis issue requires a nightly compiler in some way.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @cuviper@huhlig@alexreg@eddyb@Nemo157

      Issue actions

        Tracking issue for const generics (RFC 2000) · Issue #44580 · rust-lang/rust