For const generics, we will eventually allow arbitrary structural_match values as generic arguments. Thus, we need to figure out how to mangle them. At the moment, only unsigned integers are supported.
min_const_generics
bool (https://github.com/rust-lang/rust/pull/77452)charconst_generics
cc @eddyb @yodaldevoid
cc #60705
At the moment, only unsigned integers are supported.
bools work too, don't they? https://github.com/rust-lang/rust/issues/61383#issuecomment-497534678
@est31: the current implementation of const generics supports more types than the mangle supports, which is something we need to address.
@varkor I see. As you are special casing bools already in #61409 do you think they should be allowed in the initial version of const generics, too? Mangling schemes for them are straightforward.
It's unclear what "initial version of const generics" means at this point. We're not ready to talk about stabilisation yet. Hopefully we'll be able to discuss proper mangling soon. I know @eddyb already has some ideas.
Quoting @eddyb from Discord channel #compiler for my own benefit if nothing else:
unsigned integers is really what people want, IMO. but I have an idea of how to encode arbitrary ADTs into the symbol mangling, so it shouldn't be too bad
(basically something like
std::fmt::Formatter::debug_{list,struct,tuple}, and the struct/tuple forms can take a path that's the path of the variant in an enum, for enum values)
lol I didn't finish my thought: you'd encode
Some(0i32)as something likeTNvINt...6OptioniE4Somei0_E
that is,...::Option<i32>::Some(0i32)
Such printing should probably share the walking logic with the const validator (https://github.com/rust-lang/rust/blob/master/src/librustc_mir/interpret/validity.rs), because both need to do the same thing.
These tests fail with -Zsymbol-mangling-version=v0:
[ui] ui/const-generics/fn-const-param-call.rs
[ui] ui/const-generics/issues/issue-61432.rs
[ui] ui/const-generics/issues/issue-62579-no-match.rs
[ui] ui/const-generics/raw-ptr-const-param-deref.rs
[ui] ui/const-generics/slice-const-param.rs
Maybe we should start adding revisions that use -Zsymbol-mangling-version=v0 to all const generic tests and FIXMEs pointing to this issue for the ones that don't work?
More specifically, what I did to test this was replace Legacy with V0 here: https://github.com/rust-lang/rust/blob/42ce9b4e9054d63c8f352f994e2d5dae7d04130f/src/librustc_session/options.rs#L953
I've just noticed a potential issue with the syntax:
We support p after the "basic type" (currently only unsigned integers).
As a type, p means "placeholder" and is printed as _.
This is useful for e.g. a static inside an impl method, because it doesn't depend on the impls's parameters, so we end up with e.g. <Foo<_>>::foo::BAR.
But for a constant integer, we encode a similar situation (e.g. <ArrayVec<_, _>>::foo::BAR) using, for the const generic arg, jp (j is the type usize) - so more like _: usize than just _.
(For completeness, 42: usize is encoded as j2a_ - i.e. we use the value in hex)
Now, jp vs just p (which is not supported as a constant right now) is harmless, even if a bit longer, and the ability to print _: usize in verbose mode is neat.
But if we start including ADTs, we might need, for const generics of type (usize, usize), to encode TjpjpE, i.e. (_: usize, _: usize), printed as (_, _) by default.
This is starting to get weird, but it's still manageable, the real problem is enums.
How would you encode an erased Option<usize>? Normal values of that type would be rely on either Option::<usize>::Some or Option::<usize>::None, but for placeholders we can't choose.
The good news is we can still add a general placeholder, either just p as a constant, or p followed by its type (if we want to be able to print a type).
However, since the type of a constant must be monomorphic (or maybe in the future, determined by type parameters in scope), we don't have to encode it.
Speaking of which, the current syntax is also redundant in that we print all the integers the same, so we don't really need to encode which one it is, just that the hex nibbles should be printed as an integer.
We're permitting signed integers for min_const_generics, so we need to at least handle those.
Signed integers and char are now supported: https://github.com/rust-lang/rust/pull/77554, so marking this as unblocking.
Most helpful comment
Signed integers and
charare now supported: https://github.com/rust-lang/rust/pull/77554, so marking this as unblocking.