-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
docs(unstable-book): Document const generics features #155543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
5eae716
6315e17
73e44e8
c4eb1bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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)] | ||
|
popzxc marked this conversation as resolved.
|
||
| #![feature(min_generic_const_args)] | ||
| #![feature(generic_const_args)] | ||
| #![expect(incomplete_features)] | ||
|
|
||
| type const ADD1<const N: usize>: usize = const { N + 1 }; | ||
|
|
||
| type const INC<const N: usize>: usize = ADD1::<N>; | ||
|
|
||
| const ARR: [(); ADD1::<0>] = [(); INC::<0>]; | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<const N: usize> | ||
| 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<B: Bar>(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; | ||
| } | ||
|
Comment on lines
+43
to
+51
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This body sort of shifts the attention from the things I wanted to highlight, but I thought that adding |
||
| out | ||
| } | ||
|
|
||
|
|
||
| // Create a new type based on a generic argument. | ||
| pub struct Grow<const N: usize> { | ||
| arr: [usize; N], | ||
| } | ||
|
|
||
| impl<const N: usize> Grow<N> { | ||
| 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 } | ||
| } | ||
| } | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # generic_const_items | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not directly related to other 3, but it 1. seems to be cross-referenced a lot (e.g. in UI tests), and 2. similar in spirit and might often be a thing that people actually want to have. |
||
|
|
||
| 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<const ARG: usize>: usize = const { ARG + 1 }; | ||
|
popzxc marked this conversation as resolved.
Outdated
|
||
|
|
||
| #[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<const ARG: usize>: usize = const { | ||
| if ARG > 0 { | ||
| ARG + 1 | ||
| } else { | ||
| panic!("0 value") | ||
| } | ||
| }; | ||
|
popzxc marked this conversation as resolved.
Outdated
|
||
|
|
||
| // Will fail to compile if the `Copy` derive is removed. | ||
| const COPY_MARKER<C: Copy>: () = (); | ||
|
|
||
| #[derive(Clone, Copy)] | ||
| struct Foo; | ||
|
|
||
| const FOO_IS_COPY: () = COPY_MARKER::<Foo>; | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Link updated, pending corresponding PR merge |
||
| [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<B: Bar> { | ||
| 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<B: Bar> | ||
| 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]; | ||
| ``` | ||
Uh oh!
There was an error while loading. Please reload this page.