diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 1785014954093..ff2baf30e1c88 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -527,8 +527,9 @@ declare_features! ( /// Allows defining gen blocks and `gen fn`. (unstable, gen_blocks, "1.75.0", Some(117078)), /// Allows using generics in more complex const expressions, based on definitional equality. - (unstable, generic_const_args, "1.95.0", Some(151972)), - /// Allows non-trivial generic constants which have to have wfness manually propagated to callers + (incomplete, generic_const_args, "1.95.0", Some(151972)), + /// Allows non-trivial generic constants which have to be shown to successfully evaluate + /// to a value by being part of an item signature. (incomplete, generic_const_exprs, "1.56.0", Some(76560)), /// Allows generic parameters and where-clauses on free & associated const items. (incomplete, generic_const_items, "1.73.0", Some(113521)), @@ -590,7 +591,8 @@ declare_features! ( /// Allows additional const parameter types, such as [u8; 10] or user defined types. /// User defined types must not have fields more private than the type itself. (unstable, min_adt_const_params, "1.96.0", Some(154042)), - /// Enables the generic const args MVP (only bare paths, not arbitrary computation). + /// Enables the generic const args MVP (paths to type const items and constructors + /// for ADTs and primitives). (incomplete, min_generic_const_args, "1.84.0", Some(132980)), /// A minimal, sound subset of specialization intended to be used by the /// standard library until the soundness issues with specialization diff --git a/src/doc/unstable-book/src/language-features/generic-const-args.md b/src/doc/unstable-book/src/language-features/generic-const-args.md new file mode 100644 index 0000000000000..b9870e60d0f91 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/generic-const-args.md @@ -0,0 +1,37 @@ +# generic_const_args + +Allows using generics in more complex const expressions, based on definitional equality. + +The tracking issue for this feature is: [#151972] + +[#151972]: https://github.com/rust-lang/rust/issues/151972 + +------------------------ + +Warning: This feature is incomplete; its design and syntax may change. + +This feature enables many of the same use cases supported by [generic_const_exprs], +but based on the machinery developed for [min_generic_const_args]. In a way, it is +meant to be an interim successor for GCE (though it might not currently support all +the valid cases that supported by GCE). + +See also: [generic_const_items] + +[min_generic_const_args]: min-generic-const-args.md +[generic_const_exprs]: generic-const-exprs.md +[generic_const_items]: generic-const-items.md + +## Examples + +```rust +#![feature(generic_const_items)] +#![feature(min_generic_const_args)] +#![feature(generic_const_args)] +#![expect(incomplete_features)] + +type const ADD1: usize = const { N + 1 }; + +type const INC: usize = ADD1::; + +const ARR: [(); ADD1::<0>] = [(); INC::<0>]; +``` diff --git a/src/doc/unstable-book/src/language-features/generic-const-exprs.md b/src/doc/unstable-book/src/language-features/generic-const-exprs.md new file mode 100644 index 0000000000000..2085ed8fed0cc --- /dev/null +++ b/src/doc/unstable-book/src/language-features/generic-const-exprs.md @@ -0,0 +1,73 @@ +# generic_const_exprs + +Allows non-trivial generic constants which have to be shown to successfully evaluate +to a value by being part of an item signature. + +The tracking issue for this feature is: [#76560] + + +[#76560]: https://github.com/rust-lang/rust/issues/76560 + +------------------------ + +Warning: This feature is incomplete; its design and syntax may change. + +See also: [min_generic_const_args], [generic_const_args] + +[min_generic_const_args]: min-generic-const-args.md +[generic_const_args]: generic-const-args.md + +## Examples + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +// Use parameters that depend on a generic argument. +struct Foo +where + [(); N + 1]:, +{ + array: [usize; N + 1], +} + +// Use generic parameters in const operations. +trait Bar { + const X: usize; + const Y: usize; +} + +// Note `B::X * B::Y`. +const fn baz(x: [usize; B::X], y: [usize; B::Y]) -> [usize; B::X * B::Y] { + let mut out = [0; B::X * B::Y]; + let mut i = 0; + while i < B::Y { + let mut j = 0; + while j < B::X { + out[i * B::X + j] = y[i].saturating_mul(x[j]); + j += 1; + } + i += 1; + } + out +} + + +// Create a new type based on a generic argument. +pub struct Grow { + arr: [usize; N], +} + +impl Grow { + pub const fn grow(self, val: usize) -> Grow<{ N + 1 }> { + let mut new_arr = [0; { N + 1 }]; + let mut idx = 0; + while idx < N { + new_arr[idx] = self.arr[idx]; + idx += 1; + } + new_arr[N] = val; + Grow { arr: new_arr } + } +} +``` diff --git a/src/doc/unstable-book/src/language-features/generic-const-items.md b/src/doc/unstable-book/src/language-features/generic-const-items.md new file mode 100644 index 0000000000000..c856c9f135aff --- /dev/null +++ b/src/doc/unstable-book/src/language-features/generic-const-items.md @@ -0,0 +1,53 @@ +# generic_const_items + +Allows generic parameters and where-clauses on free & associated const items. + +The tracking issue for this feature is: [#113521] + +[#113521]: https://github.com/rust-lang/rust/issues/113521 + +------------------------ + +Warning: This feature is an [experiment] and lacks an RFC. +There are no guarantees that it will ever be stabilized. + +See also: [generic_const_exprs], [min_generic_const_args]. + +[experiment]: https://lang-team.rust-lang.org/how_to/experiment.html +[generic_const_exprs]: generic-const-exprs.md +[min_generic_const_args]: min-generic-const-args.md + +## Examples + +### Generic constant values + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_items)] + +const GENERIC_VAL: usize = ARG + 1; + +#[test] +fn generic_const_arg() { + assert_eq!(GENERIC_VAL::<1>, 2); + assert_eq!(GENERIC_VAL::<2>, 3); +} +``` + +### Conditional constants + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_items)] + +// `GENERIC_VAL::<0>` will fail to compile +const GENERIC_VAL: usize = if ARG > 0 { ARG + 1 } else { panic!("0 value") }; + +// Will fail to compile if the `Copy` derive is removed. +const COPY_MARKER: () = (); + +#[derive(Clone, Copy)] +struct Foo; + +const FOO_IS_COPY: () = COPY_MARKER::; +``` diff --git a/src/doc/unstable-book/src/language-features/min-generic-const-args.md b/src/doc/unstable-book/src/language-features/min-generic-const-args.md new file mode 100644 index 0000000000000..336b6a420c2d6 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/min-generic-const-args.md @@ -0,0 +1,110 @@ +# min_generic_const_args + +Enables the generic const args MVP (paths to type const items and constructors for ADTs and primitives). + +The tracking issue for this feature is: [#132980] + +[#132980]: https://github.com/rust-lang/rust/issues/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][feature_background] +for more details. + +Related features: [generic_const_args], [generic_const_items]. + +[feature_background]: https://github.com/rust-lang/project-const-generics/blob/main/documents/min_const_generics_plan.md +[generic_const_exprs]: generic-const-exprs.md +[generic_const_args]: generic-const-args.md +[generic_const_items]: generic-const-items.md + +## `type const` syntax + +This feature introduces new syntax: `type const`. +Constants marked as `type const` are allowed to be used in type contexts, e.g.: + +```compile_fail +#![allow(incomplete_features)] +#![feature(min_generic_const_args)] + +type const X: usize = 1; +const Y: usize = 1; + +struct Foo { + good_arr: [(); X], // Allowed + bad_arr: [(); Y], // Will not compile, `Y` must be `type const`. +} +``` + +## Examples + +```rust +#![allow(incomplete_features)] +#![feature(min_generic_const_args)] + +trait Bar { + type const VAL: usize; + type const VAL2: usize; +} + +struct Baz; + +impl Bar for Baz { + type const VAL: usize = 2; + type const VAL2: usize = const { Self::VAL * 2 }; +} + +struct Foo { + arr1: [usize; B::VAL], + arr2: [usize; B::VAL2], +} +``` + +Note that with [generic_const_exprs] the same example would look as follows: + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +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 +where + [(); B::VAL]:, + [(); B::VAL2]:, +{ + arr1: [usize; B::VAL], + arr2: [usize; B::VAL2], +} +``` + +Use of const functions is allowed: + +```rust +#![allow(incomplete_features)] +#![feature(min_generic_const_args)] + +const VAL: usize = 1; + +const fn inc(val: usize) -> usize { + val + 1 +} + +type const INC: usize = const { inc(VAL) }; + +const ARR: [usize; INC] = [0; INC]; +```