]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_error_codes/src/error_codes/E0504.md
Rollup merge of #93556 - dtolnay:trailingcomma, r=cjgillot
[rust.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 ```