@@ -1203,21 +1203,42 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> {
1203
1203
/// The `UnsafeCell<T>` type is the only legal way to obtain aliasable data that is considered
1204
1204
/// mutable. In general, transmuting an `&T` type into an `&mut T` is considered undefined behavior.
1205
1205
///
1206
- /// The compiler makes optimizations based on the knowledge that `&T` is not mutably aliased or
1207
- /// mutated, and that `&mut T` is unique. When building abstractions like `Cell`, `RefCell`,
1208
- /// `Mutex`, etc, you need to turn these optimizations off. `UnsafeCell` is the only legal way
1209
- /// to do this. When `UnsafeCell<T>` is immutably aliased, it is still safe to obtain a mutable
1210
- /// reference to its interior and/or to mutate it. However, it is up to the abstraction designer
1211
- /// to ensure that no two mutable references obtained this way are active at the same time, and
1212
- /// that there are no active mutable references or mutations when an immutable reference is obtained
1213
- /// from the cell. This is often done via runtime checks.
1206
+ /// If you have a reference `&SomeStruct`, then normally in Rust all fields of `SomeStruct` are
1207
+ /// immutable. The compiler makes optimizations based on the knowledge that `&T` is not mutably
1208
+ /// aliased or mutated, and that `&mut T` is unique. `UnsafeCel<T>` is the only core language
1209
+ /// feature to work around this restriction. All other types that allow internal mutability, such as
1210
+ /// `Cell<T>` and `RefCell<T>` use `UnsafeCell` to wrap their internal data.
1214
1211
///
1215
- /// Note that while mutating or mutably aliasing the contents of an `& UnsafeCell<T>` is
1216
- /// okay (provided you enforce the invariants some other way); it is still undefined behavior
1217
- /// to have multiple `&mut UnsafeCell<T>` aliases.
1212
+ /// The `UnsafeCell` API itself is technically very simple: it gives you a raw pointer `*mut T` to
1213
+ /// its contents. It is up to _you_ as the abstraction designer to use that raw pointer correctly.
1214
+ ///
1215
+ /// The precise Rust aliasing rules are somewhat in flux, but the main points are not contentious:
1216
+ ///
1217
+ /// - If you create a safe reference with lifetime `'a` (either a `&T` or `&mut T` reference) that
1218
+ /// is accessible by safe code (for example, because you returned it), then you must not access
1219
+ /// the data in any way that contradicts that reference for the remainder of `'a`. For example, that
1220
+ /// means that if you take the `*mut T` from an `UnsafeCell<T>` and case it to an `&T`, then until
1221
+ /// that reference's lifetime expires, the data in `T` must remain immutable (modulo any
1222
+ /// `UnsafeCell` data found within `T`, of course). Similarly, if you create an `&mut T` reference
1223
+ /// that is released to safe code, then you must not access the data within the `UnsafeCell` until
1224
+ /// that reference expires.
1225
+ ///
1226
+ /// - At all times, you must avoid data races, meaning that if multiple threads have access to
1227
+ /// the same `UnsafeCell`, then any writes must have a proper happens-before relation to all other
1228
+ /// accesses (or use atomics).
1218
1229
///
1230
+ /// To assist with proper design, the following scenarios are explicitly declared legal
1231
+ /// for single-threaded code:
1219
1232
///
1220
- /// Types like `Cell<T>` and `RefCell<T>` use this type to wrap their internal data.
1233
+ /// 1. A `&T` reference can be released to safe code and there it can co-exit with other `&T`
1234
+ /// references, but not with a `&mut T`
1235
+ ///
1236
+ /// 2. A `&mut T` reference may be released to safe code, provided neither other `&mut T` nor `&T`
1237
+ /// co-exist with it. A `&mut T` must always be unique.
1238
+ ///
1239
+ /// Note that while mutating or mutably aliasing the contents of an `& UnsafeCell<T>` is
1240
+ /// okay (provided you enforce the invariants some other way), it is still undefined behavior
1241
+ /// to have multiple `&mut UnsafeCell<T>` aliases.
1221
1242
///
1222
1243
/// # Examples
1223
1244
///
@@ -1282,9 +1303,9 @@ impl<T: ?Sized> UnsafeCell<T> {
1282
1303
/// Gets a mutable pointer to the wrapped value.
1283
1304
///
1284
1305
/// This can be cast to a pointer of any kind.
1285
- /// Ensure that the access is unique when casting to
1286
- /// `&mut T`, and ensure that there are no mutations or mutable
1287
- /// aliases going on when casting to `&T`
1306
+ /// Ensure that the access is unique (no active references, mutable or not)
1307
+ /// when casting to `&mut T`, and ensure that there are no mutations
1308
+ /// or mutable aliases going on when casting to `&T`
1288
1309
///
1289
1310
/// # Examples
1290
1311
///
0 commit comments