]> git.proxmox.com Git - rustc.git/blame - src/librustc_error_codes/error_codes/E0492.md
New upstream version 1.47.0+dfsg1
[rustc.git] / src / librustc_error_codes / error_codes / E0492.md
CommitLineData
60c5eb7d
XL
1A borrow of a constant containing interior mutability was attempted.
2
3Erroneous code example:
4
5```compile_fail,E0492
6use std::sync::atomic::AtomicUsize;
7
8const A: AtomicUsize = AtomicUsize::new(0);
9static B: &'static AtomicUsize = &A;
10// error: cannot borrow a constant which may contain interior mutability,
11// create a static instead
12```
13
14A `const` represents a constant value that should never change. If one takes
15a `&` reference to the constant, then one is taking a pointer to some memory
16location containing the value. Normally this is perfectly fine: most values
17can't be changed via a shared `&` pointer, but interior mutability would allow
18it. That is, a constant value could be mutated. On the other hand, a `static` is
19explicitly a single memory location, which can be mutated at will.
20
21So, in order to solve this error, either use statics which are `Sync`:
22
23```
24use std::sync::atomic::AtomicUsize;
25
26static A: AtomicUsize = AtomicUsize::new(0);
27static B: &'static AtomicUsize = &A; // ok!
28```
29
30You can also have this error while using a cell type:
31
32```compile_fail,E0492
33use std::cell::Cell;
34
35const A: Cell<usize> = Cell::new(1);
36const B: &Cell<usize> = &A;
37// error: cannot borrow a constant which may contain interior mutability,
38// create a static instead
39
40// or:
41struct C { a: Cell<usize> }
42
43const D: C = C { a: Cell::new(1) };
44const E: &Cell<usize> = &D.a; // error
45
46// or:
47const F: &C = &D; // error
48```
49
50This is because cell types do operations that are not thread-safe. Due to this,
51they don't implement Sync and thus can't be placed in statics.
52
53However, if you still wish to use these types, you can achieve this by an unsafe
54wrapper:
55
56```
57use std::cell::Cell;
58use std::marker::Sync;
59
60struct NotThreadSafe<T> {
61 value: Cell<T>,
62}
63
64unsafe impl<T> Sync for NotThreadSafe<T> {}
65
66static A: NotThreadSafe<usize> = NotThreadSafe { value : Cell::new(1) };
67static B: &'static NotThreadSafe<usize> = &A; // ok!
68```
69
70Remember this solution is unsafe! You will have to ensure that accesses to the
71cell are synchronized.