@@ -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+
19021981E0493 : r##"
19031982A type with a destructor was assigned to an invalid type of variable. Erroneous
19041983code example:
@@ -1967,7 +2046,6 @@ impl<'a> Foo<'a> {
19672046
19682047Please change the name of one of the lifetimes to remove this error. Example:
19692048
1970-
19712049```
19722050struct Foo<'a> {
19732051 a: &'a i32,
@@ -2070,6 +2148,7 @@ If you wish to apply this attribute to all methods in an impl, manually annotate
20702148each method; it is not possible to annotate the entire impl with an `#[inline]`
20712149attribute.
20722150"## ,
2151+
20732152}
20742153
20752154
@@ -2120,6 +2199,5 @@ register_diagnostics! {
21202199 E0489 , // type/lifetime parameter not in scope here
21212200 E0490 , // a value of type `..` is borrowed for too long
21222201 E0491 , // in type `..`, reference has a longer lifetime than the data it...
2123- E0492 , // cannot borrow a constant which contains interior mutability
21242202 E0495 , // cannot infer an appropriate lifetime due to conflicting requirements
21252203}
0 commit comments