Skip to content

Commit 66ea245

Browse files
committed
Move generic args to the generics chapter
This moves the generic args so that the Generics chapter is whole, and covers all the aspects of generics.
1 parent af6a54d commit 66ea245

2 files changed

Lines changed: 78 additions & 55 deletions

File tree

src/paths.md

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,6 @@ PathExprSegment ->
5050
5151
PathIdentSegment ->
5252
IDENTIFIER | `super` | `self` | `Self` | `crate` | `$crate`
53-
54-
GenericArgs ->
55-
`<` `>`
56-
| `<` ( GenericArg `,` )* GenericArg `,`? `>`
57-
58-
GenericArg ->
59-
Lifetime | Type | GenericArgsConst | GenericArgsBinding | GenericArgsBounds
60-
61-
GenericArgsConst ->
62-
BlockExpression
63-
| LiteralExpression
64-
| `-` LiteralExpression
65-
| SimplePathSegment
66-
67-
GenericArgsBinding ->
68-
IDENTIFIER GenericArgs? `=` Type
69-
70-
GenericArgsBounds ->
71-
IDENTIFIER GenericArgs? `:` TypeParamBounds
7253
```
7354

7455
r[paths.expr.intro]
@@ -82,38 +63,6 @@ The `::` token is required before the opening `<` for generic arguments to avoid
8263
Vec::<u8>::with_capacity(1024);
8364
```
8465

85-
r[paths.expr.argument-order]
86-
The order of generic arguments is restricted to lifetime arguments, then type arguments, then const arguments, then equality constraints.
87-
88-
r[paths.expr.complex-const-params]
89-
Const arguments must be surrounded by braces unless they are a [literal], an [inferred const], or a single segment path. An [inferred const] may not be surrounded by braces.
90-
91-
```rust
92-
mod m {
93-
pub const C: usize = 1;
94-
}
95-
const C: usize = m::C;
96-
fn f<const N: usize>() -> [u8; N] { [0; N] }
97-
98-
let _ = f::<1>(); // Literal.
99-
let _: [_; 1] = f::<_>(); // Inferred const.
100-
let _: [_; 1] = f::<(((_)))>(); // Inferred const.
101-
let _ = f::<C>(); // Single segment path.
102-
let _ = f::<{ m::C }>(); // Multi-segment path must be braced.
103-
```
104-
105-
```rust,compile_fail
106-
fn f<const N: usize>() -> [u8; N] { [0; _] }
107-
let _: [_; 1] = f::<{ _ }>();
108-
// ^ ERROR `_` not allowed here
109-
```
110-
111-
> [!NOTE]
112-
> In a generic argument list, an [inferred const] is parsed as an [inferred type][InferredType] but then semantically treated as a separate kind of [const generic argument].
113-
114-
r[paths.expr.impl-trait-params]
115-
The synthetic type parameters corresponding to `impl Trait` types are implicit, and these cannot be explicitly specified.
116-
11766
r[paths.qualified]
11867
## Qualified paths
11968

