]> git.proxmox.com Git - rustc.git/blob - src/librustc_borrowck/diagnostics.rs
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / librustc_borrowck / diagnostics.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![allow(non_snake_case)]
12
13 register_long_diagnostics! {
14
15 E0373: r##"
16 This error occurs when an attempt is made to use data captured by a closure,
17 when that data may no longer exist. It's most commonly seen when attempting to
18 return a closure:
19
20 ```
21 fn foo() -> Box<Fn(u32) -> u32> {
22 let x = 0u32;
23 Box::new(|y| x + y)
24 }
25 ```
26
27 Notice that `x` is stack-allocated by `foo()`. By default, Rust captures
28 closed-over data by reference. This means that once `foo()` returns, `x` no
29 longer exists. An attempt to access `x` within the closure would thus be unsafe.
30
31 Another situation where this might be encountered is when spawning threads:
32
33 ```
34 fn foo() {
35 let x = 0u32;
36 let y = 1u32;
37
38 let thr = std::thread::spawn(|| {
39 x + y
40 });
41 }
42 ```
43
44 Since our new thread runs in parallel, the stack frame containing `x` and `y`
45 may well have disappeared by the time we try to use them. Even if we call
46 `thr.join()` within foo (which blocks until `thr` has completed, ensuring the
47 stack frame won't disappear), we will not succeed: the compiler cannot prove
48 that this behaviour is safe, and so won't let us do it.
49
50 The solution to this problem is usually to switch to using a `move` closure.
51 This approach moves (or copies, where possible) data into the closure, rather
52 than taking references to it. For example:
53
54 ```
55 fn foo() -> Box<Fn(u32) -> u32> {
56 let x = 0u32;
57 Box::new(move |y| x + y)
58 }
59 ```
60
61 Now that the closure has its own copy of the data, there's no need to worry
62 about safety.
63 "##,
64
65 E0381: r##"
66 It is not allowed to use or capture an uninitialized variable. For example:
67
68 ```
69 fn main() {
70 let x: i32;
71 let y = x; // error, use of possibly uninitialized variable
72 ```
73
74 To fix this, ensure that any declared variables are initialized before being
75 used.
76 "##,
77
78 E0384: r##"
79 This error occurs when an attempt is made to reassign an immutable variable.
80 For example:
81
82 ```
83 fn main(){
84 let x = 3;
85 x = 5; // error, reassignment of immutable variable
86 }
87 ```
88
89 By default, variables in Rust are immutable. To fix this error, add the keyword
90 `mut` after the keyword `let` when declaring the variable. For example:
91
92 ```
93 fn main(){
94 let mut x = 3;
95 x = 5;
96 }
97 ```
98 "##
99
100 }
101
102 register_diagnostics! {
103 E0382, // use of partially/collaterally moved value
104 E0383, // partial reinitialization of uninitialized structure
105 E0385, // {} in an aliasable location
106 E0386, // {} in an immutable container
107 E0387, // {} in a captured outer variable in an `Fn` closure
108 E0388, // {} in a static location
109 E0389 // {} in a `&` reference
110 }