@@ -43,16 +43,17 @@ struct Ref<'a, T> where T: 'a { r: &'a T }
43
43
struct InnerArray <T , const N : usize >([T ; N ]);
44
44
```
45
45
46
- The generic parameters are in scope within the item definition where they are
47
- declared.
46
+ Generic parameters are in scope within the item definition where they are
47
+ declared. They are not in scope for items declared within the body of a
48
+ function as described in [ item declarations] .
48
49
49
50
[ References] , [ raw pointers] , [ arrays] , [ slices] [ arrays ] , [ tuples] , and
50
51
[ function pointers] have lifetime or type parameters as well, but are not
51
52
referred to with path syntax.
52
53
53
54
### Const generics
54
55
55
- Const generic parameters allow items to be generic over constant values. The
56
+ * Const generic parameters* allow items to be generic over constant values. The
56
57
const identifier introduces a name for the constant parameter, and all
57
58
instances of the item must be instantiated with a value of the given type.
58
59
@@ -62,11 +63,10 @@ instances of the item must be instantiated with a value of the given type.
62
63
The only allowed types of const parameters are ` u8 ` , ` u16 ` , ` u32 ` , ` u64 ` , ` u128 ` , ` usize `
63
64
` i8 ` , ` i16 ` , ` i32 ` , ` i64 ` , ` i128 ` , ` isize ` , ` char ` and ` bool ` .
64
65
65
- Const parameters can generally be used anywhere a [ const item] can be used,
66
- with the exception of the definition of any [ item] within the body of a
67
- function, and can only be used as standalone expressions in [ types] and
68
- [ array repeat expressions] (described below). That is, they are allowed in the
69
- following places:
66
+ Const parameters can be used anywhere a [ const item] can be used, with the
67
+ exception that when used in a [ type] or [ array repeat expression] , it must be
68
+ standalone (as described below). That is, they are allowed in the following
69
+ places:
70
70
71
71
1 . As an applied const to any type which forms a part of the signature of the
72
72
item in question.
@@ -121,7 +121,7 @@ fn foo<const N: usize>() {
121
121
```
122
122
123
123
As a further restriction, const parameters may only appear as a standalone
124
- argument inside of [ types ] and [ array repeat expressions ] . In those contexts,
124
+ argument inside of a [ type ] or [ array repeat expression ] . In those contexts,
125
125
they may only be used as a single segment [ path expression] , possibly inside a
126
126
[ block] (such as ` N ` or ` {N} ` ). That is, they cannot be combined with other
127
127
expressions.
@@ -141,9 +141,10 @@ A const argument in a [path] specifies the const value to use for that item.
141
141
The argument must be a [ const expression] of the type ascribed to the const
142
142
parameter. The const expression must be a [ block expression] [ block ]
143
143
(surrounded with braces) unless it is a single path segment (an [ IDENTIFIER] )
144
- or a [ literal] (with a possibly leading ` - ` token). This syntactic restriction
145
- is necessary to avoid requiring infinite lookahead when parsing an expression
146
- inside of a type.
144
+ or a [ literal] (with a possibly leading ` - ` token).
145
+
146
+ > ** Note** : This syntactic restriction is necessary to avoid requiring
147
+ > infinite lookahead when parsing an expression inside of a type.
147
148
148
149
``` rust
149
150
fn double <const N : i32 >() {
@@ -166,6 +167,10 @@ When there is ambiguity if a generic argument could be resolved as either a
166
167
type or const argument, it is always resolved as a type. Placing the argument
167
168
in a block expression can force it to be interpreted as a const argument.
168
169
170
+ <!-- TODO: Rewrite the paragraph above to be in terms of namespaces, once
171
+ namespaces are introduced, and it is clear which namespace each parameter
172
+ lives in. -->
173
+
169
174
``` rust,compile_fail
170
175
type N = u32;
171
176
struct Foo<const N: usize>;
@@ -189,6 +194,26 @@ struct Baz<T>;
189
194
struct Biz<'a>;
190
195
```
191
196
197
+ When resolving a trait bound obligation, the exhaustiveness of all
198
+ implementations of const parameters is not considered when determining if the
199
+ bound is satisfied. For example, in the following, even though all possible
200
+ const values for the ` bool ` type are implemented, it is still an error that
201
+ the trait bound is not satisfied:
202
+
203
+ ``` rust,compile_fail
204
+ struct Foo<const B: bool>;
205
+ trait Bar {}
206
+ impl Bar for Foo<true> {}
207
+ impl Bar for Foo<false> {}
208
+
209
+ fn needs_bar(_: impl Bar) {}
210
+ fn generic<const B: bool>() {
211
+ let v = Foo::<B>;
212
+ needs_bar(v); // ERROR: trait bound `Foo<B>: Bar` is not satisfied
213
+ }
214
+ ```
215
+
216
+
192
217
## Where clauses
193
218
194
219
> ** <sup >Syntax</sup >** \
@@ -262,7 +287,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
262
287
[ _Type_ ] : ../types.md#type-expressions
263
288
[ _TypeParamBounds_ ] : ../trait-bounds.md
264
289
265
- [ array repeat expressions ] : ../expressions/array-expr.md
290
+ [ array repeat expression ] : ../expressions/array-expr.md
266
291
[ arrays ] : ../types/array.md
267
292
[ associated const ] : associated-items.md#associated-constants
268
293
[ associated type ] : associated-items.md#associated-types
@@ -275,6 +300,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
275
300
[ function pointers ] : ../types/function-pointer.md
276
301
[ higher-ranked lifetimes ] : ../trait-bounds.md#higher-ranked-trait-bounds
277
302
[ implementations ] : implementations.md
303
+ [ item declarations ] : ../statements.md#item-declarations
278
304
[ item ] : ../items.md
279
305
[ literal ] : ../expressions/literal-expr.md
280
306
[ path ] : ../paths.md
@@ -289,6 +315,6 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
289
315
[ trait object ] : ../types/trait-object.md
290
316
[ traits ] : traits.md
291
317
[ type aliases ] : type-aliases.md
292
- [ types ] : ../types.md
318
+ [ type ] : ../types.md
293
319
[ unions ] : unions.md
294
320
[ attributes ] : ../attributes.md
0 commit comments