Rust Const Generics Project Group

@rust-const-generics

Rust Const Generics Project Group

Public team

Joined on Jun 15, 2021

  • summary This document should be considered an "extension" to lcnr's min_generic_const_exprs proposal. It builds off the proposal of only allowing const items (i.e. ADD:<usize, N, 1> instead of N + 1) by adding a desugaring of N + 1 and foo(..) to const items to allow nice user facing syntax for things that seem like they should "obviously" work. changes add AbstractConst variant to ty::ConstKind Instead of storing generic type level constants as ConstKind::Unevaluated we should add a ConstKind::AbstractConst and directly lower type level generic exprs to it instead of anonymous const items: enum ConstKind<'tcx> { Param(ty::ParamConst), Infer(InferConst<'tcx>),
     Like  Bookmark
  • struct Foo; impl Foo { fn foo<const N: usize>(self) -> [u8; N] { [0; N] } // ^ called `const_param` in the diagram } struct Bar; impl Bar { fn foo<const M: i32>(self) -> [u8; 3] { [0; 3] } } fn context() -> [u8; 4] {
     Like  Bookmark
  • If we do not require a proof that generic constants are evaluatable we end up with errors during monomorphization, which is bad™ as these don't get detected by cargo check. Evaluatable bounds vs conditions TODO: Elaborate on the difference between evaluatable { N - 1 } and is_true { N > 0 }. It is not possible to rely on conditions to prevent errors during monomorphization by themselves, as it not possible for the compiler to prove that a condition completely covers the cases where some other constant panics. This is related to silent CTFE errors. Having a lint which suggests adding conditions for each potentially panicking constant is also very difficult, as the compiler does not look into functions for this. We also again have the issue that having the compiler figure out with which inputs something causes a panic is impossible. Defining evaluatable
     Like  Bookmark
  • We cannot ignore CTFE failures of constants used in the type system An impl like this is considered exhaustive impl<const N: usize> Trait<N> for () { type Assoc = [u8; 32]; const ASSOC: usize = N; } If we were to ignore (): Trait<error>, what are sensible values for the associated items of that type.
     Like  Bookmark
  • not strictly necessary things are marked with in italics. cc https://hackmd.io/dwO7dvv5RI-ob1d5P5QDQA?view adt const params structural equality opt in vs backcompat concerns function pointers
     Like  Bookmark
  • Hey :wave: after more than half a year since the last update there are some news wrt const generics. #88369 removes the unstable features const_generics, lazy_normalization_consts, and const_evaluatable_checked. Depending on what you need, you can now choose between feature(const_param_types) and feature(generic_const_exprs). While I am at it, here's a quick overview of the new - and preexisting - features and how much still needs to be done for them to get stabilized: feature(const_param_types) On stable, only integers, char and bool are allowed as the types of const parameters. This feature allows additional types, such as &'static str and user defined types. #![feature(const_param_types)] #[derive(PartialEq, Eq)]
     Like  Bookmark
  • written anonymously by two random people you will never guess who What do we want to avoid unused substs see https://github.com/rust-lang/project-const-generics/blob/master/design-docs/anon-const-substs.md#unused-substs Closures with anon consts in args cause "closure/generation that references itself" errors https://github.com/rust-lang/rust/issues/85665 #![feature(generic_const_exprs)] struct Foo<F: Fn([(); N + 1]), const N: usize>(F);
     Like  Bookmark
  • Where do const expressions appear / come from Types Array [T; C] -- anonymous constants Type parameter S<{C}> Predicates where T: Foo<C>
     Like  Bookmark
  • stabilisation PR Stabilization report This is the stabilization report for const parameter defaults and the removal of the type and const parameter ordering restriction. Its feature is #![feature(const_generics_defaults)]. This report is a collaborative effort of @BoxyUwU and @lcnr. Summary While supplying default arguments for type parameters is already possible on stable, this is not allowed for const parameters. Due to the restriction that type parameters must be in front of all const parameters, type parameter defaults cannot be used on stable if a const parameter exists.
     Like  Bookmark
  • actual impl here Note that the "error" cases always create _ patterns after hard erroring fn recur(const, behind_ref: bool) -> Result<pat, Fallback> { match const.ty { float => lint + Ok(opaque), union => error, struct + !PartialEq + !StructuralEq => error, // Super hacky: this doesn't hard error, but unwinds to where
     Like 1 Bookmark
  • What is this A write-up concerning the design space around structural equality. Motivation Pattern matching and const generics require a stricter notion of equality than PartialEq + Eq can promise. Sometimes we need to know that the PartialEq impl is equivalent to running the PartialEq impl of each field and using && to combine the results. This is true for automatically derived PartialEq impls. When using constants in patterns we can use this knowledge to "destructure" the constant and consider it during exhaustiveness checking. In case this property does not apply to the field of whatever we are matching on we can always fall back to treating the constant as unknown wrt exhaustiveness and call PartialEq::eq as if the user would have used a pattern guard instead of a pattern. An example of such fallback (more details later) would be
     Like  Bookmark