gca_min_const_items
Enables the generic const args MVP (paths to direct const items and constructors for ADTs and primitives).
The tracking issue for this feature is: #132980
Warning: This feature is incomplete; its design and syntax may change.
This feature acts as a minimal alternative to generic_const_exprs that allows a smaller subset of functionality,
and uses a different approach for implementation. It is intentionally more restrictive, which helps with avoiding edge
cases that make the generic_const_exprs hard to implement properly. See Feature background
for more details.
Related features: gca_macroless_args, gca_const_items, generic_const_items.
gca! macro
This feature introduces a new macro: gca!.
When an expression is used as a generic argument, it is typically lowered as an “anon const”, which is an expression
that is opaque to the type system and cannot contain generics. Using gca! instead represents the
expression “directly”, i.e. without an anon const, in a way that is visible to the type system.
(Note that plain paths to generic parameters are always represented directly, without gca!, as this
already works on stable)
See gca_macroless_args as a feature to disable the requirement of writing gca!.
direct const items
This feature introduces a new item kind: consts with a gca! right-hand side.
Constants with a direct right-hand side are allowed to be used in type contexts, e.g.:
#![allow(incomplete_features)]
#![feature(gca_min_const_items)]
const X: usize = core::gca!(1);
const Y: usize = 1;
struct Foo {
good_arr: [(); core::gca!(X)], // Allowed
bad_arr: [(); core::gca!(Y)], // Will not compile
}
Examples
#![allow(unused)]
#![allow(incomplete_features)]
#![feature(gca_min_const_items)]
fn main() {
trait Bar {
#[rustc_always_gca]
const VAL: usize;
#[rustc_always_gca]
const VAL2: usize;
}
struct Baz;
impl Bar for Baz {
const VAL: usize = core::gca!(2);
const VAL2: usize = core::gca!(const { Self::VAL * 2 });
}
struct Foo<B: Bar> {
arr1: [usize; core::gca!(B::VAL)],
arr2: [usize; core::gca!(B::VAL2)],
}
}
Note that with generic_const_exprs the same example would look as follows:
#![allow(unused)]
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
fn main() {
trait Bar {
const VAL: usize;
const VAL2: usize;
}
struct Baz;
impl Bar for Baz {
const VAL: usize = 2;
const VAL2: usize = const { Self::VAL * 2 };
}
struct Foo<B: Bar>
where
[(); B::VAL]:,
[(); B::VAL2]:,
{
arr1: [usize; B::VAL],
arr2: [usize; B::VAL2],
}
}
Use of const functions is allowed:
#![allow(unused)]
#![allow(incomplete_features)]
#![feature(gca_min_const_items)]
fn main() {
const VAL: usize = 1;
const fn inc(val: usize) -> usize {
val + 1
}
const INC: usize = core::gca!(const { inc(VAL) });
const ARR: [usize; INC] = [0; INC];
}