@@ -180,11 +180,9 @@ is considered local.
180
180
181
181
## Generic Implementations
182
182
183
- An implementation can take [ generic parameters] which are written directly
184
- after the ` impl ` keyword. The parameters can be used in the rest of the
185
- implementation. Type and const parameters must be used at least once in either
186
- the trait or the implementing type of an implementation. Lifetime parameters
187
- do not need to be used unless they appear in an [ associated type] .
183
+ An implementation can take [ generic parameters] , which can be used in the rest
184
+ of the implementation. Implementation parameters are written directly after the
185
+ ` impl ` keyword.
188
186
189
187
``` rust
190
188
# trait Seq <T > { fn dummy (& self , _ : T ) { } }
@@ -196,6 +194,85 @@ impl Seq<bool> for u32 {
196
194
}
197
195
```
198
196
197
+ Generic parameters * constrain* an implementation if the parameter appears at
198
+ least once in one of:
199
+
200
+ * The implemented trait, if it has one
201
+ * The implementing type
202
+ * As an [ associated type] in the [ bounds] of a type that contains another
203
+ parameter that constrains the implementation
204
+
205
+ Type and const parameters must always constrain the implementation. Lifetimes
206
+ must constrain the implementation if the lifetime is used in an associated type.
207
+
208
+ Examples of constraining situations:
209
+
210
+ ``` rust
211
+ # trait Trait {}
212
+ # trait GenericTrait <T > {}
213
+ # trait HasAssocType { type Ty ; }
214
+ # struct Struct ;
215
+ # struct GenericStruct <T >(T );
216
+ # struct ConstGenericStruct <const N : usize >([(); N ]);
217
+ // T constrains by being an argument to GenericTrait.
218
+ impl <T > GenericTrait <T > for i32 { /* ... */ }
219
+
220
+ // T constrains by being an arguement to GenericStruct
221
+ impl <T > Trait for GenericStruct <T > { /* ... */ }
222
+
223
+ // Likewise, N constrains by being an argument to ConstGenericStruct
224
+ impl <const N : usize > Trait for ConstGenericStruct <N > { /* ... */ }
225
+
226
+ // T constrains by being in an associated type in a bound for type `U` which is
227
+ // itself a generic parameter constraining the trait.
228
+ impl <T , U > GenericTrait <U > for u32 where U : HasAssocType <Ty = T > { /* ... */ }
229
+
230
+ // Like previous, except the type is `(U, isize)`. `U` appears inside the type
231
+ // that includes `T`, and is not the type itself.
232
+ impl <T , U > GenericStruct <U > where (U , isize ): HasAssocType <Ty = T > { /* ... */ }
233
+ ```
234
+
235
+ Examples of non-constraining situations:
236
+
237
+ ``` rust,compile_fail
238
+ // The rest of these are errors, since they have type or const parameters that
239
+ // do not constrain.
240
+
241
+ // T does not constrain since it does not appear at all.
242
+ impl<T> Struct { /* ... */ }
243
+
244
+ // N does not constrain for the same reason.
245
+ impl<const N: usize> Struct { /* ... */ }
246
+
247
+ // Usage of T inside the implementation does not constrain the impl.
248
+ impl<T> Struct {
249
+ fn uses_t(t: &T) { /* ... */ }
250
+ }
251
+
252
+ // T is used as an associated type in the bounds for U, but U does not constrain.
253
+ impl<T, U> Struct where U: HasAssocType<Ty = T> { /* ... */ }
254
+
255
+ // T is used in the bounds, but not as an associated type, so it does not constrain.
256
+ impl<T, U> GenericTrait<U> for u32 where U: GenericTrait<T> {}
257
+ ```
258
+
259
+ Example of an allowed unconstraining lifetime parameter:
260
+
261
+ ``` rust
262
+ # struct Struct ;
263
+ impl <'a > Struct {}
264
+ ```
265
+
266
+ Example of a disallowed unconstraining lifetime parameter:
267
+
268
+ ``` rust,compile_fail
269
+ # struct Struct;
270
+ # trait HasAssocType { type Ty; }
271
+ impl<'a> HasAssocType for Struct {
272
+ type Ty = &'a Struct;
273
+ }
274
+ ```
275
+
199
276
## Attributes on Implementations
200
277
201
278
Implementations may contain outer [ attributes] before the ` impl ` keyword and
@@ -217,18 +294,19 @@ attributes].
217
294
[ _Visibility_ ] : ../visibility-and-privacy.md
218
295
[ _WhereClause_ ] : generics.md#where-clauses
219
296
[ trait ] : traits.md
220
- [ associated functions ] : associated-items.md#associated-functions-and-methods
221
297
[ associated constants ] : associated-items.md#associated-constants
298
+ [ associated functions ] : associated-items.md#associated-functions-and-methods
222
299
[ associated type ] : associated-items.md#associated-types
223
300
[ attributes ] : ../attributes.md
301
+ [ bounds ] : ../trait-bounds.md
224
302
[ `cfg` ] : ../conditional-compilation.md
225
303
[ `deprecated` ] : ../attributes/diagnostics.md#the-deprecated-attribute
226
304
[ `doc` ] : ../../rustdoc/the-doc-attribute.html
305
+ [ generic parameters ] : generics.md
227
306
[ path ] : ../paths.md
228
307
[ the lint check attributes ] : ../attributes/diagnostics.md#lint-check-attributes
229
308
[ Unsafe traits ] : traits.md#unsafe-traits
230
309
[ local trait ] : ../glossary.md#local-trait
231
310
[ local type ] : ../glossary.md#local-type
232
311
[ fundamental types ] : ../glossary.md#fundamental-type-constructors
233
312
[ uncovered type ] : ../glossary.md#uncovered-type
234
- [ generic parameters ] : generics.md
0 commit comments