@@ -180,11 +180,9 @@ is considered local.
180180
181181## Generic Implementations
182182
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.
188186
189187``` rust
190188# trait Seq <T > { fn dummy (& self , _ : T ) { } }
@@ -196,6 +194,85 @@ impl Seq<bool> for u32 {
196194}
197195```
198196
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+
199276## Attributes on Implementations
200277
201278Implementations may contain outer [ attributes] before the ` impl ` keyword and
@@ -217,18 +294,19 @@ attributes].
217294[ _Visibility_ ] : ../visibility-and-privacy.md
218295[ _WhereClause_ ] : generics.md#where-clauses
219296[ trait ] : traits.md
220- [ associated functions ] : associated-items.md#associated-functions-and-methods
221297[ associated constants ] : associated-items.md#associated-constants
298+ [ associated functions ] : associated-items.md#associated-functions-and-methods
222299[ associated type ] : associated-items.md#associated-types
223300[ attributes ] : ../attributes.md
301+ [ bounds ] : ../trait-bounds.md
224302[ `cfg` ] : ../conditional-compilation.md
225303[ `deprecated` ] : ../attributes/diagnostics.md#the-deprecated-attribute
226304[ `doc` ] : ../../rustdoc/the-doc-attribute.html
305+ [ generic parameters ] : generics.md
227306[ path ] : ../paths.md
228307[ the lint check attributes ] : ../attributes/diagnostics.md#lint-check-attributes
229308[ Unsafe traits ] : traits.md#unsafe-traits
230309[ local trait ] : ../glossary.md#local-trait
231310[ local type ] : ../glossary.md#local-type
232311[ fundamental types ] : ../glossary.md#fundamental-type-constructors
233312[ uncovered type ] : ../glossary.md#uncovered-type
234- [ generic parameters ] : generics.md
0 commit comments