|
| 1 | +# "Stabilizable" prototype for expanded const generics |
| 2 | + |
| 3 | +| Metadata | | |
| 4 | +| --- | --- | |
| 5 | +| Owner(s) | @BoxyUwU | |
| 6 | +| Teams | [types] | |
| 7 | +| Status | Proposed | |
| 8 | +| Tracking issue | [rust-lang/rust-project-goals#100] | |
| 9 | + |
| 10 | + |
| 11 | +## Summary |
| 12 | + |
| 13 | +Experiment with a new `min_generic_const_args` implementation to address challenges found with the existing approach to supporting generic parameters in const generic arguments. |
| 14 | + |
| 15 | +## Motivation |
| 16 | + |
| 17 | +`min_const_generics` was stabilized with the restriction that const-generic arguments may not use generic parameters other than a bare const parameter, e.g. `Foo<N>` is legal but not `Foo<{ T::ASSOC }>`. This restriction is lifted under `feature(generic_const_exprs)` however its design is fundamentally flawed and introduces significant complexity to the compiler. A ground up rewrite of the feature with a significantly limited scope (e.g. `min_generic_const_args`) would give a viable path to stabilization and result in large cleanups to the compiler. |
| 18 | + |
| 19 | +### The status quo |
| 20 | + |
| 21 | +A large amount of rust users run into the `min_const_generics` limitation that it is not legal to use generic parameters with const generics. It is generally a bad user experience to hit a wall where a feature is unfinished, and this limitation also prevents patterns that are highly desirable. We have always intended to lift this restriction since stabilizing `min_const_generics` but we did not know how. |
| 22 | + |
| 23 | +It is possible to use generic parameters with const generics by using `feature(generic_const_exprs)`. Unfortunately this feature has a number of fundamental issues that are hard to solve and as a result is *very* broken. It being so broken results in two main issues: |
| 24 | +- When users hit a wall with `min_const_generics` they cannot reach for the `generic_const_exprs` feature because it is either broken or has no path to stabilization. |
| 25 | +- In the compiler, to work around the fundamental issues with `generic_const_exprs`, we have a number of hacks which negatively affect the quality of the codebase and the general experience of contributing to the type system. |
| 26 | + |
| 27 | +### The next six months |
| 28 | + |
| 29 | +We have a design for `min_generic_const_args` in mind but would like to validate it through implementation as const generics has a history of unforseen issues showing up during implementation. Therefore we will pursue a prototype implementation in 2025. As a stretch goal, we will attempt to review the design with the lang team in the form of a design meeting or RFC. |
| 30 | + |
| 31 | +In the past 6 months preliminary refactors were made to allow actually implementing the core of the design, this took significantly longer than expected which highlights the importance of actually implementing the design to see if it works. |
| 32 | + |
| 33 | +### The "shiny future" we are working towards |
| 34 | + |
| 35 | +The larger plan with const generics (but not this project-goal) is to bring feature-parity with type generics for const generics: |
| 36 | +- Arbitrary types can be used in const generics instead of just: integers, floats, bool and char. |
| 37 | + - implemented under `feature(adt_const_params)` and is relatively close to stabilization |
| 38 | +- Generic parameters are allowed to be used in const generic arguments (e.g. `Foo<{ <T as Trait>::ASSOC_CONST }>`). |
| 39 | +- Users can specify `_` as the argument to a const generic, allowing inferring the value just like with types. |
| 40 | + - implemented under `feature(generic_arg_infer)` and is relatively close to stabilization |
| 41 | +- Associated const items can introduce generic parameters to bring feature parity with type aliases |
| 42 | + - implemented under `feature(generic_const_items)`, needs a bit of work to finish it. Becomes significantly more important *after* implementing `min_generic_const_args` |
| 43 | +- Introduce associated const equality bounds, e.g. `T: Trait<ASSOC = N>` to bring feature parity with associated types |
| 44 | + - implemented under `feature(associated_const_equality)`, blocked on allowing generic parameters in const generic arguments |
| 45 | + |
| 46 | +Allowing generic parameters to be used in const generic arguments is the only part of const generics that requires significant amounts of work while also having significant benefit. Everything else is already relatively close to the point of stabilization. I chose to specify this goal to be for implementing `min_generic_const_args` over "stabilize the easy stuff" as I would like to know whether the implementation of `min_generic_const_args` will surface constraints on the other features that may not be possible to easily fix in a backwards compatible manner. Regardless I expect these features will still progress while `min_generic_const_args` is being implemented. |
| 47 | + |
| 48 | +## Design axioms |
| 49 | + |
| 50 | +- Do not block future extensions to const generics |
| 51 | +- It should not feel worse to write type system logic with const generics compared to type generics |
| 52 | +- Avoid post-monomorphization errors |
| 53 | +- The "minimal" subset should not feel arbitrary |
| 54 | + |
| 55 | +## Ownership and team asks |
| 56 | + |
| 57 | +**Owner:** @BoxyUwU, project-const-generics lead, T-types member |
| 58 | + |
| 59 | +This section defines the specific work items that are planned and who is expected to do them. It should also include what will be needed from Rust teams. |
| 60 | + |
| 61 | +* Subgoal: |
| 62 | + * Describe the work to be done and use `↳` to mark "subitems". |
| 63 | +* Owner(s) or team(s): |
| 64 | + * List the owner for this item (who will do the work) or ![Help wanted][] if an owner is needed. |
| 65 | + * If the item is a "team ask" (i.e., approve an RFC), put ![Team][] and the team name(s). |
| 66 | +* Status: |
| 67 | + * List ![Help wanted][] if there is an owner but they need support, for example funding. |
| 68 | + * Other needs (e.g., complete, in FCP, etc) are also fine. |
| 69 | + |
| 70 | +| Subgoal | Owner(s) or team(s) | Notes | |
| 71 | +| ---------------------------- | ------------------------- | ----- | |
| 72 | +| Discussion and moral support | ![Team][] [lang] [types] | | |
| 73 | +| Implementation and mentoring | @BoxyUwu | | |
| 74 | +| Implementation | @camelid @compiler-errors | | |
| 75 | +| Reviewer | @compiler-errors | | |
| 76 | + |
| 77 | +## Outputs and milestones |
| 78 | + |
| 79 | +### Outputs |
| 80 | + |
| 81 | +- A sound, fully implemented `feature(min_generic_const_args)` available on nightly |
| 82 | +- All issues with `generic_const_exprs`'s design have been comprehensively documented (stretch goal) |
| 83 | +- RFC for `min_generic_const_args`'s design (stretch goal) |
| 84 | + |
| 85 | +### Milestones |
| 86 | + |
| 87 | +- [x] Prerequisite refactorings for `min_generic_const_args` have taken place |
| 88 | +- Initial implementation of `min_generic_const_args` lands and is useable on nightly |
| 89 | +- All known issues are resolved with `min_generic_const_args` |
| 90 | +- Document detailing `generic_const_exprs` issues |
| 91 | +- RFC is written and filed for `min_generic_const_args` |
| 92 | + |
| 93 | +## Frequently asked questions |
| 94 | + |
| 95 | +### Do you expect `min_generic_const_args` to be stabilized by the end? |
| 96 | + |
| 97 | +No. The feature should be fully implemented such that it does not need any more work to make it ready for stabilization, however I do not intend to actually set the goal of stabilizing it as it may wind up blocked on the new trait solver being stable first. |
0 commit comments