]> git.proxmox.com Git - rustc.git/blob - src/doc/nomicon/lifetime-mismatch.md
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / doc / nomicon / lifetime-mismatch.md
1 % Limits of Lifetimes
2
3 Given the following code:
4
5 ```rust,ignore
6 struct Foo;
7
8 impl Foo {
9 fn mutate_and_share(&mut self) -> &Self { &*self }
10 fn share(&self) {}
11 }
12
13 fn main() {
14 let mut foo = Foo;
15 let loan = foo.mutate_and_share();
16 foo.share();
17 }
18 ```
19
20 One might expect it to compile. We call `mutate_and_share`, which mutably borrows
21 `foo` temporarily, but then returns only a shared reference. Therefore we
22 would expect `foo.share()` to succeed as `foo` shouldn't be mutably borrowed.
23
24 However when we try to compile it:
25
26 ```text
27 <anon>:11:5: 11:8 error: cannot borrow `foo` as immutable because it is also borrowed as mutable
28 <anon>:11 foo.share();
29 ^~~
30 <anon>:10:16: 10:19 note: previous borrow of `foo` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `foo` until the borrow ends
31 <anon>:10 let loan = foo.mutate_and_share();
32 ^~~
33 <anon>:12:2: 12:2 note: previous borrow ends here
34 <anon>:8 fn main() {
35 <anon>:9 let mut foo = Foo;
36 <anon>:10 let loan = foo.mutate_and_share();
37 <anon>:11 foo.share();
38 <anon>:12 }
39 ^
40 ```
41
42 What happened? Well, we got the exact same reasoning as we did for
43 [Example 2 in the previous section][ex2]. We desugar the program and we get
44 the following:
45
46 ```rust,ignore
47 struct Foo;
48
49 impl Foo {
50 fn mutate_and_share<'a>(&'a mut self) -> &'a Self { &'a *self }
51 fn share<'a>(&'a self) {}
52 }
53
54 fn main() {
55 'b: {
56 let mut foo: Foo = Foo;
57 'c: {
58 let loan: &'c Foo = Foo::mutate_and_share::<'c>(&'c mut foo);
59 'd: {
60 Foo::share::<'d>(&'d foo);
61 }
62 }
63 }
64 }
65 ```
66
67 The lifetime system is forced to extend the `&mut foo` to have lifetime `'c`,
68 due to the lifetime of `loan` and mutate_and_share's signature. Then when we
69 try to call `share`, and it sees we're trying to alias that `&'c mut foo` and
70 blows up in our face!
71
72 This program is clearly correct according to the reference semantics we actually
73 care about, but the lifetime system is too coarse-grained to handle that.
74
75
76 TODO: other common problems? SEME regions stuff, mostly?
77
78
79
80
81 [ex2]: lifetimes.html#example-2:-aliasing-a-mutable-reference