about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-11-29 22:54:43 +0000
committerbors <bors@rust-lang.org>2015-11-29 22:54:43 +0000
commitb22d7a5d2f2aba0ff1623ca85bbd6e1f94a95ed3 (patch)
treeb6fd9474ab8682e676a5a7dd652ceb32c6d20df4 /src
parent15ad1d199b24b74cd07fb42b2b101a585aff16cc (diff)
parent483656b606f81f0163b04fd05088813639b7f024 (diff)
downloadrust-b22d7a5d2f2aba0ff1623ca85bbd6e1f94a95ed3.tar.gz
rust-b22d7a5d2f2aba0ff1623ca85bbd6e1f94a95ed3.zip
Auto merge of #29976 - GuillaumeGomez:patch-5, r=Manishearth
r? @Manishearth
Diffstat (limited to 'src')
-rw-r--r--src/librustc/diagnostics.rs82
1 files changed, 80 insertions, 2 deletions
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index b4e188c498d..bdfdc7f4786 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -1899,6 +1899,85 @@ contain references (with a maximum lifetime of `'a`).
 [1]: https://github.com/rust-lang/rfcs/pull/1156
 "##,
 
+E0492: r##"
+A borrow of a constant containing interior mutability was attempted. Erroneous
+code example:
+
+```
+use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
+
+const A: AtomicUsize = ATOMIC_USIZE_INIT;
+static B: &'static AtomicUsize = &A;
+// error: cannot borrow a constant which contains interior mutability, create a
+//        static instead
+```
+
+A `const` represents a constant value that should never change. If one takes
+a `&` reference to the constant, then one is taking a pointer to some memory
+location containing the value. Normally this is perfectly fine: most values
+can't be changed via a shared `&` pointer, but interior mutability would allow
+it. That is, a constant value could be mutated. On the other hand, a `static` is
+explicitly a single memory location, which can be mutated at will.
+
+So, in order to solve this error, either use statics which are `Sync`:
+
+```
+use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
+
+static A: AtomicUsize = ATOMIC_USIZE_INIT;
+static B: &'static AtomicUsize = &A; // ok!
+```
+
+You can also have this error while using a cell type:
+
+```
+#![feature(const_fn)]
+
+use std::cell::Cell;
+
+const A: Cell<usize> = Cell::new(1);
+const B: &'static Cell<usize> = &A;
+// error: cannot borrow a constant which contains interior mutability, create
+//        a static instead
+
+// or:
+struct C { a: Cell<usize> }
+
+const D: C = C { a: Cell::new(1) };
+const E: &'static Cell<usize> = &D.a; // error
+
+// or:
+const F: &'static C = &D; // error
+```
+
+This is because cell types internally use `UnsafeCell`, which isn't `Sync`.
+These aren't thread safe, and thus can't be placed in statics. In this case,
+`StaticMutex` would work just fine, but it isn't stable yet:
+https://doc.rust-lang.org/nightly/std/sync/struct.StaticMutex.html
+
+However, if you still wish to use these types, you can achieve this by an unsafe
+wrapper:
+
+```
+#![feature(const_fn)]
+
+use std::cell::Cell;
+use std::marker::Sync;
+
+struct NotThreadSafe<T> {
+    value: Cell<T>,
+}
+
+unsafe impl<T> Sync for NotThreadSafe<T> {}
+
+static A: NotThreadSafe<usize> = NotThreadSafe { value : Cell::new(1) };
+static B: &'static NotThreadSafe<usize> = &A; // ok!
+```
+
+Remember this solution is unsafe! You will have to ensure that accesses to the
+cell are synchronized.
+"##,
+
 E0493: r##"
 A type with a destructor was assigned to an invalid type of variable. Erroneous
 code example:
@@ -1967,7 +2046,6 @@ impl<'a> Foo<'a> {
 
 Please change the name of one of the lifetimes to remove this error. Example:
 
-
 ```
 struct Foo<'a> {
     a: &'a i32,
@@ -2070,6 +2148,7 @@ If you wish to apply this attribute to all methods in an impl, manually annotate
 each method; it is not possible to annotate the entire impl with an `#[inline]`
 attribute.
 "##,
+
 }
 
 
@@ -2120,6 +2199,5 @@ register_diagnostics! {
     E0489, // type/lifetime parameter not in scope here
     E0490, // a value of type `..` is borrowed for too long
     E0491, // in type `..`, reference has a longer lifetime than the data it...
-    E0492, // cannot borrow a constant which contains interior mutability
     E0495, // cannot infer an appropriate lifetime due to conflicting requirements
 }