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