Skip to content

Commit 1c3659a

Browse files
committed
Updates from review.
1 parent ebb5552 commit 1c3659a

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
@@ -33,16 +33,17 @@ struct Ref<'a, T> where T: 'a { r: &'a T }
3333
struct InnerArray<T, const N: usize>([T; N]);
3434
```
3535

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].
3839

3940
[References], [raw pointers], [arrays], [slices][arrays], [tuples], and
4041
[function pointers] have lifetime or type parameters as well, but are not
4142
referred to with path syntax.
4243

4344
### Const generics
4445

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

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

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

6161
1. As an applied const to any type which forms a part of the signature of the
6262
item in question.
@@ -111,7 +111,7 @@ fn foo<const N: usize>() {
111111
```
112112

113113
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,
115115
they may only be used as a single segment [path expression], possibly inside a
116116
[block] (such as `N` or `{N}`). That is, they cannot be combined with other
117117
expressions.
@@ -131,9 +131,10 @@ A const argument in a [path] specifies the const value to use for that item.
131131
The argument must be a [const expression] of the type ascribed to the const
132132
parameter. The const expression must be a [block expression][block]
133133
(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.
137138
138139
```rust
139140
fn double<const N: i32>() {
@@ -156,6 +157,10 @@ When there is ambiguity if a generic argument could be resolved as either a
156157
type or const argument, it is always resolved as a type. Placing the argument
157158
in a block expression can force it to be interpreted as a const argument.
158159

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+
159164
```rust,compile_fail
160165
type N = u32;
161166
struct Foo<const N: usize>;
@@ -179,6 +184,26 @@ struct Baz<T>;
179184
struct Biz<'a>;
180185
```
181186

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+
182207
## Where clauses
183208

184209
> **<sup>Syntax</sup>**\
@@ -256,7 +281,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
256281
[_Type_]: ../types.md#type-expressions
257282
[_TypeParamBounds_]: ../trait-bounds.md
258283

259-
[array repeat expressions]: ../expressions/array-expr.md
284+
[array repeat expression]: ../expressions/array-expr.md
260285
[arrays]: ../types/array.md
261286
[associated const]: associated-items.md#associated-constants
262287
[associated type]: associated-items.md#associated-types
@@ -269,6 +294,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
269294
[function pointers]: ../types/function-pointer.md
270295
[higher-ranked lifetimes]: ../trait-bounds.md#higher-ranked-trait-bounds
271296
[implementations]: implementations.md
297+
[item declarations]: ../statements.md#item-declarations
272298
[item]: ../items.md
273299
[literal]: ../expressions/literal-expr.md
274300
[path]: ../paths.md
@@ -283,6 +309,6 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
283309
[trait object]: ../types/trait-object.md
284310
[traits]: traits.md
285311
[type aliases]: type-aliases.md
286-
[types]: ../types.md
312+
[type]: ../types.md
287313
[unions]: unions.md
288314
[attributes]: ../attributes.md

0 commit comments

Comments
 (0)