@@ -67,36 +67,23 @@ The only allowed types of const parameters are `u8`, `u16`, `u32`, `u64`, `u128`
6767` i8 ` , ` i16 ` , ` i32 ` , ` i64 ` , ` i128 ` , ` isize ` , ` char ` and ` bool ` .
6868
6969r[ items.generics.const.usage]
70- Const parameters can be used anywhere a [ const item] can be used, with the
71- exception that when used in a [ type] or [ array repeat expression] , it must be
72- standalone (as described below). That is, they are allowed in the following
73- places:
74-
75- 1 . As an applied const to any type which forms a part of the signature of the
76- item in question.
77- 2 . As part of a const expression used to define an [ associated const] , or as a
78- parameter to an [ associated type] .
79- 3 . As a value in any runtime expression in the body of any functions in the
80- item.
81- 4 . As a parameter to any type used in the body of any functions in the item.
82- 5 . As a part of the type of any fields in the item.
83-
70+ Within an item that has const parameter declarations, the names of the const parameters are values:
8471``` rust
8572// Examples where const generic parameters can be used.
8673
8774// Used in the signature of the item itself.
8875fn foo <const N : usize >(arr : [i32 ; N ]) {
89- // Used as a type within a function body.
76+ // Used within a type within a function body.
9077 let x : [i32 ; N ];
91- // Used as an expression.
78+ // Used within an expression.
9279 println! (" {}" , N * 2 );
9380}
9481
95- // Used as a field of a struct.
82+ // Used within a field of a struct.
9683struct Foo <const N : usize >([i32 ; N ]);
9784
9885impl <const N : usize > Foo <N > {
99- // Used as an associated constant.
86+ // Used within an associated constant.
10087 const CONST : usize = N * 4 ;
10188}
10289
@@ -105,13 +92,14 @@ trait Trait {
10592}
10693
10794impl <const N : usize > Trait for Foo <N > {
108- // Used as an associated type.
95+ // Used within an associated type.
10996 type Output = [i32 ; N ];
11097}
11198```
11299
113100``` rust,compile_fail
114- // Examples where const generic parameters cannot be used.
101+ // Examples where const generic parameters cannot be used as the uses are not
102+ // within the item defining the const parameter.
115103fn foo<const N: usize>() {
116104 // Cannot use in item definitions within a function body.
117105 const BAD_CONST: [usize; N] = [1; N];
@@ -124,71 +112,7 @@ fn foo<const N: usize>() {
124112}
125113```
126114
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- ```
115+ There are limitations around how a const parameter can be used within a const argument ([ const generics] ).
192116
193117r[ items.generics.const.variance]
194118Unlike type and lifetime parameters, const parameters can be declared without
@@ -207,26 +131,6 @@ struct Unconstrained;
207131impl<const N: usize> Unconstrained {}
208132```
209133
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-
230134r[ items.generics.where]
231135## Where clauses
232136
@@ -290,10 +194,10 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
290194[ associated const ] : associated-items.md#associated-constants
291195[ associated type ] : associated-items.md#associated-types
292196[ attributes ] : ../attributes.md
293- [ block ] : ../expressions/block-expr.md
294197[ const contexts ] : ../const_eval.md#const-context
295198[ const expression ] : ../const_eval.md#constant-expressions
296199[ const item ] : constant-items.md
200+ [ const generics ] : ../const-generics.md
297201[ enumerations ] : enumerations.md
298202[ functions ] : functions.md
299203[ function pointers ] : ../types/function-pointer.md
@@ -303,7 +207,6 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
303207[ implementations ] : implementations.md
304208[ item declarations ] : ../statements.md#item-declarations
305209[ item ] : ../items.md
306- [ literal ] : ../expressions/literal-expr.md
307210[ path ] : ../paths.md
308211[ path expression ] : ../expressions/path-expr.md
309212[ raw pointers ] : ../types/pointer.md#raw-pointers-const-and-mut
@@ -315,4 +218,4 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
315218[ type aliases ] : type-aliases.md
316219[ type ] : ../types.md
317220[ unions ] : unions.md
318- [ value namespace ] : ../names/namespaces.md
221+ [ value namespace ] : ../names/namespaces.md
0 commit comments