Skip to content

Commit cf0516b

Browse files
committed
RFC3458: Document why field copies and moves require unsafe
See: - #3458 (comment) - #3458 (comment)
1 parent ed920e9 commit cf0516b

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

text/0000-unsafe-fields.md

+34
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,40 @@ variants are conceptually unsafe, requiring the programmer to use `unsafe` even
628628
of 'safe' fields. This violates [*Tenet: Safe Usage is Usually
629629
Safe*](#tenet-safe-usage-is-usually-safe).
630630

631+
### Field Moving is Safe
632+
633+
We propose that all uses of `unsafe` fields require `unsafe`, including reading. Alternatively, we
634+
might consider making reads safe. However, a field may carry an invariant that would be violated by
635+
a read. In the [*Complete Example*](#complete-example), `KeepAlive<T>::arc` is marked `unsafe`
636+
because it carries such an invariant:
637+
638+
```rust
639+
/// Keeps the parent [`UniqueArc`] alive without providing read or write access
640+
/// to its value.
641+
pub struct KeepAlive<T> {
642+
/// # Safety
643+
///
644+
/// `T` may not be accessed (read or written) via this `Arc`.
645+
unsafe arc: Arc<UnsafeCell<T>>,
646+
}
647+
```
648+
649+
Allowing `arc` to be safely moved out of `KeepAlive<T>` would create the false impression that it is
650+
safe to use `arc` — it is not. By requiring `unsafe` to read `arc`, Rust's safety tooling ensures a
651+
narrow safety boundary: the user is forced to justify their actions when accessing `arc` (which
652+
documents its safety conditions as they relate to `KeepAlive`), rather than in downstream
653+
interactions with `UnsafeCell<T>` (whose methods necessarily provide only general guidance).
654+
Consequently, we require that moving unsafe fields out of their enclosing type requires `unsafe`.
655+
656+
### Field Copying is Safe
657+
658+
We propose that all uses of unsafe fields require `unsafe`, including copying. Alternatively, we
659+
might consider making field copies safe. However, a field may carry an invariant that could be
660+
violated as consequence a copy. For example, consider a field of type `&'static RefCell<T>` that
661+
imposes an invariant on the value of `T`. In this alternative proposal, such a field could be safely
662+
copiable out of its enclosing type, then safely mutated via the API of `RefCell`. Consequently, we
663+
require that copying unsafe fields out of their enclosing type requires `unsafe`.
664+
631665
### Copy Is Safe To Implement
632666

633667
We propose that `Copy` is conditionally unsafe to implement; i.e., that the `unsafe` modifier is

0 commit comments

Comments
 (0)