Skip to content

Commit f07b828

Browse files
committed
Updates from review.
1 parent 84a0a7a commit f07b828

File tree

1 file changed

+40
-14
lines changed

1 file changed

+40
-14
lines changed

src/items/generics.md

+40-14
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,17 @@ struct Ref<'a, T> where T: 'a { r: &'a T }
4343
struct InnerArray<T, const N: usize>([T; N]);
4444
```
4545

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. Note that they are not in scope for items declared within the body
48+
of a function as described in [item declarations].
4849

4950
[References], [raw pointers], [arrays], [slices][arrays], [tuples], and
5051
[function pointers] have lifetime or type parameters as well, but are not
5152
referred to with path syntax.
5253

5354
### Const generics
5455

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
5657
const identifier introduces a name for the constant parameter, and all
5758
instances of the item must be instantiated with a value of the given type.
5859

@@ -62,11 +63,10 @@ instances of the item must be instantiated with a value of the given type.
6263
The only allowed types of const parameters are `u8`, `u16`, `u32`, `u64`, `u128`, `usize`
6364
`i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `char` and `bool`.
6465

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:
7070

7171
1. As an applied const to any type which forms a part of the signature of the
7272
item in question.
@@ -121,7 +121,7 @@ fn foo<const N: usize>() {
121121
```
122122

123123
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,
125125
they may only be used as a single segment [path expression], possibly inside a
126126
[block] (such as `N` or `{N}`). That is, they cannot be combined with other
127127
expressions.
@@ -141,9 +141,10 @@ A const argument in a [path] specifies the const value to use for that item.
141141
The argument must be a [const expression] of the type ascribed to the const
142142
parameter. The const expression must be a [block expression][block]
143143
(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.
147148
148149
```rust
149150
fn double<const N: i32>() {
@@ -166,6 +167,10 @@ When there is ambiguity if a generic argument could be resolved as either a
166167
type or const argument, it is always resolved as a type. Placing the argument
167168
in a block expression can force it to be interpreted as a const argument.
168169

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+
169174
```rust,compile_fail
170175
type N = u32;
171176
struct Foo<const N: usize>;
@@ -189,6 +194,26 @@ struct Baz<T>;
189194
struct Biz<'a>;
190195
```
191196

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+
192217
## Where clauses
193218

194219
> **<sup>Syntax</sup>**\
@@ -262,7 +287,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
262287
[_Type_]: ../types.md#type-expressions
263288
[_TypeParamBounds_]: ../trait-bounds.md
264289

265-
[array repeat expressions]: ../expressions/array-expr.md
290+
[array repeat expression]: ../expressions/array-expr.md
266291
[arrays]: ../types/array.md
267292
[associated const]: associated-items.md#associated-constants
268293
[associated type]: associated-items.md#associated-types
@@ -275,6 +300,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
275300
[function pointers]: ../types/function-pointer.md
276301
[higher-ranked lifetimes]: ../trait-bounds.md#higher-ranked-trait-bounds
277302
[implementations]: implementations.md
303+
[item declarations]: ../statements.md#item-declarations
278304
[item]: ../items.md
279305
[literal]: ../expressions/literal-expr.md
280306
[path]: ../paths.md
@@ -289,6 +315,6 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
289315
[trait object]: ../types/trait-object.md
290316
[traits]: traits.md
291317
[type aliases]: type-aliases.md
292-
[types]: ../types.md
318+
[type]: ../types.md
293319
[unions]: unions.md
294320
[attributes]: ../attributes.md

0 commit comments

Comments
 (0)