Skip to content

Commit 50073d8

Browse files
committed
Improve the generic_arg_infer docs
Syntactically, the inferred const is an expression. Semantically, though, it's a new kind of const generic argument. Let's add the necessary language in various places to make this all clear, and let's fix the grammar for `GenericArgsConst` correspondingly.
1 parent b5f6be8 commit 50073d8

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

src/expressions/array-expr.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ r[expr.array.length-operand]
3535
The expression after the `;` is called the *length operand*.
3636

3737
r[expr.array.length-restriction]
38-
It must have type `usize` and be a [constant expression], such as a [literal] or a [constant item].
38+
The length operand must either be an [inferred const] or be a [constant expression] of type `usize` (e.g. a [literal] or a [constant item]).
3939

4040
r[expr.array.repeat-behavior]
4141
An array expression of this form creates an array with the length of the value of the length operand with each element being a copy of the repeat operand.
@@ -113,6 +113,7 @@ The array index expression can be implemented for types other than arrays and sl
113113
[array]: ../types/array.md
114114
[constant expression]: ../const_eval.md#constant-expressions
115115
[constant item]: ../items/constant-items.md
116+
[inferred const]: items.generics.const.inferred
116117
[literal]: ../tokens.md#literals
117118
[memory location]: ../expressions.md#place-expressions-and-value-expressions
118119
[panic]: ../panic.md

src/items/generics.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,17 +172,24 @@ fn example() {
172172
```
173173

174174
r[items.generics.const.inferred]
175-
Where a const argument is expected, an `_` (optionally surrounding by any number of matching parentheses), called the "inferred const", can be used instead. This asks the compiler to infer the const argument if possible based on surrounding information.
175+
Where a const argument is expected, an `_` (optionally surrounding by any number of matching parentheses), called the *inferred const* ([grammar][InferredConst], [path rules][paths.expr.complex-const-params]), can be used instead. This asks the compiler to infer the const argument if possible based on surrounding information.
176176

177177
```rust
178-
fn make_buf() -> [u8; 1024] {
178+
fn make_buf<const N: usize>() -> [u8; N] {
179179
[0x1; _]
180-
// ^ Infers `1024`.
180+
// ^ Infers `N`.
181181
}
182+
let _: [u8; 1024] = make_buf::<_>();
183+
// ^ Infers `1024`.
182184
```
183185

184186
r[items.generics.const.inferred.constraint]
185-
It cannot be used in item signatures.
187+
The inferred const cannot be used in item signatures.
188+
189+
```rust,compile_fail
190+
fn f<const N: usize>(x: [u8; N]) -> [u8; _] { x }
191+
// ^ ERROR
192+
```
186193

187194
r[items.generics.const.type-ambiguity]
188195
When there is ambiguity if a generic argument could be resolved as either a

src/paths.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,15 @@ GenericArg ->
6262
6363
GenericArgsConst ->
6464
BlockExpression
65+
| InferredConst
6566
| LiteralExpression
6667
| `-` LiteralExpression
6768
| SimplePathSegment
6869
70+
InferredConst ->
71+
| `(` InferredConst `)`
72+
| `_`
73+
6974
GenericArgsBinding ->
7075
IDENTIFIER GenericArgs? `=` Type
7176
@@ -91,8 +96,21 @@ The order of generic arguments is restricted to lifetime arguments, then type
9196
arguments, then const arguments, then equality constraints.
9297

9398
r[paths.expr.complex-const-params]
94-
Const arguments must be surrounded by braces unless they are a
95-
[literal] or a single segment path.
99+
Const arguments must be surrounded by braces unless they are a [literal], an [inferred const] ([grammar][InferredConst]), or a single segment path.
100+
101+
```rust
102+
mod m {
103+
const C: usize = 42;
104+
}
105+
const C: usize = m::C;
106+
fn callee<const N: usize>() {}
107+
108+
callee::<42>(); // Literal.
109+
callee::<_>(); // Inferred constn.
110+
callee::<(((_)))>(); // Inferred const.
111+
callee::<C>(); // Single segment path.
112+
callee::<{ m::C }>(); // Multi-segment path must be braced.
113+
```
96114

97115
r[paths.expr.impl-trait-params]
98116
The synthetic type parameters corresponding to `impl Trait` types are implicit,
@@ -484,6 +502,7 @@ mod without { // crate::without
484502
[expressions]: expressions.md
485503
[extern prelude]: names/preludes.md#extern-prelude
486504
[implementation]: items/implementations.md
505+
[inferred const]: items.generics.const.inferred
487506
[macro transcribers]: macros-by-example.md
488507
[macros]: macros.md
489508
[mbe]: macros-by-example.md

0 commit comments

Comments
 (0)