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