]> git.proxmox.com Git - rustc.git/blob - src/doc/trpl/lifetimes.md
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / doc / trpl / lifetimes.md
1 % Lifetimes
2
3 This guide is one of three presenting Rust’s ownership system. This is one of
4 Rust’s most unique and compelling features, with which Rust developers should
5 become quite acquainted. Ownership is how Rust achieves its largest goal,
6 memory safety. There are a few distinct concepts, each with its own chapter:
7
8 * [ownership][ownership], the key concept
9 * [borrowing][borrowing], and their associated feature ‘references’
10 * lifetimes, which you’re reading now
11
12 These three chapters are related, and in order. You’ll need all three to fully
13 understand the ownership system.
14
15 [ownership]: ownership.html
16 [borrowing]: references-and-borrowing.html
17
18 # Meta
19
20 Before we get to the details, two important notes about the ownership system.
21
22 Rust has a focus on safety and speed. It accomplishes these goals through many
23 ‘zero-cost abstractions’, which means that in Rust, abstractions cost as little
24 as possible in order to make them work. The ownership system is a prime example
25 of a zero-cost abstraction. All of the analysis we’ll talk about in this guide
26 is _done at compile time_. You do not pay any run-time cost for any of these
27 features.
28
29 However, this system does have a certain cost: learning curve. Many new users
30 to Rust experience something we like to call ‘fighting with the borrow
31 checker’, where the Rust compiler refuses to compile a program that the author
32 thinks is valid. This often happens because the programmer’s mental model of
33 how ownership should work doesn’t match the actual rules that Rust implements.
34 You probably will experience similar things at first. There is good news,
35 however: more experienced Rust developers report that once they work with the
36 rules of the ownership system for a period of time, they fight the borrow
37 checker less and less.
38
39 With that in mind, let’s learn about lifetimes.
40
41 # Lifetimes
42
43 Lending out a reference to a resource that someone else owns can be
44 complicated. For example, imagine this set of operations:
45
46 - I acquire a handle to some kind of resource.
47 - I lend you a reference to the resource.
48 - I decide I’m done with the resource, and deallocate it, while you still have
49 your reference.
50 - You decide to use the resource.
51
52 Uh oh! Your reference is pointing to an invalid resource. This is called a
53 dangling pointer or ‘use after free’, when the resource is memory.
54
55 To fix this, we have to make sure that step four never happens after step
56 three. The ownership system in Rust does this through a concept called
57 lifetimes, which describe the scope that a reference is valid for.
58
59 When we have a function that takes a reference by argument, we can be implicit
60 or explicit about the lifetime of the reference:
61
62 ```rust
63 // implicit
64 fn foo(x: &i32) {
65 }
66
67 // explicit
68 fn bar<'a>(x: &'a i32) {
69 }
70 ```
71
72 The `'a` reads ‘the lifetime a’. Technically, every reference has some lifetime
73 associated with it, but the compiler lets you elide them in common cases.
74 Before we get to that, though, let’s break the explicit example down:
75
76 ```rust,ignore
77 fn bar<'a>(...)
78 ```
79
80 This part declares our lifetimes. This says that `bar` has one lifetime, `'a`.
81 If we had two reference parameters, it would look like this:
82
83 ```rust,ignore
84 fn bar<'a, 'b>(...)
85 ```
86
87 Then in our parameter list, we use the lifetimes we’ve named:
88
89 ```rust,ignore
90 ...(x: &'a i32)
91 ```
92
93 If we wanted an `&mut` reference, we’d do this:
94
95 ```rust,ignore
96 ...(x: &'a mut i32)
97 ```
98
99 If you compare `&mut i32` to `&'a mut i32`, they’re the same, it’s just that
100 the lifetime `'a` has snuck in between the `&` and the `mut i32`. We read `&mut
101 i32` as ‘a mutable reference to an i32’ and `&'a mut i32` as ‘a mutable
102 reference to an `i32` with the lifetime `'a`’.
103
104 # In `struct`s
105
106 You’ll also need explicit lifetimes when working with [`struct`][structs]s:
107
108 ```rust
109 struct Foo<'a> {
110 x: &'a i32,
111 }
112
113 fn main() {
114 let y = &5; // this is the same as `let _y = 5; let y = &_y;`
115 let f = Foo { x: y };
116
117 println!("{}", f.x);
118 }
119 ```
120
121 [structs]: structs.html
122
123 As you can see, `struct`s can also have lifetimes. In a similar way to functions,
124
125 ```rust
126 struct Foo<'a> {
127 # x: &'a i32,
128 # }
129 ```
130
131 declares a lifetime, and
132
133 ```rust
134 # struct Foo<'a> {
135 x: &'a i32,
136 # }
137 ```
138
139 uses it. So why do we need a lifetime here? We need to ensure that any reference
140 to a `Foo` cannot outlive the reference to an `i32` it contains.
141
142 ## `impl` blocks
143
144 Let’s implement a method on `Foo`:
145
146 ```rust
147 struct Foo<'a> {
148 x: &'a i32,
149 }
150
151 impl<'a> Foo<'a> {
152 fn x(&self) -> &'a i32 { self.x }
153 }
154
155 fn main() {
156 let y = &5; // this is the same as `let _y = 5; let y = &_y;`
157 let f = Foo { x: y };
158
159 println!("x is: {}", f.x());
160 }
161 ```
162
163 As you can see, we need to declare a lifetime for `Foo` in the `impl` line. We repeat
164 `'a` twice, just like on functions: `impl<'a>` defines a lifetime `'a`, and `Foo<'a>`
165 uses it.
166
167 ## Multiple lifetimes
168
169 If you have multiple references, you can use the same lifetime multiple times:
170
171 ```rust
172 fn x_or_y<'a>(x: &'a str, y: &'a str) -> &'a str {
173 # x
174 # }
175 ```
176
177 This says that `x` and `y` both are alive for the same scope, and that the
178 return value is also alive for that scope. If you wanted `x` and `y` to have
179 different lifetimes, you can use multiple lifetime parameters:
180
181 ```rust
182 fn x_or_y<'a, 'b>(x: &'a str, y: &'b str) -> &'a str {
183 # x
184 # }
185 ```
186
187 In this example, `x` and `y` have different valid scopes, but the return value
188 has the same lifetime as `x`.
189
190 ## Thinking in scopes
191
192 A way to think about lifetimes is to visualize the scope that a reference is
193 valid for. For example:
194
195 ```rust
196 fn main() {
197 let y = &5; // -+ y goes into scope
198 // |
199 // stuff // |
200 // |
201 } // -+ y goes out of scope
202 ```
203
204 Adding in our `Foo`:
205
206 ```rust
207 struct Foo<'a> {
208 x: &'a i32,
209 }
210
211 fn main() {
212 let y = &5; // -+ y goes into scope
213 let f = Foo { x: y }; // -+ f goes into scope
214 // stuff // |
215 // |
216 } // -+ f and y go out of scope
217 ```
218
219 Our `f` lives within the scope of `y`, so everything works. What if it didn’t?
220 This code won’t work:
221
222 ```rust,ignore
223 struct Foo<'a> {
224 x: &'a i32,
225 }
226
227 fn main() {
228 let x; // -+ x goes into scope
229 // |
230 { // |
231 let y = &5; // ---+ y goes into scope
232 let f = Foo { x: y }; // ---+ f goes into scope
233 x = &f.x; // | | error here
234 } // ---+ f and y go out of scope
235 // |
236 println!("{}", x); // |
237 } // -+ x goes out of scope
238 ```
239
240 Whew! As you can see here, the scopes of `f` and `y` are smaller than the scope
241 of `x`. But when we do `x = &f.x`, we make `x` a reference to something that’s
242 about to go out of scope.
243
244 Named lifetimes are a way of giving these scopes a name. Giving something a
245 name is the first step towards being able to talk about it.
246
247 ## 'static
248
249 The lifetime named ‘static’ is a special lifetime. It signals that something
250 has the lifetime of the entire program. Most Rust programmers first come across
251 `'static` when dealing with strings:
252
253 ```rust
254 let x: &'static str = "Hello, world.";
255 ```
256
257 String literals have the type `&'static str` because the reference is always
258 alive: they are baked into the data segment of the final binary. Another
259 example are globals:
260
261 ```rust
262 static FOO: i32 = 5;
263 let x: &'static i32 = &FOO;
264 ```
265
266 This adds an `i32` to the data segment of the binary, and `x` is a reference
267 to it.
268
269 ## Lifetime Elision
270
271 Rust supports powerful local type inference in function bodies, but it’s
272 forbidden in item signatures to allow reasoning about the types based on
273 the item signature alone. However, for ergonomic reasons a very restricted
274 secondary inference algorithm called “lifetime elision” applies in function
275 signatures. It infers only based on the signature components themselves and not
276 based on the body of the function, only infers lifetime parameters, and does
277 this with only three easily memorizable and unambiguous rules. This makes
278 lifetime elision a shorthand for writing an item signature, while not hiding
279 away the actual types involved as full local inference would if applied to it.
280
281 When talking about lifetime elision, we use the term *input lifetime* and
282 *output lifetime*. An *input lifetime* is a lifetime associated with a parameter
283 of a function, and an *output lifetime* is a lifetime associated with the return
284 value of a function. For example, this function has an input lifetime:
285
286 ```rust,ignore
287 fn foo<'a>(bar: &'a str)
288 ```
289
290 This one has an output lifetime:
291
292 ```rust,ignore
293 fn foo<'a>() -> &'a str
294 ```
295
296 This one has a lifetime in both positions:
297
298 ```rust,ignore
299 fn foo<'a>(bar: &'a str) -> &'a str
300 ```
301
302 Here are the three rules:
303
304 * Each elided lifetime in a function’s arguments becomes a distinct lifetime
305 parameter.
306
307 * If there is exactly one input lifetime, elided or not, that lifetime is
308 assigned to all elided lifetimes in the return values of that function.
309
310 * If there are multiple input lifetimes, but one of them is `&self` or `&mut
311 self`, the lifetime of `self` is assigned to all elided output lifetimes.
312
313 Otherwise, it is an error to elide an output lifetime.
314
315 ### Examples
316
317 Here are some examples of functions with elided lifetimes. We’ve paired each
318 example of an elided lifetime with its expanded form.
319
320 ```rust,ignore
321 fn print(s: &str); // elided
322 fn print<'a>(s: &'a str); // expanded
323
324 fn debug(lvl: u32, s: &str); // elided
325 fn debug<'a>(lvl: u32, s: &'a str); // expanded
326
327 // In the preceding example, `lvl` doesn’t need a lifetime because it’s not a
328 // reference (`&`). Only things relating to references (such as a `struct`
329 // which contains a reference) need lifetimes.
330
331 fn substr(s: &str, until: u32) -> &str; // elided
332 fn substr<'a>(s: &'a str, until: u32) -> &'a str; // expanded
333
334 fn get_str() -> &str; // ILLEGAL, no inputs
335
336 fn frob(s: &str, t: &str) -> &str; // ILLEGAL, two inputs
337 fn frob<'a, 'b>(s: &'a str, t: &'b str) -> &str; // Expanded: Output lifetime is ambiguous
338
339 fn get_mut(&mut self) -> &mut T; // elided
340 fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded
341
342 fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command // elided
343 fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // expanded
344
345 fn new(buf: &mut [u8]) -> BufWriter; // elided
346 fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // expanded
347 ```