@@ -33,16 +33,17 @@ struct Ref<'a, T> where T: 'a { r: &'a T }
33
33
struct InnerArray <T , const N : usize >([T ; N ]);
34
34
```
35
35
36
- The generic parameters are in scope within the item definition where they are
37
- declared.
36
+ Generic parameters are in scope within the item definition where they are
37
+ declared. They are not in scope for items declared within the body of a
38
+ function as described in [ item declarations] .
38
39
39
40
[ References] , [ raw pointers] , [ arrays] , [ slices] [ arrays ] , [ tuples] , and
40
41
[ function pointers] have lifetime or type parameters as well, but are not
41
42
referred to with path syntax.
42
43
43
44
### Const generics
44
45
45
- Const generic parameters allow items to be generic over constant values. The
46
+ * Const generic parameters* allow items to be generic over constant values. The
46
47
const identifier introduces a name for the constant parameter, and all
47
48
instances of the item must be instantiated with a value of the given type.
48
49
@@ -52,11 +53,10 @@ instances of the item must be instantiated with a value of the given type.
52
53
The only allowed types of const parameters are ` u8 ` , ` u16 ` , ` u32 ` , ` u64 ` , ` u128 ` , ` usize `
53
54
` i8 ` , ` i16 ` , ` i32 ` , ` i64 ` , ` i128 ` , ` isize ` , ` char ` and ` bool ` .
54
55
55
- Const parameters can generally be used anywhere a [ const item] can be used,
56
- with the exception of the definition of any [ item] within the body of a
57
- function, and can only be used as standalone expressions in [ types] and
58
- [ array repeat expressions] (described below). That is, they are allowed in the
59
- following places:
56
+ Const parameters can be used anywhere a [ const item] can be used, with the
57
+ exception that when used in a [ type] or [ array repeat expression] , it must be
58
+ standalone (as described below). That is, they are allowed in the following
59
+ places:
60
60
61
61
1 . As an applied const to any type which forms a part of the signature of the
62
62
item in question.
@@ -111,7 +111,7 @@ fn foo<const N: usize>() {
111
111
```
112
112
113
113
As a further restriction, const parameters may only appear as a standalone
114
- argument inside of [ types ] and [ array repeat expressions ] . In those contexts,
114
+ argument inside of a [ type ] or [ array repeat expression ] . In those contexts,
115
115
they may only be used as a single segment [ path expression] , possibly inside a
116
116
[ block] (such as ` N ` or ` {N} ` ). That is, they cannot be combined with other
117
117
expressions.
@@ -131,9 +131,10 @@ A const argument in a [path] specifies the const value to use for that item.
131
131
The argument must be a [ const expression] of the type ascribed to the const
132
132
parameter. The const expression must be a [ block expression] [ block ]
133
133
(surrounded with braces) unless it is a single path segment (an [ IDENTIFIER] )
134
- or a [ literal] (with a possibly leading ` - ` token). This syntactic restriction
135
- is necessary to avoid requiring infinite lookahead when parsing an expression
136
- inside of a type.
134
+ or a [ literal] (with a possibly leading ` - ` token).
135
+
136
+ > ** Note** : This syntactic restriction is necessary to avoid requiring
137
+ > infinite lookahead when parsing an expression inside of a type.
137
138
138
139
``` rust
139
140
fn double <const N : i32 >() {
@@ -156,6 +157,10 @@ When there is ambiguity if a generic argument could be resolved as either a
156
157
type or const argument, it is always resolved as a type. Placing the argument
157
158
in a block expression can force it to be interpreted as a const argument.
158
159
160
+ <!-- TODO: Rewrite the paragraph above to be in terms of namespaces, once
161
+ namespaces are introduced, and it is clear which namespace each parameter
162
+ lives in. -->
163
+
159
164
``` rust,compile_fail
160
165
type N = u32;
161
166
struct Foo<const N: usize>;
@@ -179,6 +184,26 @@ struct Baz<T>;
179
184
struct Biz<'a>;
180
185
```
181
186
187
+ When resolving a trait bound obligation, the exhaustiveness of all
188
+ implementations of const parameters is not considered when determining if the
189
+ bound is satisfied. For example, in the following, even though all possible
190
+ const values for the ` bool ` type are implemented, it is still an error that
191
+ the trait bound is not satisfied:
192
+
193
+ ``` rust,compile_fail
194
+ struct Foo<const B: bool>;
195
+ trait Bar {}
196
+ impl Bar for Foo<true> {}
197
+ impl Bar for Foo<false> {}
198
+
199
+ fn needs_bar(_: impl Bar) {}
200
+ fn generic<const B: bool>() {
201
+ let v = Foo::<B>;
202
+ needs_bar(v); // ERROR: trait bound `Foo<B>: Bar` is not satisfied
203
+ }
204
+ ```
205
+
206
+
182
207
## Where clauses
183
208
184
209
> ** <sup >Syntax</sup >** \
@@ -256,7 +281,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
256
281
[ _Type_ ] : ../types.md#type-expressions
257
282
[ _TypeParamBounds_ ] : ../trait-bounds.md
258
283
259
- [ array repeat expressions ] : ../expressions/array-expr.md
284
+ [ array repeat expression ] : ../expressions/array-expr.md
260
285
[ arrays ] : ../types/array.md
261
286
[ associated const ] : associated-items.md#associated-constants
262
287
[ associated type ] : associated-items.md#associated-types
@@ -269,6 +294,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
269
294
[ function pointers ] : ../types/function-pointer.md
270
295
[ higher-ranked lifetimes ] : ../trait-bounds.md#higher-ranked-trait-bounds
271
296
[ implementations ] : implementations.md
297
+ [ item declarations ] : ../statements.md#item-declarations
272
298
[ item ] : ../items.md
273
299
[ literal ] : ../expressions/literal-expr.md
274
300
[ path ] : ../paths.md
@@ -283,6 +309,6 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
283
309
[ trait object ] : ../types/trait-object.md
284
310
[ traits ] : traits.md
285
311
[ type aliases ] : type-aliases.md
286
- [ types ] : ../types.md
312
+ [ type ] : ../types.md
287
313
[ unions ] : unions.md
288
314
[ attributes ] : ../attributes.md
0 commit comments