]> git.lizzy.rs Git - rust.git/blob - src/doc/book/lifetimes.md
core: Use raw pointers to avoid aliasing in str::split_at_mut
[rust.git] / src / doc / book / lifetimes.md
1 % Lifetimes
2
3 This guide is three 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 1. I acquire a handle to some kind of resource.
47 2. I lend you a reference to the resource.
48 3. I decide I’m done with the resource, and deallocate it, while you still have
49   your reference.
50 4. 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 (i.e. omit, see
74 ["Lifetime Elision"][lifetime-elision] below) them in common cases.
75 Before we get to that, though, let’s break the explicit example down:
76
77 [lifetime-elision]: #lifetime-elision
78
79 ```rust,ignore
80 fn bar<'a>(...)
81 ```
82
83 We previously talked a little about [function syntax][functions], but we didn’t
84 discuss the `<>`s after a function’s name. A function can have ‘generic
85 parameters’ between the `<>`s, of which lifetimes are one kind. We’ll discuss
86 other kinds of generics [later in the book][generics], but for now, let’s
87 focus on the lifetimes aspect.
88
89 [functions]: functions.html
90 [generics]: generics.html
91
92 We use `<>` to declare our lifetimes. This says that `bar` has one lifetime,
93 `'a`. If we had two reference parameters, it would look like this:
94
95
96 ```rust,ignore
97 fn bar<'a, 'b>(...)
98 ```
99
100 Then in our parameter list, we use the lifetimes we’ve named:
101
102 ```rust,ignore
103 ...(x: &'a i32)
104 ```
105
106 If we wanted a `&mut` reference, we’d do this:
107
108 ```rust,ignore
109 ...(x: &'a mut i32)
110 ```
111
112 If you compare `&mut i32` to `&'a mut i32`, they’re the same, it’s that
113 the lifetime `'a` has snuck in between the `&` and the `mut i32`. We read `&mut
114 i32` as ‘a mutable reference to an `i32`’ and `&'a mut i32` as ‘a mutable
115 reference to an `i32` with the lifetime `'a`’.
116
117 # In `struct`s
118
119 You’ll also need explicit lifetimes when working with [`struct`][structs]s that
120 contain references:
121
122 ```rust
123 struct Foo<'a> {
124     x: &'a i32,
125 }
126
127 fn main() {
128     let y = &5; // this is the same as `let _y = 5; let y = &_y;`
129     let f = Foo { x: y };
130
131     println!("{}", f.x);
132 }
133 ```
134
135 [structs]: structs.html
136
137 As you can see, `struct`s can also have lifetimes. In a similar way to functions,
138
139 ```rust
140 struct Foo<'a> {
141 # x: &'a i32,
142 # }
143 ```
144
145 declares a lifetime, and
146
147 ```rust
148 # struct Foo<'a> {
149 x: &'a i32,
150 # }
151 ```
152
153 uses it. So why do we need a lifetime here? We need to ensure that any reference
154 to a `Foo` cannot outlive the reference to an `i32` it contains.
155
156 ## `impl` blocks
157
158 Let’s implement a method on `Foo`:
159
160 ```rust
161 struct Foo<'a> {
162     x: &'a i32,
163 }
164
165 impl<'a> Foo<'a> {
166     fn x(&self) -> &'a i32 { self.x }
167 }
168
169 fn main() {
170     let y = &5; // this is the same as `let _y = 5; let y = &_y;`
171     let f = Foo { x: y };
172
173     println!("x is: {}", f.x());
174 }
175 ```
176
177 As you can see, we need to declare a lifetime for `Foo` in the `impl` line. We repeat
178 `'a` twice, like on functions: `impl<'a>` defines a lifetime `'a`, and `Foo<'a>`
179 uses it.
180
181 ## Multiple lifetimes
182
183 If you have multiple references, you can use the same lifetime multiple times:
184
185 ```rust
186 fn x_or_y<'a>(x: &'a str, y: &'a str) -> &'a str {
187 #    x
188 # }
189 ```
190
191 This says that `x` and `y` both are alive for the same scope, and that the
192 return value is also alive for that scope. If you wanted `x` and `y` to have
193 different lifetimes, you can use multiple lifetime parameters:
194
195 ```rust
196 fn x_or_y<'a, 'b>(x: &'a str, y: &'b str) -> &'a str {
197 #    x
198 # }
199 ```
200
201 In this example, `x` and `y` have different valid scopes, but the return value
202 has the same lifetime as `x`.
203
204 ## Thinking in scopes
205
206 A way to think about lifetimes is to visualize the scope that a reference is
207 valid for. For example:
208
209 ```rust
210 fn main() {
211     let y = &5;     // -+ y goes into scope
212                     //  |
213     // stuff        //  |
214                     //  |
215 }                   // -+ y goes out of scope
216 ```
217
218 Adding in our `Foo`:
219
220 ```rust
221 struct Foo<'a> {
222     x: &'a i32,
223 }
224
225 fn main() {
226     let y = &5;           // -+ y goes into scope
227     let f = Foo { x: y }; // -+ f goes into scope
228     // stuff              //  |
229                           //  |
230 }                         // -+ f and y go out of scope
231 ```
232
233 Our `f` lives within the scope of `y`, so everything works. What if it didn’t?
234 This code won’t work:
235
236 ```rust,ignore
237 struct Foo<'a> {
238     x: &'a i32,
239 }
240
241 fn main() {
242     let x;                    // -+ x goes into scope
243                               //  |
244     {                         //  |
245         let y = &5;           // ---+ y goes into scope
246         let f = Foo { x: y }; // ---+ f goes into scope
247         x = &f.x;             //  | | error here
248     }                         // ---+ f and y go out of scope
249                               //  |
250     println!("{}", x);        //  |
251 }                             // -+ x goes out of scope
252 ```
253
254 Whew! As you can see here, the scopes of `f` and `y` are smaller than the scope
255 of `x`. But when we do `x = &f.x`, we make `x` a reference to something that’s
256 about to go out of scope.
257
258 Named lifetimes are a way of giving these scopes a name. Giving something a
259 name is the first step towards being able to talk about it.
260
261 ## 'static
262
263 The lifetime named ‘static’ is a special lifetime. It signals that something
264 has the lifetime of the entire program. Most Rust programmers first come across
265 `'static` when dealing with strings:
266
267 ```rust
268 let x: &'static str = "Hello, world.";
269 ```
270
271 String literals have the type `&'static str` because the reference is always
272 alive: they are baked into the data segment of the final binary. Another
273 example are globals:
274
275 ```rust
276 static FOO: i32 = 5;
277 let x: &'static i32 = &FOO;
278 ```
279
280 This adds an `i32` to the data segment of the binary, and `x` is a reference
281 to it.
282
283 ## Lifetime Elision
284
285 Rust supports powerful local type inference in function bodies, but it’s
286 forbidden in item signatures to allow reasoning about the types based on
287 the item signature alone. However, for ergonomic reasons a very restricted
288 secondary inference algorithm called “lifetime elision” applies in function
289 signatures. It infers only based on the signature components themselves and not
290 based on the body of the function, only infers lifetime parameters, and does
291 this with only three easily memorizable and unambiguous rules. This makes
292 lifetime elision a shorthand for writing an item signature, while not hiding
293 away the actual types involved as full local inference would if applied to it.
294
295 When talking about lifetime elision, we use the term *input lifetime* and
296 *output lifetime*. An *input lifetime* is a lifetime associated with a parameter
297 of a function, and an *output lifetime* is a lifetime associated with the return
298 value of a function. For example, this function has an input lifetime:
299
300 ```rust,ignore
301 fn foo<'a>(bar: &'a str)
302 ```
303
304 This one has an output lifetime:
305
306 ```rust,ignore
307 fn foo<'a>() -> &'a str
308 ```
309
310 This one has a lifetime in both positions:
311
312 ```rust,ignore
313 fn foo<'a>(bar: &'a str) -> &'a str
314 ```
315
316 Here are the three rules:
317
318 * Each elided lifetime in a function’s arguments becomes a distinct lifetime
319   parameter.
320
321 * If there is exactly one input lifetime, elided or not, that lifetime is
322   assigned to all elided lifetimes in the return values of that function.
323
324 * If there are multiple input lifetimes, but one of them is `&self` or `&mut
325   self`, the lifetime of `self` is assigned to all elided output lifetimes.
326
327 Otherwise, it is an error to elide an output lifetime.
328
329 ### Examples
330
331 Here are some examples of functions with elided lifetimes.  We’ve paired each
332 example of an elided lifetime with its expanded form.
333
334 ```rust,ignore
335 fn print(s: &str); // elided
336 fn print<'a>(s: &'a str); // expanded
337
338 fn debug(lvl: u32, s: &str); // elided
339 fn debug<'a>(lvl: u32, s: &'a str); // expanded
340
341 // In the preceding example, `lvl` doesn’t need a lifetime because it’s not a
342 // reference (`&`). Only things relating to references (such as a `struct`
343 // which contains a reference) need lifetimes.
344
345 fn substr(s: &str, until: u32) -> &str; // elided
346 fn substr<'a>(s: &'a str, until: u32) -> &'a str; // expanded
347
348 fn get_str() -> &str; // ILLEGAL, no inputs
349
350 fn frob(s: &str, t: &str) -> &str; // ILLEGAL, two inputs
351 fn frob<'a, 'b>(s: &'a str, t: &'b str) -> &str; // Expanded: Output lifetime is ambiguous
352
353 fn get_mut(&mut self) -> &mut T; // elided
354 fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded
355
356 fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command; // elided
357 fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command; // expanded
358
359 fn new(buf: &mut [u8]) -> BufWriter; // elided
360 fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a>; // expanded
361 ```