š” official blog Generic Const Args and You | Inside Rust Blog
https://blog.rust-lang.org/inside-rust/2026/10/02/generic-const-args-and-you/72
u/kiujhytg2 19h ago
Thanks for all of your hard work, const generics is one of those "It can't be that hard, can it, can't you just ..." tasks that's more complex than it initially seems
41
u/yodal_ 17h ago
I remember when work was first starting on const generics. I was actually one of the first people to work on it, though lcnr quickly became the main driving force as I had to focus on my senior year of college. We got full const generics "working" pretty quickly all things considered. It was only a few months of work off and on. I remember finally getting a const generics program building and running around Christmas Eve of 2017. One of the first programs even used expressions! It felt like we were so close.
We then realized how many corner cases and hidden assumptions there were hiding all over the compiler. This resulted in at least three massive refactors to get even min_const_generics over the finish line. It is crazy to think that the "full" feature is still being worked on nearly a decade later, but just from the early work I can't say I'm too surprised.
18
u/noop_noob 16h ago
generic_const_exprs is one of the nightly features that is prone to crashing the compiler. List of known crashes: https://github.com/rust-lang/rust/issues?q=is%3Aissue+state%3Aopen+label%3AF-generic_const_exprs+label%3AI-ICE
28
u/Shnatsel 19h ago
min_generic_const_args and the full-blown generic_const_args would be very useful for SIMD, so I'm excited to hear there is progress!
22
u/CouteauBleu 14h ago
This article is really missing an explanation of what the gca! macro means and why it's necessary.
From the background I have, I'm guessing it's mostly about semver stability (e.g. if any function can be used in type signatures, then changing any function body becomes a breaking change) but I'd appreciate a full explanation spelling it out rather than just "this macro allows you to used this syntax but not that one".
6
u/kibwen 10h ago
See the prior discussion from this Zulip thread for more information on the difficulties that motivated the current design and its limitations: https://rust-lang.zulipchat.com/#narrow/channel/260443-project-const-generics/topic/nightly-2026-09-06.20generic.20const.20regression/near/622430401
8
u/matthieum [he/him] 14h ago
There are hints dropped in the What is Macroless section.
Apparently, it's just about being explicit about GCA being used, tying in with your remark on SemVer I guess.
But yeah... I kinda kept wondering if the topic of why there's a macro would be addressed later in the article, and was left hanging.
11
u/CouteauBleu 12h ago
There are hints dropped in the What is Macroless section.
That section doesn't actually what "GCA" is for. Like, it says that using the
gca!syntax implicitly would make it unclear when the restrictions apply, but the article doesn't explain whygca!even has these restrictions in the first place.4
u/kotakotik22 13h ago
I agree, that would have been nice.
I think it's also because GCA types push errors to post-mono: some definitely-erroneous functions would never produce a compiler error if they're never called. For example:
``` fn foo<const N : usize>() -> usize { N }
// note: the ABC type parameter is necessary so that the compiler doesn't automatically monomorphize this function. For the current rust compiler this doesn't make a difference but it would for a theoretical one where everything is GCA fn bar<const ABC : usize>() -> usize { foo::<{ 0usize - 1 }>() } ```
Currently, this will fail to compile even if
baris never used (monomorphized). If everything was GCA, this would only produce an error once bar is used by another function. (Similar to a panicking const-block)I'm not really sure how much of an issue this really is: there are not many cases where a constant fails to initialize and it is known to always fail. But it does make some small difference for users and likely a huge difference for the compiler.
2
u/kotakotik22 13h ago
This could also have bigger consequences with potential future features. For example, if constants could have global side effects, it would suddenly begin to matter whether a constant was used at all: under GCA, global state would now depend on whether a function is called anywhere in the program.
Also, if we added
whereclauses which depend on constant arguments (e.g.where N > 16), we would now have a lot of functions that are more difficult to debug becauseNcould be influenced by anything in the call chain.And maybe more substantial cases I can't think of right now.
15
5
u/bascule 14h ago
Very excited for this feature as using an associated constant as the size of an array is the main reason RustCrypto has used typenum and hybrid-array/generic-array.
GCA should allow us to completely eliminate use of hybrid-array. We may need to keep using typenum for awhile until const generic expressions actually have full feature parity with it, but as soon as we can use typenum::Unsigned::USIZE as N in [T; N] the need for hybrid-array goes away.
3
u/Thomasedv 16h ago
I skimmed the article, so pardon if it's already stated. My head isn't able to parse all that complexity on a late Friday.Ā
One of the tings I miss was when working on a function where most things were the same, but it branched on an enum with 3 values.Ā
Much to my disappointment, this didn't work despite the enum being stateless so it's just pure integers at that point being used. Seeing the article, I didn't see if this special case was mentioned or not, only that you'd have to use the macro for an enum with fields that hold values. Ideally the stateless enums could easily be converted to pure integers behind the scenes and circumvent GCA complexity entirely?Ā
Const generics with enums seems so much better for readability. Especially at the caller side where you'll either pass a number/bool, or some named constant to represent the value as a number. It makes so much more sense to have the enum directly and use it in the function. And the macro makes you pay an near equal amount of readability to use the function.Ā
Also, for the macroless case, is it a compiler limit that we can leave the syntax inside the const block as some MaybeGca type, and resolve it based on the expected type? After all the function or struct already defines the expected type, so if you know that, you should know if you're getting something that potentially is GCA? I'm not particularly familiar with const generics, so I'm just guessing. My knowledge of this starts and stops with trying to use an enum variant as a const.
6
u/vdrnm 16h ago
Enums are supported with nightly feature
min_adt_const_params.
Obviously not super convenient due tonightlyand having to useConstParamTyderive, but it works:#![feature(min_adt_const_params)] use core::marker::ConstParamTy; #[derive(ConstParamTy, PartialEq,Eq)] enum UEnum { One,Two,Three } fn generic_over_enum<const E: UEnum>() { match E { UEnum::One => println!("one"), UEnum::Two => println!("two"), UEnum::Three => println!("three"), } }2
u/Thomasedv 15h ago
Thanks for that. It would certainly be enough for my use.Ā
Hopefully it makes it to stable in some form, as it's very convenient when needed. Sadly I don't want to use nightly for my own project.Ā
5
u/Mrblahblah200 13h ago
Why is the gca macro here needed? Also, itās a liiittle ugly, I hope itās removed or renamed before release
2
u/noop_noob 13h ago
This is explained in the post under the heading "What is Macroless"
1
u/Mrblahblah200 8h ago
Ah cheers! I disagree with their reasoning honestly. It smacks to me of purity over utility
0
u/SirKastic23 8h ago
Did you read the post?
All GCA features require any newly supported expressions to be written inside of a gca! macro call. We are aware that this requirement poses significant ergonomic problems and are currently looking into ways to avoid this, though have not arrived at a good solution yet (more on this later).
3
u/ioneska 2h ago
Did you read the post?
All GCA features require any newly supported expressions to be written inside of a gca! macro call.
And yet this doesn't really answer to the parent question: Why is the gca macro here needed.
2
u/SirKastic23 1h ago
Probably because this is an experimental feature?
I guess I would have liked to see why they decided to require the macro for the feature, so it's a fair question by all means
But assuming that this is how the feature would land in stable doesn't make any sense
2
2
u/InternationalFee3911 15h ago
Just at lunch Iād been niggling that the new release once again didnāt advance constexprs. Followed right on the heels by this articleā¦
While itās amazing and laudable the amount of dedication and resourcefulness that goes into fixing these surprisingly hard problems, at the same time it makes me cry. Basic arithmetic ([u8; N-1]) is one of the things I long for most. The macro sure feels alien, but if it gives a huge benefit, itās not too bad as a workaround.
But the timeline ā letās hope GCA lands before GTA VII (rumored 2030!)
2
u/________-__-_______ 11h ago
Great to see this is actively progressing! Together with const fn in trait this is the feature I most often miss when doing compile time chicanery, really excited for it to be stabilized.
3
u/Lucretiel Datadog 10h ago
As excited as I am for const generic expressions (Iāve needed them surprisingly more often than I expected), Iām gonna be honest that Iām not a fan of the vibes on this. Is the macro expected to be temporary? I think Iām a bigger than most of new language features on average, but this definitely crosses a qualitative line in my head towards the ālost the plotā the characterizes a lot of modern C++ features.Ā
3
2
u/SirKastic23 8h ago edited 8h ago
Iām gonna be honest that Iām not a fan of the vibes on this. Is the macro expected to be temporary?
Is the only vibe you have an issue with the macro?
The post makes it clear it is meant to be temporary
All GCA features require any newly supported expressions to be written inside of a gca! macro call. We are aware that this requirement poses significant ergonomic problems and are currently looking into ways to avoid this, though have not arrived at a good solution yet (more on this later).
2
u/yuriks 7h ago edited 7h ago
Yeah honestly, I've occasionally wanted the ability to use arithmetic expressions in const generic parameters, and was also excited for the reduction of restrictions on the feature just from the principle of "things that feel like they should work should work" which seems to underpin a lot of the recent work on the language. But after reading this post I was just left with the feeling that "maybe I can do without this one, actually". :|
I'm definitely missing some of the context on the implementation difficulties since it's been a while since I've read into this deeply, but the article I feel also didn't do a great job convincing me why I would want to deal with this. The allowed kinds of expressions seem very limited (e.g. from what I understand arithmetic is still actually impossible? Or at least none of the examples clearly showed it being possible.) and there aren't motivational examples showing how they could improve existing code. The justification for the
gca!syntax also seemed circular. It talks about how it's needed to distinguish what parameters can use the new flexibility or not, but from my point of view all of those restrictions seem to stem more from compiler limitations rather than a semantic difference that I should be paying attention to as a programmer.I'll have to give it a re-read later to see if I just need some more coffee, but I'm glad to see I'm at least not alone in being confused(?) by the post.
EDIT: To clarify, I'm not criticizing the work that went into the feature at all. I understand how challenging it is to design and implement these things. I guess my point is that, as a call to action/testing, I don't feel like the article really inspired me to experiment or be excited about what's coming from it.
0
u/sasik520 15h ago
I sometimes wonder if it didn't go too far.
The article mentions rust wants to support stuff like struct Bar<const N: Foo>; or fn accepts_arrays<const N: [usize; 2]>() {}. I just wonder, if this really brings that much benefit?
So far, all use cases I've seen involve ints and the most demanded thing is being able to add and/or substract consts, e.g.
``` struct Bar<const N: usize> {}
impl<const N: usize> Bar<N> { fn baz() -> Baz { Baz::<N + 2> {} } } ```
Maybe plain simple enums could be supported too, but honestly since nothing stop an enum to add a parametrized variant at any time, I'm unsure if it's that good idea.
Are there really any real-life use cases for more complex const generics and especially ones that justify all of this extreme complexity?
(btw. I have an exact same thought on specialization)
9
u/CouteauBleu 14h ago
One very immediate use-case is being able to use
NonZeroU32and the likes in const generics, without special-casing them.7
u/Lasuman 15h ago
Yes there are certainly use cases for complex const-generics, a good example is my crate which uses them to encode possible-value-sets.
-4
u/sasik520 15h ago
I mean... don't be offended please, but this is an example of a crate with 67 downloads.
Does it justify years of work of multiple people and probably hundreds of thousands of line of code in the compiler and the tooling?
7
u/Lasuman 15h ago
Crates that make use of many very unstable features naturally have a very limited potential user base.
Since const-generics are very limited on stable, what you generally see in the wild will only make use of the currently available feature set.Also hundreds of thousands LOC is an overestimation by an order of magnitude.
6
u/Recatek gecs 13h ago
Every addition to the language that satisfies my use case is vital.
Every addition to the language unrelated to my use case is bloat.
1
u/sasik520 13h ago
There are for sure people thinking this way but that's definitely not my point of view and I have never started anything like that.
2
u/Tastaturtaste 14h ago
Of course there won't be much code in the wild showing use-cases as long as it's not possible to write the code on stable.Ā
If you are interested in use-cases that will be possible with this, you can take a look at C++'s Non-Type-Template-Parameters (NTTPs), which since C++ 20 also support structural types.Ā
One use-case could be support for a custom "on-drop" function on
my::Boxwithout increasing it's size: If the "on-drop" function is stateless and its type can be made part of the Box instantiation, the instance wouldn't have to store the function or even a pointer to the function.Ā ĀĀ Ā struct Box<T, const F: FnOnce(T)>{}Ā Ā Ā Ā let box = Box::new::<i32, typeof!(|n| println!("{n}"))>(5);Ā Ā Ā Ā assert_eq!(std::mem::size_of_val(&box), 8);Ā Ā Ā Ā drop(box); // prints 5
As you probably notice, other stuff is still missing to make this possible:
typeofis one of the missing pieces. But generic_const_exprs should get us one step closer.3
u/SmartAsFart 10h ago
You don't need const generics for a custom drop function. You just create a
Droppertrait with a method which you call with the contents of your custom box. This is a ZST, with no requirement for const generics.1
77
u/Recatek gecs 20h ago
The generic_const_exprs feature is probably the #1 most frequent unstable feature that the compiler points out to me as I'm writing code. I constantly bang my head against this limitation right now. Always very excited and eager to read about progress in this space.