-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Closed
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)A-const-genericsArea: const generics (parameters and arguments)Area: const generics (parameters and arguments)A-type-systemArea: Type systemArea: Type systemB-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.Blocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCF-const_generics`#![feature(const_generics)]``#![feature(const_generics)]`S-tracking-impl-incompleteStatus: The implementation is incomplete.Status: The implementation is incomplete.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamrequires-nightlyThis issue requires a nightly compiler in some way.This issue requires a nightly compiler in some way.
Description
Tracking issue for rust-lang/rfcs#2000
Updates:
- 2 May 2019: Tracking issue for const generics (RFC 2000) #44580 (comment)
- 19 Oct 2019: Tracking issue for const generics (RFC 2000) #44580 (comment)
- 2 Jan 2020: Tracking issue for const generics (RFC 2000) #44580 (comment)
- 22 Jul 2020: Tracking issue for const generics (RFC 2000) #44580 (comment)
- 17 Nov 2020: Tracking issue for const generics (RFC 2000) #44580 (comment)
- 11 Dez 2021: Tracking issue for const generics (RFC 2000) #44580 (comment)
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.
To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.ImplementationDocumentation- rustc guide
To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
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)
).Fix other A-const-generics issues.Audit uses ofhas_infer_types
.Forbid complex expressions for const arguments involving parameters (for now), e.g.{X * 2}
.Audit diagnostics (e.g. Add help note to unconstrained const parameter #76401 (comment)).To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
porky11, RobertWHurst, eterevsky, runiq, Antti and 172 moreburdges, archshift, Systemcluster, goodmanjonathan, est31 and 99 moreebkalderon, botev, porky11, RobertWHurst, milibopp and 87 moreknappador, aminroosta, hameerabbasi, goddessfreya, bermanboris and 6 morebermanboris, aldanor, hameerabbasi, denisandroid and CGMossa
Metadata
Metadata
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)A-const-genericsArea: const generics (parameters and arguments)Area: const generics (parameters and arguments)A-type-systemArea: Type systemArea: Type systemB-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.Blocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCF-const_generics`#![feature(const_generics)]``#![feature(const_generics)]`S-tracking-impl-incompleteStatus: The implementation is incomplete.Status: The implementation is incomplete.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamrequires-nightlyThis issue requires a nightly compiler in some way.This issue requires a nightly compiler in some way.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
eddyb commentedon Sep 15, 2017
#44275 added a
ConstEvaluatable
predicate, andWF([T; expr])
now requiresConstEvaluatable(expr)
, asexpr
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 theUnevaluated
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 commentedon Sep 18, 2017
Implementation waypoints (for more direct mentoring, seek
@eddyb
on Gitter oreddyb
on IRC):const
parameters alongside type onesparse_generic_params
- parseconst IDENT: Type
DefId
collectorty::Generics
- addconst
parameters alongside type onesgenerics_of
- createty::ConstParameterDef
fromhir::ConstParam
Def
- add a variant forconst
parameterswith_type_parameter_rib
- support both type andconst
genericsConstVal
- addParam
variant akin toty::TyParam
TyArray
with a length that's anExprPath
that resolved toDef::ConstParam
should useConstVal::Param
instead ofConstVal::Unevaluated
- in a similar fashion to howDef::TyParam
turns intoty::TyParam
subst::Kind
- support&ty::Const
and checkas_const
as well in where places whereas_type
andas_region
are checkedConstVal
- addInferVar
variant akin toty::ReVar
/ty::TyInfer(TyVar(_))
InferCtxt
-const
counterparts toint_unification_table
and itsUnifyKey
implty::relate::{Relate,TypeRelation}
- support relatingty::Const
, and handleConstVal::InferVar
in a similar way to howsuper_combine_tys
does it for typesNote 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>
.jplatte commentedon Sep 18, 2017
I'd like to take a stab at this :)
264 remaining items
bstrie commentedon Oct 20, 2019
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 commentedon Oct 20, 2019
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?
Manishearth commentedon Oct 20, 2019
You can convert a comment to an issue, but not move comments. Locking is fine, and i'd just hide off topic comments.
varkor commentedon Jan 2, 2020
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.
canonicalize_const_var
leaking inference variables #65652)resolve_type_vars_with_obligations
to also resolve const inference variables #65579){}
(Generic arg disambiguation #66104)structural_match
checking to forbid types with custom equality checking from being used as const generics (Forbid non-structural_match
types in const generics #65627)ConstValue::Placeholder
#65643, RenameConstValue::Infer(InferConst::Canonical(..))
toConstValue::Bound(..)
#65660, Fix an issue with const inference variables sticking around under Chalk + NLL #65696)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 commentedon Jul 5, 2020
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 commentedon Jul 22, 2020
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
andIntoIterator
andFromIterator
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).
unused_braces
(addunused_braces
lint #70081)dyn Trait
for const generic parameters (forbiddyn Trait
in patterns #71038)ConstKind::Param
#72052)AnonConst
s' parent ingenerics_of
. #70452)ConstKind::Error
and convertErrorHandled::Reported
to it. #71049)GenericArg
s instead ofTy
s. #70164)type_name
for const generics #68111)TooGeneric
error #67906, MakeTooGeneric
error in WF checking a proper error #68388, Move generic arg/param validation tocreate_substs_for_generic_args
to resolve various const generics issues #68434)structural_match
error diagnostic for const generics clearer #70845)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 commentedon Nov 17, 2020
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 🎉
fn array_windows
(Add array_windows fn #75026)array
lang item andfn map
to arrays (Addarray
lang item and[T; N]::map(f: FnMut(T) -> S)
#75212)min_const_generics
(Add a bunch of const-generic revisions formin_const_generics
#75322)min_const_generics
(Add regression test for #72787 #75165, Add regression test for #64494 #75166, MinConstGenerics UI test for invalid values for bool & char #78428)min_const_generics
(Add revisions to const generic issue UI tests. #76514, Finish off revisions for const generics UI tests. #76599)min_const_generics
diagnostics improvements #77825)min_const_generics
(Added somemin_const_generics
revisions intoconst_generics
tests #75938)LengthAtMost32
bound on array impls (Remove trait LengthAtMost32 #74060)min_const_generics
(resolve: prohibit anon const non-static lifetimes #76739)Index
andIndexMut
for arrays (ImplementIndex
andIndexMut
for arrays #74989)bool
in symbol mangling (Permit ty::Bool in const generics for v0 mangling #77452)ConstKind::Placeholder
(Add type toConstKind::Placeholder
#78463)char
(Support signed integers andchar
in v0 mangling #77554)impl Trait
, added tests (Fix missing diagnostic span forimpl Trait
with const generics, and add various tests formin_const_generics
andconst_generics
#77439)min_const_generics
restrictions (Implement themin_const_generics
feature gate #74877, Forbid generic parameters in anon consts inside of type defaults #74487, allow concrete self types in consts #76195, min_const_generics: allow ty param in repeat expr #78224)fn array_chunks
(addslice::array_chunks
to std #74373)array_windows
instead ofwindows
in the compiler #76825)TooGeneric
instead #76581, dead_code: look at trait impls even if they don't contain items #77073)feature(generic_const_exprs)
#76560)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.lcnr commentedon Dec 11, 2021
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 sourcework you might do. always being available is incredibly unhealthy and is not desirable or praiseworthyValtrees
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.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.
is_const_evaluatable
#82707 Fix generic arg mismatch errors being ignored with explicit late bound lifetimes #84410 Makeconst_generics_defaults
not an incomplete feature #85251 Fix some diagnostic issues with const_generics_defaults feature gate #85800 Add test for forward declared const param defaults #85896 Display defaults on const params- rustdoc #85957 const_eval_checked: Support as casts in abstract consts #86130 rustdoc- dont ICE onConstEvaluatable
predicates #86242 dont provide fwd declared params to cg defaults #86580 Make SelfInTyParamDefault wording not be specific to type defaults #87134 permit drop impls with generic constants in where clauses #87770 correctly handle enum variants inopt_const_param_of
#87854 Add tests for somefeature(const_evaluatable_checked)
incr comp issues #88146 canonicalize consts before calling try_unify_abstract_consts query #88166 Add tests for some const generics issues #88602 generic_const_exprs: use thir for abstract consts instead of mir #88709 dont.ensure()
thethir_abstract_const
query call inmir_build
#89113 Add some tests for const_generics_defaults #90114 Stabilisefeature(const_generics_defaults)
#90207impl From<[(K, V); N]> for HashMap
(and friends) #84111 Replace Copy/Clone compiler magic on arrays with library impls #86041GenericArg::Const
to reduce enum size #88574AbstractConst
private fields #88644impl Foo<const N: ty> {}
syntax #85346hir::GenericArg::Infer
inwrong_number_of_generic_args.rs
#88949[T; N]::map()
#87174feature(const_generics_defaults)
#75384 Add error message for private fn #79291 Add check for[T;N]
/usize
mismatch in astconv #80538 Add better diagnostic for unbounded Abst. Const #81544 Add diagnostics for specific cases for const/type mismatch err #82055 Allow using-C force-unwind-tables=no
whenpanic=unwind
#83482 Add hir::GenericArg::Infer #83484 Add help message to suggest const for unused type param #84784 Move generic error message to separate branches #89317WithOptConstParam
docs, move rustdoc test #78609 const_generics: assert resolve hack causes an error #79236 correctly deal with late-bound lifetimes in anon consts #79298 const_evaluatable_checked: fix occurs check #79635 always eagerly eval consts in Relate #81309 combine: stop eagerly evaluating consts #81351 add const_evaluatable_checked test #81430 const_evaluatable: stop looking into type aliases #81433 update array missingIntoIterator
msg #82626 extractConstKind::Unevaluated
into a struct #83040 various const parameter defaults improvements #84299 deal withconst_evaluatable_checked
inConstEquate
#85481 only check cg defaults wf once instantiated #86987 lazily "compute" anon const default substs #87280 update const generics feature gates #88369 small const generics cleanup #88557 add const generics test #90578const_generics_defaults
: don't ICE in the unimplemented parts #80599const_generics
replaced withadt_const_params
note #88726[T; N]
iteratorcore::array::IntoIter
#80470is_global
incandidate_should_be_dropped_in_favor_of
#90375joshtriplett commentedon Feb 9, 2022
Thanks to @lcnr for the ongoing excellent summaries!
lcnr commentedon Mar 21, 2022
All remaining const generics features are tracked in separate issues:
feature(generic_const_exprs)
#76560feature(adt_const_params)
#95174_
as a const argument:feature(generic_arg_infer)
#85077For 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.