@@ -99,11 +99,133 @@ GenericArgsBounds ->
9999 IDENTIFIER GenericArgs ? `: ` Bounds
100100```
101101
102- r[ generics.arguments.argument-order]
103- The order of generic arguments is restricted to lifetime arguments, then type arguments, then const arguments, then equality constraints.
102+ ### Argument ordering and matching
103+
104+ r[ generics.arguments.lifetime-order]
105+ Lifetime arguments must appear before all other argument kinds.
106+
107+ > [ !EXAMPLE]
108+ > ``` rust,compile_fail
109+ > struct Foo<'a, T> {
110+ > data: &'a T,
111+ > }
112+ >
113+ > // ERROR: lifetime argument `'static` must come before type argument `i32`
114+ > let _: Foo<i32, 'static>;
115+ > ```
116+
117+ r[generics.arguments.positional-matching]
118+ Generic arguments are matched to generic parameters positionally:
119+
120+ - The i<sub>th</sub> lifetime argument corresponds to the i<sub>th</sub> lifetime parameter.
121+ - The i<sub>th</sub> type or const argument corresponds to the i<sub>th</sub> type or const parameter (counted together in declaration order).
122+
123+ r[generics.arguments.constraint-order]
124+ Associated item constraints must be listed after all other argument kinds, and may be listed in any order.
125+
126+ > [!EXAMPLE]
127+ > ```rust
128+ > use std::fmt::Display;
129+ >
130+ > trait Container {
131+ > type Item;
132+ > type Error;
133+ > }
134+ >
135+ > // Associated item constraints may be listed in any order relative to each other.
136+ > fn process<C: Container<Error = String, Item = i32>>(_: C) {}
137+ > ```
138+
139+ > [!EXAMPLE]
140+ > ```rust,compile_fail
141+ > struct Foo<'a, T> {
142+ > data: &'a T,
143+ > }
144+ >
145+ > trait MyTrait {
146+ > type Assoc;
147+ > }
148+ >
149+ > // ERROR: associated item constraints must come after all other argument kinds.
150+ > fn bad<T: MyTrait>(_: &dyn MyTrait<Assoc = i32>) where T: 'static {}
151+ > let _: std::collections::HashMap<Item = i32, String, String>;
152+ > ```
153+
154+ r[generics.arguments.lifetime-elision]
155+ Lifetime arguments may be omitted in the following cases:
156+
157+ - When [lifetime elision] rules apply.
158+ - In [turbofish] expressions (`::<...>`) where all lifetimes can be inferred.
159+
160+ > [!EXAMPLE]
161+ > ```rust
162+ > struct Foo<'a, T> {
163+ > data: &'a T,
164+ > }
165+ >
166+ > fn make_foo<'a, T>(data: &'a T) -> Foo<'a, T> {
167+ > Foo { data }
168+ > }
169+ >
170+ > // Turbofish: lifetime arguments omitted because they can be inferred.
171+ > let x = 42i32;
172+ > let foo = make_foo::<i32>(&x); // `'_` lifetime argument elided in turbofish
173+ >
174+ > // Lifetime arguments omitted in a type annotation.
175+ > let foo: Foo<i32> = Foo { data: &x };
176+ > ```
177+
178+ r[generics.arguments.all-lifetimes]
179+ If any lifetime argument is provided, then all lifetime parameters must be specified.
180+
181+ > [!EXAMPLE]
182+ > ```rust,compile_fail
183+ > struct Foo<'a, 'b, T> {
184+ > x: &'a T,
185+ > y: &'b T,
186+ > }
187+ >
188+ > fn make_foo<'a, 'b, T>(x: &'a T, y: &'b T) -> Foo<'a, 'b, T> {
189+ > Foo { x, y }
190+ > }
191+ >
192+ > let a = 1i32;
193+ > let b = 2i32;
194+ >
195+ > // OK: no lifetime arguments supplied (elided).
196+ > let _: Foo<i32> = Foo { x: &a, y: &b };
197+ > // OK: all lifetime arguments supplied.
198+ > let _: Foo<'static, 'static, i32> = Foo { x: &1, y: &2 };
199+ > // ERROR: only one of two lifetime arguments provided.
200+ > let _: Foo<'static, i32> = Foo { x: &1, y: &b };
201+ > ```
202+
203+ r[generics.arguments.defaults]
204+ Type and const parameters with default values need not be supplied. A parameter without a default cannot follow one with a default.
205+
206+ When fewer arguments are supplied than parameters exist, the missing trailing arguments use their defaults if available, or are inferred if inference is enabled for that context.
207+
208+ r[generics.arguments.self-param]
209+ The `Self` parameter (when present, e.g., in [trait definitions][items.traits.self-param]) is implicit and cannot be explicitly specified.
104210
105211r[generics.arguments.impl-trait-params]
106- The synthetic type parameters corresponding to ` impl Trait ` types are implicit, and these cannot be explicitly specified.
212+ Synthetic type parameters corresponding to `impl Trait` types are implicit and cannot be explicitly specified.
213+
214+ r[generics.arguments.late-bound-lifetimes]
215+ It is an error to provide explicit lifetime arguments when late-bound lifetimes are present.
216+
217+ > [!EXAMPLE]
218+ > ```rust,compile_fail
219+ > fn foo<'a>(x: &'a str) -> &'a str { x }
220+ >
221+ > // ERROR: cannot specify late-bound lifetime arguments explicitly
222+ > foo::<'static>("hello");
223+ > ```
224+
225+ <!--
226+ FCW exists for non-value (function) position, see
227+ https://doc.rust-lang.org/nightly/rustc/lints/listing/warn-by-default.html#late-bound-lifetime-arguments
228+ -->
107229
108230r[generics.const]
109231## Const generics
@@ -333,6 +455,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
333455[ inferred const ] : generics.const.inferred
334456[ item declarations ] : statement.item
335457[ item ] : items
458+ [ lifetime elision ] : lifetime-elision
336459[ literal ] : expr.literal
337460[ path expression ] : expr.path
338461[ path ] : paths
@@ -345,6 +468,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
345468[ trait object ] : type.trait-object
346469[ traits ] : items.traits
347470[ tuples ] : type.tuple
471+ [ turbofish ] : paths.expr.turbofish
348472[ type aliases ] : items.type
349473[ unions ] : items.union
350474[ value namespace ] : names.namespaces
0 commit comments