@@ -158,41 +158,74 @@ fn call_on_ref_zero<F>(f: F) where F: for<'a> Fn(&'a i32) {
158158
159159## Implied bounds
160160
161- Rust sometimes infers some bounds the user would have otherwise been required to write .
161+ Lifetime bounds required for types to be well-formed are sometimes inferred by the compiler .
162162
163163``` rust
164164fn requires_t_outlives_a <'a , T >(x : & 'a T ) {}
165165```
166- While this function requires ` T ` to outlive ` 'a ` , this is inferred because the function signature
167- contains the type ` &'a T ` which is only valid if ` T: 'a ` holds.
166+ The type parameter ` T ` is required to outlive ` 'a ` for the type ` &'a T ` to be well-formed.
167+ This is inferred because the function signature contains the type ` &'a T ` which is
168+ only valid if ` T: 'a ` holds.
168169
169170Rust adds implied bounds for all inputs and outputs of functions. Inside of ` requires_t_outlives_a `
170171you can assume ` T: 'a ` to hold even if you don't explicitly specify this:
171- ``` rust,compile_fail
172+ ``` rust
173+ fn requires_t_outlives_a_not_implied <'a , T : 'a >() {}
174+
172175fn requires_t_outlives_a <'a , T >(x : & 'a T ) {
173176 // This compiles, because `T: 'a` is implied by
174177 // the reference type `&'a T`.
175178 requires_t_outlives_a_not_implied :: <'a , T >();
176179}
180+ ```
177181
182+ ``` rust,compile_fail
183+ # fn requires_t_outlives_a_not_implied<'a, T: 'a>() {}
178184fn not_implied<'a, T>() {
179185 // This errors, because `T: 'a` is not implied by
180186 // the function signature.
181187 requires_t_outlives_a_not_implied::<'a, T>();
182188}
183-
184- fn requires_t_outlives_a_not_implied<'a, T: 'a>() {}
185189```
186190
187- Only lifetime bounds are implied, trait bounds still have to be explicitly added.
188- This behavior may change in the future however. The following example still causes an error:
191+ Only lifetime bounds are implied, trait bounds still have to be explicitly added. The following example therefore causes an error:
189192``` rust,compile_fail
190193use std::fmt::Debug;
191194struct IsDebug<T: Debug>(T);
192195// error[E0277]: `T` doesn't implement `Debug`
193196fn doesnt_specify_t_debug<T>(x: IsDebug<T>) {}
194197```
195198
199+ Lifetime bounds are also inferred in type definitions and impl blocks.
200+
201+ ``` rust
202+ struct Struct <'a , T > {
203+ // This requires `T: 'a` to be well-formed
204+ // which is inferred by the compiler.
205+ field : & 'a T ,
206+ }
207+
208+ enum Enum <'a , T > {
209+ // This requires `T: 'a` to be well-formed,
210+ // which is inferred by the compiler.
211+ //
212+ // Note that `T: 'a` is required even when only
213+ // using `Enum::OtherVariant`.
214+ SomeVariant (& 'a T ),
215+ OtherVariant ,
216+ }
217+
218+ trait Trait <'a , T : 'a > {}
219+
220+ // This would error because `T: 'a` is not implied by any type
221+ // in the impl header.
222+ // impl<'a, T> Trait<'a, T> for () {}
223+
224+ // This compiles as `T: 'a` is implied by the self type `&'a ()`.
225+ impl <'a , T > Trait <'a , T > for & 'a T {}
226+ ```
227+
228+
196229[ LIFETIME_OR_LABEL ] : tokens.md#lifetimes-and-loop-labels
197230[ _GenericParams_ ] : items/generics.md
198231[ _TypePath_ ] : paths.md#paths-in-types
0 commit comments