@@ -465,17 +414,14 @@ mod without { // crate::without
465414
[`$crate`]: macro.decl.hygiene.crate
466415
[implementations]: items/implementations.md
467416
[items]: items.md
468-
[literal]: expressions/literal-expr.md
469417
[use declarations]: items/use-declarations.md
470418
[`Self` scope]: names/scopes.md#self-scope
471419
[`use`]: items/use-declarations.md
472420
[attributes]: attributes.md
473-
[const generic argument]: generics.const.argument
474421
[enumeration]: items/enumerations.md
475422
[expressions]: expressions.md
476423
[extern prelude]: names/preludes.md#extern-prelude
477424
[implementation]: items/implementations.md
478-
[inferred const]: generics.const.inferred
479425
[macro transcribers]: macros-by-example.md
480426
[macros]: macros.md
481427
[mbe]: macros-by-example.md

src/types/generics.md

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ let _: S<1> = f::<(((_)))>(); // Inferred const.
151151
> In a generic argument list, an [inferred const] is parsed as an [inferred type][InferredType] but then semantically treated as a separate kind of [const generic argument].
152152
153153
r[generics.const.inferred]
154-
Where a const argument is expected, an `_` (optionally surrounded by any number of matching parentheses), called the *inferred const* ([path rules][paths.expr.complex-const-params], [array expression rules][expr.array.length-restriction]), can be used instead. This asks the compiler to infer the const argument if possible based on surrounding information.
154+
Where a const argument is expected, an `_` (optionally surrounded by any number of matching parentheses), called the *inferred const* ([generic argument rules][generics.arguments.complex-const-params], [array expression rules][expr.array.length-restriction]), can be used instead. This asks the compiler to infer the const argument if possible based on surrounding information.
155155

156156
```rust
157157
fn make_buf<const N: usize>() -> [u8; N] {
@@ -225,6 +225,81 @@ fn generic<const B: bool>() {
225225
}
226226
```
227227

228+
r[generics.arguments]
229+
## Generic arguments
230+
231+
r[generics.arguments.intro]
232+
Generic arguments are the concrete values provided for generic parameters when using a parameterized item. They are specified in angle brackets (`<...>`) following the item's path (see [paths in types] and [paths in expressions]). Generic arguments can include lifetimes, types, and const values corresponding to the generic parameters declared on the item.
233+
234+
```rust
235+
struct Foo<'a, T, const N: usize> {
236+
data: &'a [T; N],
237+
}
238+
239+
fn make_foo<'a, T, const N: usize>(data: &'a [T; N]) -> Foo<'a, T, N> {
240+
Foo { data }
241+
}
242+
243+
// Generic arguments: lifetime 'static, type i32, const value 3.
244+
let foo: Foo<'static, i32, 3> = Foo { data: &[1, 2, 3] };
245+
// Example of a call expression.
246+
make_foo::<i32, 3>(&[1, 2, 3]);
247+
```
248+
249+
r[generics.arguments.syntax]
250+
```grammar,paths
251+
GenericArgs ->
252+
`<` `>`
253+
| `<` ( GenericArg `,` )* GenericArg `,`? `>`
254+
255+
GenericArg ->
256+
Lifetime | Type | GenericArgsConst | GenericArgsBinding | GenericArgsBounds
257+
258+
GenericArgsConst ->
259+
BlockExpression
260+
| LiteralExpression
261+
| `-` LiteralExpression
262+
| SimplePathSegment
263+
264+
GenericArgsBinding ->
265+
IDENTIFIER GenericArgs? `=` Type
266+
267+
GenericArgsBounds ->
268+
IDENTIFIER GenericArgs? `:` TypeParamBounds
269+
```
270+
271+
r[generics.arguments.argument-order]
272+
The order of generic arguments is restricted to lifetime parameters and then type and const parameters intermixed.
273+
274+
r[generics.arguments.complex-const-params]
275+
Const arguments must be surrounded by braces unless they are a [literal], an [inferred const], or a single segment path. An [inferred const] may not be surrounded by braces.
276+
277+
```rust
278+
mod m {
279+
pub const C: usize = 1;
280+
}
281+
const C: usize = m::C;
282+
fn f<const N: usize>() -> [u8; N] { [0; N] }
283+
284+
let _ = f::<1>(); // Literal.
285+
let _: [_; 1] = f::<_>(); // Inferred const.
286+
let _: [_; 1] = f::<(((_)))>(); // Inferred const.
287+
let _ = f::<C>(); // Single segment path.
288+
let _ = f::<{ m::C }>(); // Multi-segment path must be braced.
289+
```
290+
291+
```rust,compile_fail
292+
fn f<const N: usize>() -> [u8; N] { [0; _] }
293+
let _: [_; 1] = f::<{ _ }>();
294+
// ^ ERROR `_` not allowed here
295+
```
296+
297+
> [!NOTE]
298+
> In a generic argument list, an [inferred const] is parsed as an [inferred type][InferredType] but then semantically treated as a separate kind of [const generic argument].
299+
300+
r[generics.arguments.impl-trait-params]
301+
The synthetic type parameters corresponding to `impl Trait` types are implicit, and these cannot be explicitly specified.
302+
228303
r[generics.parameters.attributes]
229304
## Attributes
230305

@@ -266,6 +341,8 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
266341
[literal]: ../expressions/literal-expr.md
267342
[path]: ../paths.md
268343
[path expression]: ../expressions/path-expr.md
344+
[paths in expressions]: paths.expr
345+
[paths in types]: paths.type
269346
[raw pointers]: pointer.md#raw-pointers-const-and-mut
270347
[references]: pointer.md#shared-references-
271348
[structs]: ../items/structs.md

0 commit comments

Comments
 (0)