]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/diagnostics.rs
Fix invalid associated type rendering in rustdoc
[rust.git] / src / librustc_mir / diagnostics.rs
1 // Copyright 2015 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 E0010: r##"
16 The value of statics and constants must be known at compile time, and they live
17 for the entire lifetime of a program. Creating a boxed value allocates memory on
18 the heap at runtime, and therefore cannot be done at compile time. Erroneous
19 code example:
20
21 ```compile_fail,E0010
22 #![feature(box_syntax)]
23
24 const CON : Box<i32> = box 0;
25 ```
26 "##,
27
28 E0013: r##"
29 Static and const variables can refer to other const variables. But a const
30 variable cannot refer to a static variable. For example, `Y` cannot refer to
31 `X` here:
32
33 ```compile_fail,E0013
34 static X: i32 = 42;
35 const Y: i32 = X;
36 ```
37
38 To fix this, the value can be extracted as a const and then used:
39
40 ```
41 const A: i32 = 42;
42 static X: i32 = A;
43 const Y: i32 = A;
44 ```
45 "##,
46
47 // FIXME(#24111) Change the language here when const fn stabilizes
48 E0015: r##"
49 The only functions that can be called in static or constant expressions are
50 `const` functions, and struct/enum constructors. `const` functions are only
51 available on a nightly compiler. Rust currently does not support more general
52 compile-time function execution.
53
54 ```
55 const FOO: Option<u8> = Some(1); // enum constructor
56 struct Bar {x: u8}
57 const BAR: Bar = Bar {x: 1}; // struct constructor
58 ```
59
60 See [RFC 911] for more details on the design of `const fn`s.
61
62 [RFC 911]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md
63 "##,
64
65 E0016: r##"
66 Blocks in constants may only contain items (such as constant, function
67 definition, etc...) and a tail expression. Erroneous code example:
68
69 ```compile_fail,E0016
70 const FOO: i32 = { let x = 0; x }; // 'x' isn't an item!
71 ```
72
73 To avoid it, you have to replace the non-item object:
74
75 ```
76 const FOO: i32 = { const X : i32 = 0; X };
77 ```
78 "##,
79
80 E0017: r##"
81 References in statics and constants may only refer to immutable values.
82 Erroneous code example:
83
84 ```compile_fail,E0017
85 static X: i32 = 1;
86 const C: i32 = 2;
87
88 // these three are not allowed:
89 const CR: &'static mut i32 = &mut C;
90 static STATIC_REF: &'static mut i32 = &mut X;
91 static CONST_REF: &'static mut i32 = &mut C;
92 ```
93
94 Statics are shared everywhere, and if they refer to mutable data one might
95 violate memory safety since holding multiple mutable references to shared data
96 is not allowed.
97
98 If you really want global mutable state, try using `static mut` or a global
99 `UnsafeCell`.
100 "##,
101
102 E0018: r##"
103
104 The value of static and constant integers must be known at compile time. You
105 can't cast a pointer to an integer because the address of a pointer can
106 vary.
107
108 For example, if you write:
109
110 ```compile_fail,E0018
111 static MY_STATIC: u32 = 42;
112 static MY_STATIC_ADDR: usize = &MY_STATIC as *const _ as usize;
113 static WHAT: usize = (MY_STATIC_ADDR^17) + MY_STATIC_ADDR;
114 ```
115
116 Then `MY_STATIC_ADDR` would contain the address of `MY_STATIC`. However,
117 the address can change when the program is linked, as well as change
118 between different executions due to ASLR, and many linkers would
119 not be able to calculate the value of `WHAT`.
120
121 On the other hand, static and constant pointers can point either to
122 a known numeric address or to the address of a symbol.
123
124 ```
125 static MY_STATIC_ADDR: &'static u32 = &MY_STATIC;
126 // ... and also
127 static MY_STATIC_ADDR2: *const u32 = &MY_STATIC;
128
129 const CONST_ADDR: *const u8 = 0x5f3759df as *const u8;
130 ```
131
132 This does not pose a problem by itself because they can't be
133 accessed directly.
134 "##,
135
136 E0019: r##"
137 A function call isn't allowed in the const's initialization expression
138 because the expression's value must be known at compile-time. Erroneous code
139 example:
140
141 ```compile_fail
142 enum Test {
143     V1
144 }
145
146 impl Test {
147     fn test(&self) -> i32 {
148         12
149     }
150 }
151
152 fn main() {
153     const FOO: Test = Test::V1;
154
155     const A: i32 = FOO.test(); // You can't call Test::func() here!
156 }
157 ```
158
159 Remember: you can't use a function call inside a const's initialization
160 expression! However, you can totally use it anywhere else:
161
162 ```
163 fn main() {
164     const FOO: Test = Test::V1;
165
166     FOO.func(); // here is good
167     let x = FOO.func(); // or even here!
168 }
169 ```
170 "##,
171
172 E0022: r##"
173 Constant functions are not allowed to mutate anything. Thus, binding to an
174 argument with a mutable pattern is not allowed. For example,
175
176 ```compile_fail
177 const fn foo(mut x: u8) {
178     // do stuff
179 }
180 ```
181
182 Is incorrect because the function body may not mutate `x`.
183
184 Remove any mutable bindings from the argument list to fix this error. In case
185 you need to mutate the argument, try lazily initializing a global variable
186 instead of using a `const fn`, or refactoring the code to a functional style to
187 avoid mutation if possible.
188 "##,
189
190 E0394: r##"
191 A static was referred to by value by another static.
192
193 Erroneous code examples:
194
195 ```compile_fail,E0394
196 static A: u32 = 0;
197 static B: u32 = A; // error: cannot refer to other statics by value, use the
198                    //        address-of operator or a constant instead
199 ```
200
201 A static cannot be referred by value. To fix this issue, either use a
202 constant:
203
204 ```
205 const A: u32 = 0; // `A` is now a constant
206 static B: u32 = A; // ok!
207 ```
208
209 Or refer to `A` by reference:
210
211 ```
212 static A: u32 = 0;
213 static B: &'static u32 = &A; // ok!
214 ```
215 "##,
216
217 E0395: r##"
218 The value assigned to a constant scalar must be known at compile time,
219 which is not the case when comparing raw pointers.
220
221 Erroneous code example:
222
223 ```compile_fail,E0395
224 static FOO: i32 = 42;
225 static BAR: i32 = 42;
226
227 static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) };
228 // error: raw pointers cannot be compared in statics!
229 ```
230
231 The address assigned by the linker to `FOO` and `BAR` may or may not
232 be identical, so the value of `BAZ` can't be determined.
233
234 If you want to do the comparison, please do it at run-time.
235
236 For example:
237
238 ```
239 static FOO: i32 = 42;
240 static BAR: i32 = 42;
241
242 let baz: bool = { (&FOO as *const i32) == (&BAR as *const i32) };
243 // baz isn't a constant expression so it's ok
244 ```
245 "##,
246
247 E0396: r##"
248 The value behind a raw pointer can't be determined at compile-time
249 (or even link-time), which means it can't be used in a constant
250 expression. Erroneous code example:
251
252 ```compile_fail,E0396
253 const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
254
255 const VALUE: u8 = unsafe { *REG_ADDR };
256 // error: raw pointers cannot be dereferenced in constants
257 ```
258
259 A possible fix is to dereference your pointer at some point in run-time.
260
261 For example:
262
263 ```
264 const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
265
266 let reg_value = unsafe { *REG_ADDR };
267 ```
268 "##,
269
270 E0492: r##"
271 A borrow of a constant containing interior mutability was attempted. Erroneous
272 code example:
273
274 ```compile_fail,E0492
275 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
276
277 const A: AtomicUsize = ATOMIC_USIZE_INIT;
278 static B: &'static AtomicUsize = &A;
279 // error: cannot borrow a constant which contains interior mutability, create a
280 //        static instead
281 ```
282
283 A `const` represents a constant value that should never change. If one takes
284 a `&` reference to the constant, then one is taking a pointer to some memory
285 location containing the value. Normally this is perfectly fine: most values
286 can't be changed via a shared `&` pointer, but interior mutability would allow
287 it. That is, a constant value could be mutated. On the other hand, a `static` is
288 explicitly a single memory location, which can be mutated at will.
289
290 So, in order to solve this error, either use statics which are `Sync`:
291
292 ```
293 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
294
295 static A: AtomicUsize = ATOMIC_USIZE_INIT;
296 static B: &'static AtomicUsize = &A; // ok!
297 ```
298
299 You can also have this error while using a cell type:
300
301 ```compile_fail,E0492
302 #![feature(const_fn)]
303
304 use std::cell::Cell;
305
306 const A: Cell<usize> = Cell::new(1);
307 const B: &'static Cell<usize> = &A;
308 // error: cannot borrow a constant which contains interior mutability, create
309 //        a static instead
310
311 // or:
312 struct C { a: Cell<usize> }
313
314 const D: C = C { a: Cell::new(1) };
315 const E: &'static Cell<usize> = &D.a; // error
316
317 // or:
318 const F: &'static C = &D; // error
319 ```
320
321 This is because cell types do operations that are not thread-safe. Due to this,
322 they don't implement Sync and thus can't be placed in statics. In this
323 case, `StaticMutex` would work just fine, but it isn't stable yet:
324 https://doc.rust-lang.org/nightly/std/sync/struct.StaticMutex.html
325
326 However, if you still wish to use these types, you can achieve this by an unsafe
327 wrapper:
328
329 ```
330 #![feature(const_fn)]
331
332 use std::cell::Cell;
333 use std::marker::Sync;
334
335 struct NotThreadSafe<T> {
336     value: Cell<T>,
337 }
338
339 unsafe impl<T> Sync for NotThreadSafe<T> {}
340
341 static A: NotThreadSafe<usize> = NotThreadSafe { value : Cell::new(1) };
342 static B: &'static NotThreadSafe<usize> = &A; // ok!
343 ```
344
345 Remember this solution is unsafe! You will have to ensure that accesses to the
346 cell are synchronized.
347 "##,
348
349 E0493: r##"
350 A type with a destructor was assigned to an invalid type of variable. Erroneous
351 code example:
352
353 ```compile_fail,E0493
354 struct Foo {
355     a: u32
356 }
357
358 impl Drop for Foo {
359     fn drop(&mut self) {}
360 }
361
362 const F : Foo = Foo { a : 0 };
363 // error: constants are not allowed to have destructors
364 static S : Foo = Foo { a : 0 };
365 // error: destructors in statics are an unstable feature
366 ```
367
368 To solve this issue, please use a type which does allow the usage of type with
369 destructors.
370 "##,
371
372 E0494: r##"
373 A reference of an interior static was assigned to another const/static.
374 Erroneous code example:
375
376 ```compile_fail,E0494
377 struct Foo {
378     a: u32
379 }
380
381 static S : Foo = Foo { a : 0 };
382 static A : &'static u32 = &S.a;
383 // error: cannot refer to the interior of another static, use a
384 //        constant instead
385 ```
386
387 The "base" variable has to be a const if you want another static/const variable
388 to refer to one of its fields. Example:
389
390 ```
391 struct Foo {
392     a: u32
393 }
394
395 const S : Foo = Foo { a : 0 };
396 static A : &'static u32 = &S.a; // ok!
397 ```
398 "##,
399
400 }
401
402 register_diagnostics! {
403     E0526, // shuffle indices are not constant
404 }