Skip to content

Commit 483656b

Browse files
Add E0492 error explanation
1 parent 1904b33 commit 483656b

File tree

1 file changed

+79
-19
lines changed

1 file changed

+79
-19
lines changed

src/librustc/diagnostics.rs

+79-19
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,85 @@ contain references (with a maximum lifetime of `'a`).
18991899
[1]: https://github.com/rust-lang/rfcs/pull/1156
19001900
"##,
19011901

1902+
E0492: r##"
1903+
A borrow of a constant containing interior mutability was attempted. Erroneous
1904+
code example:
1905+
1906+
```
1907+
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
1908+
1909+
const A: AtomicUsize = ATOMIC_USIZE_INIT;
1910+
static B: &'static AtomicUsize = &A;
1911+
// error: cannot borrow a constant which contains interior mutability, create a
1912+
// static instead
1913+
```
1914+
1915+
A `const` represents a constant value that should never change. If one takes
1916+
a `&` reference to the constant, then one is taking a pointer to some memory
1917+
location containing the value. Normally this is perfectly fine: most values
1918+
can't be changed via a shared `&` pointer, but interior mutability would allow
1919+
it. That is, a constant value could be mutated. On the other hand, a `static` is
1920+
explicitly a single memory location, which can be mutated at will.
1921+
1922+
So, in order to solve this error, either use statics which are `Sync`:
1923+
1924+
```
1925+
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
1926+
1927+
static A: AtomicUsize = ATOMIC_USIZE_INIT;
1928+
static B: &'static AtomicUsize = &A; // ok!
1929+
```
1930+
1931+
You can also have this error while using a cell type:
1932+
1933+
```
1934+
#![feature(const_fn)]
1935+
1936+
use std::cell::Cell;
1937+
1938+
const A: Cell<usize> = Cell::new(1);
1939+
const B: &'static Cell<usize> = &A;
1940+
// error: cannot borrow a constant which contains interior mutability, create
1941+
// a static instead
1942+
1943+
// or:
1944+
struct C { a: Cell<usize> }
1945+
1946+
const D: C = C { a: Cell::new(1) };
1947+
const E: &'static Cell<usize> = &D.a; // error
1948+
1949+
// or:
1950+
const F: &'static C = &D; // error
1951+
```
1952+
1953+
This is because cell types internally use `UnsafeCell`, which isn't `Sync`.
1954+
These aren't thread safe, and thus can't be placed in statics. In this case,
1955+
`StaticMutex` would work just fine, but it isn't stable yet:
1956+
https://doc.rust-lang.org/nightly/std/sync/struct.StaticMutex.html
1957+
1958+
However, if you still wish to use these types, you can achieve this by an unsafe
1959+
wrapper:
1960+
1961+
```
1962+
#![feature(const_fn)]
1963+
1964+
use std::cell::Cell;
1965+
use std::marker::Sync;
1966+
1967+
struct NotThreadSafe<T> {
1968+
value: Cell<T>,
1969+
}
1970+
1971+
unsafe impl<T> Sync for NotThreadSafe<T> {}
1972+
1973+
static A: NotThreadSafe<usize> = NotThreadSafe { value : Cell::new(1) };
1974+
static B: &'static NotThreadSafe<usize> = &A; // ok!
1975+
```
1976+
1977+
Remember this solution is unsafe! You will have to ensure that accesses to the
1978+
cell are synchronized.
1979+
"##,
1980+
19021981
E0493: r##"
19031982
A type with a destructor was assigned to an invalid type of variable. Erroneous
19041983
code example:
@@ -1967,7 +2046,6 @@ impl<'a> Foo<'a> {
19672046
19682047
Please change the name of one of the lifetimes to remove this error. Example:
19692048
1970-
19712049
```
19722050
struct Foo<'a> {
19732051
a: &'a i32,
@@ -1997,22 +2075,6 @@ It is not possible to use stability attributes outside of the standard library.
19972075
Also, for now, it is not possible to write deprecation messages either.
19982076
"##,
19992077

2000-
E0498: r##"
2001-
A plugin attribute was incorrectly used. Erroneous code example:
2002-
2003-
```
2004-
#![feature(plugin)]
2005-
#![plugin="foo")] // error: malformed plugin attribute
2006-
```
2007-
2008-
The plugin name must be written without quotes and within parenthesis. Example:
2009-
2010-
```
2011-
#![feature(plugin)]
2012-
#![plugin(foo)] // ok!
2013-
```
2014-
"##,
2015-
20162078
E0517: r##"
20172079
This error indicates that a `#[repr(..)]` attribute was placed on an unsupported
20182080
item.
@@ -2137,7 +2199,5 @@ register_diagnostics! {
21372199
E0489, // type/lifetime parameter not in scope here
21382200
E0490, // a value of type `..` is borrowed for too long
21392201
E0491, // in type `..`, reference has a longer lifetime than the data it...
2140-
E0492, // cannot borrow a constant which contains interior mutability
21412202
E0495, // cannot infer an appropriate lifetime due to conflicting requirements
2142-
E0514, // metadata version mismatch
21432203
}

0 commit comments

Comments
 (0)