]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_error_codes/src/error_codes/E0504.md
New upstream version 1.49.0+dfsg1
[rustc.git] / compiler / rustc_error_codes / src / error_codes / E0504.md
1 #### Note: this error code is no longer emitted by the compiler.
2
3 This error occurs when an attempt is made to move a borrowed variable into a
4 closure.
5
6 Erroneous code example:
7
8 ```compile_fail
9 struct FancyNum {
10 num: u8,
11 }
12
13 fn main() {
14 let fancy_num = FancyNum { num: 5 };
15 let fancy_ref = &fancy_num;
16
17 let x = move || {
18 println!("child function: {}", fancy_num.num);
19 // error: cannot move `fancy_num` into closure because it is borrowed
20 };
21
22 x();
23 println!("main function: {}", fancy_ref.num);
24 }
25 ```
26
27 Here, `fancy_num` is borrowed by `fancy_ref` and so cannot be moved into
28 the closure `x`. There is no way to move a value into a closure while it is
29 borrowed, as that would invalidate the borrow.
30
31 If the closure can't outlive the value being moved, try using a reference
32 rather than moving:
33
34 ```
35 struct FancyNum {
36 num: u8,
37 }
38
39 fn main() {
40 let fancy_num = FancyNum { num: 5 };
41 let fancy_ref = &fancy_num;
42
43 let x = move || {
44 // fancy_ref is usable here because it doesn't move `fancy_num`
45 println!("child function: {}", fancy_ref.num);
46 };
47
48 x();
49
50 println!("main function: {}", fancy_num.num);
51 }
52 ```
53
54 If the value has to be borrowed and then moved, try limiting the lifetime of
55 the borrow using a scoped block:
56
57 ```
58 struct FancyNum {
59 num: u8,
60 }
61
62 fn main() {
63 let fancy_num = FancyNum { num: 5 };
64
65 {
66 let fancy_ref = &fancy_num;
67 println!("main function: {}", fancy_ref.num);
68 // `fancy_ref` goes out of scope here
69 }
70
71 let x = move || {
72 // `fancy_num` can be moved now (no more references exist)
73 println!("child function: {}", fancy_num.num);
74 };
75
76 x();
77 }
78 ```
79
80 If the lifetime of a reference isn't enough, such as in the case of threading,
81 consider using an `Arc` to create a reference-counted value:
82
83 ```
84 use std::sync::Arc;
85 use std::thread;
86
87 struct FancyNum {
88 num: u8,
89 }
90
91 fn main() {
92 let fancy_ref1 = Arc::new(FancyNum { num: 5 });
93 let fancy_ref2 = fancy_ref1.clone();
94
95 let x = thread::spawn(move || {
96 // `fancy_ref1` can be moved and has a `'static` lifetime
97 println!("child thread: {}", fancy_ref1.num);
98 });
99
100 x.join().expect("child thread should finish");
101 println!("main thread: {}", fancy_ref2.num);
102 }
103 ```