|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Inferred const generic arguments: Call for Testing!" |
| 4 | +author: BoxyUwU |
| 5 | +team: The Const Generics Project Group <https://rust-lang.github.io/project-const-generics/> |
| 6 | +--- |
| 7 | + |
| 8 | +We are excited to announce that `feature(generic_arg_infer)` is nearing the point of stabilization. In this post we'd like to talk a bit about what this feature does, and what comes next for it. |
| 9 | + |
| 10 | +## What is `feature(generic_arg_infer)` |
| 11 | + |
| 12 | +When `feature(min_const_generics)` was [stabilized in early 2021](https://github.com/rust-lang/rust/pull/79135) it did not include the ability to use `_` as an explicit const argument: |
| 13 | +```rust |
| 14 | +fn foo() { |
| 15 | + // This errors due to `_` as an array length being unsupported |
| 16 | + let a: [u8; _] = [Default::default()]; |
| 17 | + // This is legal as `_` is permitted as a type argument |
| 18 | + let b: [_; 1] = a; |
| 19 | +} |
| 20 | +``` |
| 21 | + |
| 22 | +This is entirely a syntactic limitation; it is possible to entirely elide generic argument listings that may involve const arguments: |
| 23 | +```rust |
| 24 | +fn foo<const N: usize>(_: [u8; N]) {} |
| 25 | + |
| 26 | +fn bar() { |
| 27 | + // This errors due to `_` as a const argument being unsupported |
| 28 | + foo::<_>([1]); |
| 29 | + // This is legal as even though the const argument is *inferred* |
| 30 | + // there is no explicit `_` written. |
| 31 | + foo([1]); |
| 32 | +} |
| 33 | +``` |
| 34 | + |
| 35 | +The compiler has always been able to infer values for const generic parameters, only the ability to explicitly ask for a const argument to be inferred is unstable. |
| 36 | + |
| 37 | +It is currently also not possible to the infer the length of a repeat expression. Doing so would require moving the expression into a separate function generic over the array length. |
| 38 | + |
| 39 | +```rust |
| 40 | +fn foo() { |
| 41 | + // This errors due to `_` as a repeat count being unsupported |
| 42 | + let a: [_; 1] = [String::new(); _]; |
| 43 | +} |
| 44 | +``` |
| 45 | + |
| 46 | +With `feature(generic_arg_infer)` all of the previous examples compile. This should hopefully feel like something that should "obviously" be supported by Rust. |
| 47 | + |
| 48 | +## What comes next |
| 49 | + |
| 50 | +We have [significantly reworked the implementation](https://github.com/rust-lang/rust/pull/135272) of this recently and it should now be ready for stabilization. We'd love for you to try it out on a recent nightly and report any issues you encounter. |
| 51 | + |
| 52 | +## Acknowledgements |
| 53 | + |
| 54 | +My recent push to make this feature ready for testing would not have been possible without the help of many others. |
| 55 | + |
| 56 | +A big thank you to [@lcnr][lcnr] and [@JulianKnodt][JulianKnodt] for the initial implementation of `generic_arg_infer`, [@camelid][camelid] for refactoring our representation of const generic arguments to be more flexible, [@voidc][voidc] for helping unify the way we operate on array lengths and const generic arguments, [@lcnr][lcnr] for design work on abstracting away differences between inferred type/const/generic arguments, and finally [@compiler-errors][compiler-errors] for reviewing many PRs and implementation decisions made as part of work on this feature. |
| 57 | + |
| 58 | +[lcnr]: https://github.com/lcnr |
| 59 | +[JulianKnodt]: https://github.com/JulianKnodt |
| 60 | +[camelid]: https://github.com/camelid |
| 61 | +[voidc]: https://github.com/voidc |
| 62 | +[compiler-errors]: https://github.com/compiler-errors |
0 commit comments