]> git.proxmox.com Git - rustc.git/blob - src/doc/nomicon/lifetime-elision.md
bcd93a58d859a96d8807f7bd8b10baf6af1264a8
[rustc.git] / src / doc / nomicon / lifetime-elision.md
1 % Lifetime Elision
2
3 In order to make common patterns more ergonomic, Rust allows lifetimes to be
4 *elided* in function signatures.
5
6 A *lifetime position* is anywhere you can write a lifetime in a type:
7
8 ```rust,ignore
9 &'a T
10 &'a mut T
11 T<'a>
12 ```
13
14 Lifetime positions can appear as either "input" or "output":
15
16 * For `fn` definitions, input refers to the types of the formal arguments
17 in the `fn` definition, while output refers to
18 result types. So `fn foo(s: &str) -> (&str, &str)` has elided one lifetime in
19 input position and two lifetimes in output position.
20 Note that the input positions of a `fn` method definition do not
21 include the lifetimes that occur in the method's `impl` header
22 (nor lifetimes that occur in the trait header, for a default method).
23
24 * In the future, it should be possible to elide `impl` headers in the same manner.
25
26 Elision rules are as follows:
27
28 * Each elided lifetime in input position becomes a distinct lifetime
29 parameter.
30
31 * If there is exactly one input lifetime position (elided or not), that lifetime
32 is assigned to *all* elided output lifetimes.
33
34 * If there are multiple input lifetime positions, but one of them is `&self` or
35 `&mut self`, the lifetime of `self` is assigned to *all* elided output lifetimes.
36
37 * Otherwise, it is an error to elide an output lifetime.
38
39 Examples:
40
41 ```rust,ignore
42 fn print(s: &str); // elided
43 fn print<'a>(s: &'a str); // expanded
44
45 fn debug(lvl: uint, s: &str); // elided
46 fn debug<'a>(lvl: uint, s: &'a str); // expanded
47
48 fn substr(s: &str, until: uint) -> &str; // elided
49 fn substr<'a>(s: &'a str, until: uint) -> &'a str; // expanded
50
51 fn get_str() -> &str; // ILLEGAL
52
53 fn frob(s: &str, t: &str) -> &str; // ILLEGAL
54
55 fn get_mut(&mut self) -> &mut T; // elided
56 fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded
57
58 fn args<T: ToCStr>(&mut self, args: &[T]) -> &mut Command // elided
59 fn args<'a, 'b, T: ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // expanded
60
61 fn new(buf: &mut [u8]) -> BufWriter; // elided
62 fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // expanded
63
64 ```