You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/expressions/array-expr.md
+14-1Lines changed: 14 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -35,7 +35,18 @@ r[expr.array.length-operand]
35
35
The expression after the `;` is called the *length operand*.
36
36
37
37
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]).
39
+
40
+
```rust
41
+
constC:usize=1;
42
+
let_: [u8; C] = [0; 1]; // Literal.
43
+
let_: [u8; C] = [0; C]; // Constant item.
44
+
let_: [u8; C] = [0; _]; // Inferred const.
45
+
let_: [u8; C] = [0; (((_)))]; // Inferred const.
46
+
```
47
+
48
+
> [!NOTE]
49
+
> In an array expression, an [inferred const] is parsed as an [expression][Expression] but then semantically treated as a separate kind of [const generic argument].
39
50
40
51
r[expr.array.repeat-behavior]
41
52
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.
@@ -111,8 +122,10 @@ The array index expression can be implemented for types other than arrays and sl
A const argument in a [path] specifies the const value to use for that item.
147
147
148
148
r[items.generics.const.argument.const-expr]
149
-
The argument must be a [const expression] of the type ascribed to the const
150
-
parameter. The const expression must be a [block expression][block]
151
-
(surrounded with braces) unless it is a single path segment (an [IDENTIFIER])
152
-
or a [literal] (with a possibly leading `-` token).
149
+
The argument must either be an [inferred const] or be a [const expression] of the type ascribed to the const parameter. The const expression must be a [block expression][block] (surrounded with braces) unless it is a single path segment (an [IDENTIFIER]) or a [literal] (with a possibly leading `-` token).
153
150
154
151
> [!NOTE]
155
152
> This syntactic restriction is necessary to avoid requiring infinite lookahead when parsing an expression inside of a type.
156
153
157
154
```rust
158
-
fndouble<constN:i32>() {
159
-
println!("doubled: {}", N*2);
160
-
}
155
+
structS<constN:i64>;
156
+
constC:i64=1;
157
+
fnf<constN:i64>() ->S<N> { S }
158
+
159
+
let_=f::<1>(); // Literal.
160
+
let_=f::<-1>(); // Negative literal.
161
+
let_=f::<{ 1+2 }>(); // Constant expression.
162
+
let_=f::<C>(); // Single segment path.
163
+
let_=f::<{ C+1 }>(); // Constant expression.
164
+
let_:S<1> =f::<_>(); // Inferred const.
165
+
let_:S<1> =f::<(((_)))>(); // Inferred const.
166
+
```
167
+
168
+
> [!NOTE]
169
+
> In a generic argument list, an [inferred const] is parsed as an [inferred type][InferredType] but then semantically treated as a separate kind of [const generic argument].
161
170
162
-
constSOME_CONST:i32=12;
171
+
r[items.generics.const.inferred]
172
+
Where a const argument is expected, an `_` (optionally surrounding by any number of matching parentheses), called the *inferred const* ([path rules][paths.expr.complex-const-params], [array expression rules][expr.array.length-restriction]), can be used instead. This asks the compiler to infer the const argument if possible based on surrounding information.
163
173
164
-
fnexample() {
165
-
// Example usage of a const argument.
166
-
double::<9>();
167
-
double::<-123>();
168
-
double::<{7+8}>();
169
-
double::<SOME_CONST>();
170
-
double::<{ SOME_CONST+5 }>();
174
+
```rust
175
+
fnmake_buf<constN:usize>() -> [u8; N] {
176
+
[0; _]
177
+
// ^ Infers `N`.
171
178
}
179
+
let_: [u8; 1024] =make_buf::<_>();
180
+
// ^ Infers `1024`.
181
+
```
182
+
183
+
> [!NOTE]
184
+
> An [inferred const] is not semantically an [expression][Expression] and so is not accepted within braces.
185
+
>
186
+
> ```rust,compile_fail
187
+
> fn f<const N: usize>() -> [u8; N] { [0; _] }
188
+
> let _: [_; 1] = f::<{ _ }>();
189
+
> // ^ ERROR `_` not allowed here
190
+
> ```
191
+
192
+
r[items.generics.const.inferred.constraint]
193
+
The inferred const cannot be used in item signatures.
Copy file name to clipboardExpand all lines: src/paths.md
+26-2Lines changed: 26 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -91,8 +91,30 @@ The order of generic arguments is restricted to lifetime arguments, then type
91
91
arguments, then const arguments, then equality constraints.
92
92
93
93
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.
94
+
Const arguments must be surrounded by braces unless they are a [literal], an [inferred const], or a single segment path. An [inferred const] may not be surrounded by braces.
95
+
96
+
```rust
97
+
modm {
98
+
pubconstC:usize=1;
99
+
}
100
+
constC:usize=m::C;
101
+
fnf<constN:usize>() -> [u8; N] { [0; N] }
102
+
103
+
let_=f::<1>(); // Literal.
104
+
let_: [_; 1] =f::<_>(); // Inferred const.
105
+
let_: [_; 1] =f::<(((_)))>(); // Inferred const.
106
+
let_=f::<C>(); // Single segment path.
107
+
let_=f::<{ m::C }>(); // Multi-segment path must be braced.
108
+
```
109
+
110
+
```rust,compile_fail
111
+
fn f<const N: usize>() -> [u8; N] { [0; _] }
112
+
let _: [_; 1] = f::<{ _ }>();
113
+
// ^ ERROR `_` not allowed here
114
+
```
115
+
116
+
> [!NOTE]
117
+
> In a generic argument list, an [inferred const] is parsed as an [inferred type][InferredType] but then semantically treated as a separate kind of [const generic argument].
96
118
97
119
r[paths.expr.impl-trait-params]
98
120
The synthetic type parameters corresponding to `impl Trait` types are implicit,
@@ -480,10 +502,12 @@ mod without { // crate::without
0 commit comments