@@ -124,71 +124,7 @@ fn foo<const N: usize>() {
124
124
}
125
125
```
126
126
127
- r[ items.generics.const.standalone]
128
- As a further restriction, const parameters may only appear as a standalone
129
- argument inside of a [ type] or [ array repeat expression] . In those contexts,
130
- they may only be used as a single segment [ path expression] , possibly inside a
131
- [ block] (such as ` N ` or ` {N} ` ). That is, they cannot be combined with other
132
- expressions.
133
-
134
- ``` rust,compile_fail
135
- // Examples where const parameters may not be used.
136
-
137
- // Not allowed to combine in other expressions in types, such as the
138
- // arithmetic expression in the return type here.
139
- fn bad_function<const N: usize>() -> [u8; {N + 1}] {
140
- // Similarly not allowed for array repeat expressions.
141
- [1; {N + 1}]
142
- }
143
- ```
144
-
145
- r[ items.generics.const.argument]
146
- A const argument in a [ path] specifies the const value to use for that item.
147
-
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).
153
-
154
- > [ !NOTE]
155
- > This syntactic restriction is necessary to avoid requiring infinite lookahead when parsing an expression inside of a type.
156
-
157
- ``` rust
158
- fn double <const N : i32 >() {
159
- println! (" doubled: {}" , N * 2 );
160
- }
161
-
162
- const SOME_CONST : i32 = 12 ;
163
-
164
- fn example () {
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 }>();
171
- }
172
- ```
173
-
174
- r[ items.generics.const.type-ambiguity]
175
- When there is ambiguity if a generic argument could be resolved as either a
176
- type or const argument, it is always resolved as a type. Placing the argument
177
- in a block expression can force it to be interpreted as a const argument.
178
-
179
- <!-- TODO: Rewrite the paragraph above to be in terms of namespaces, once
180
- namespaces are introduced, and it is clear which namespace each parameter
181
- lives in. -->
182
-
183
- ``` rust,compile_fail
184
- type N = u32;
185
- struct Foo<const N: usize>;
186
- // The following is an error, because `N` is interpreted as the type alias `N`.
187
- fn foo<const N: usize>() -> Foo<N> { todo!() } // ERROR
188
- // Can be fixed by wrapping in braces to force it to be interpreted as the `N`
189
- // const parameter:
190
- fn bar<const N: usize>() -> Foo<{ N }> { todo!() } // ok
191
- ```
127
+ There are limitations around how a const parameter can be used within a const argument ([ const generics] ).
192
128
193
129
r[ items.generics.const.variance]
194
130
Unlike type and lifetime parameters, const parameters can be declared without
@@ -207,26 +143,6 @@ struct Unconstrained;
207
143
impl<const N: usize> Unconstrained {}
208
144
```
209
145
210
- r[ items.generics.const.exhaustiveness]
211
- When resolving a trait bound obligation, the exhaustiveness of all
212
- implementations of const parameters is not considered when determining if the
213
- bound is satisfied. For example, in the following, even though all possible
214
- const values for the ` bool ` type are implemented, it is still an error that
215
- the trait bound is not satisfied:
216
-
217
- ``` rust,compile_fail
218
- struct Foo<const B: bool>;
219
- trait Bar {}
220
- impl Bar for Foo<true> {}
221
- impl Bar for Foo<false> {}
222
-
223
- fn needs_bar(_: impl Bar) {}
224
- fn generic<const B: bool>() {
225
- let v = Foo::<B>;
226
- needs_bar(v); // ERROR: trait bound `Foo<B>: Bar` is not satisfied
227
- }
228
- ```
229
-
230
146
r[ items.generics.where]
231
147
## Where clauses
232
148
@@ -290,10 +206,10 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
290
206
[ associated const ] : associated-items.md#associated-constants
291
207
[ associated type ] : associated-items.md#associated-types
292
208
[ attributes ] : ../attributes.md
293
- [ block ] : ../expressions/block-expr.md
294
209
[ const contexts ] : ../const_eval.md#const-context
295
210
[ const expression ] : ../const_eval.md#constant-expressions
296
211
[ const item ] : constant-items.md
212
+ [ const generics ] : ../const-generics.md
297
213
[ enumerations ] : enumerations.md
298
214
[ functions ] : functions.md
299
215
[ function pointers ] : ../types/function-pointer.md
@@ -303,7 +219,6 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
303
219
[ implementations ] : implementations.md
304
220
[ item declarations ] : ../statements.md#item-declarations
305
221
[ item ] : ../items.md
306
- [ literal ] : ../expressions/literal-expr.md
307
222
[ path ] : ../paths.md
308
223
[ path expression ] : ../expressions/path-expr.md
309
224
[ raw pointers ] : ../types/pointer.md#raw-pointers-const-and-mut
0 commit comments