Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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];
}