]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_error_codes/src/error_codes/E0713.md
Rollup merge of #93556 - dtolnay:trailingcomma, r=cjgillot
[rust.git] / compiler / rustc_error_codes / src / error_codes / E0713.md
1 This error occurs when an attempt is made to borrow state past the end of the
2 lifetime of a type that implements the `Drop` trait.
3
4 Erroneous code example:
5
6 ```compile_fail,E0713
7 #![feature(nll)]
8
9 pub struct S<'a> { data: &'a mut String }
10
11 impl<'a> Drop for S<'a> {
12     fn drop(&mut self) { self.data.push_str("being dropped"); }
13 }
14
15 fn demo<'a>(s: S<'a>) -> &'a mut String { let p = &mut *s.data; p }
16 ```
17
18 Here, `demo` tries to borrow the string data held within its
19 argument `s` and then return that borrow. However, `S` is
20 declared as implementing `Drop`.
21
22 Structs implementing the `Drop` trait have an implicit destructor that
23 gets called when they go out of scope. This destructor gets exclusive
24 access to the fields of the struct when it runs.
25
26 This means that when `s` reaches the end of `demo`, its destructor
27 gets exclusive access to its `&mut`-borrowed string data.  allowing
28 another borrow of that string data (`p`), to exist across the drop of
29 `s` would be a violation of the principle that `&mut`-borrows have
30 exclusive, unaliased access to their referenced data.
31
32 This error can be fixed by changing `demo` so that the destructor does
33 not run while the string-data is borrowed; for example by taking `S`
34 by reference:
35
36 ```
37 pub struct S<'a> { data: &'a mut String }
38
39 impl<'a> Drop for S<'a> {
40     fn drop(&mut self) { self.data.push_str("being dropped"); }
41 }
42
43 fn demo<'a>(s: &'a mut S<'a>) -> &'a mut String { let p = &mut *(*s).data; p }
44 ```
45
46 Note that this approach needs a reference to S with lifetime `'a`.
47 Nothing shorter than `'a` will suffice: a shorter lifetime would imply
48 that after `demo` finishes executing, something else (such as the
49 destructor!) could access `s.data` after the end of that shorter
50 lifetime, which would again violate the `&mut`-borrow's exclusive
51 access.