@@ -1899,6 +1899,85 @@ contain references (with a maximum lifetime of `'a`).
1899
1899
[1]: https://github.com/rust-lang/rfcs/pull/1156
1900
1900
"## ,
1901
1901
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
+
1902
1981
E0493 : r##"
1903
1982
A type with a destructor was assigned to an invalid type of variable. Erroneous
1904
1983
code example:
@@ -1967,7 +2046,6 @@ impl<'a> Foo<'a> {
1967
2046
1968
2047
Please change the name of one of the lifetimes to remove this error. Example:
1969
2048
1970
-
1971
2049
```
1972
2050
struct Foo<'a> {
1973
2051
a: &'a i32,
@@ -2070,6 +2148,7 @@ If you wish to apply this attribute to all methods in an impl, manually annotate
2070
2148
each method; it is not possible to annotate the entire impl with an `#[inline]`
2071
2149
attribute.
2072
2150
"## ,
2151
+
2073
2152
}
2074
2153
2075
2154
@@ -2120,6 +2199,5 @@ register_diagnostics! {
2120
2199
E0489 , // type/lifetime parameter not in scope here
2121
2200
E0490 , // a value of type `..` is borrowed for too long
2122
2201
E0491 , // in type `..`, reference has a longer lifetime than the data it...
2123
- E0492 , // cannot borrow a constant which contains interior mutability
2124
2202
E0495 , // cannot infer an appropriate lifetime due to conflicting requirements
2125
2203
}
0 commit comments