Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Stabilize Unsafe Fields

Metadata
Point of contactJack Wrenn
lang championNiko Matsakis
StatusProposed
Tracking issuerust-lang/rust-project-goals#273
Zulip channelhttps://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/unsafe.20fields.20RFC
Teamsbook, clippy, lang, libs, rustdoc, rustfmt, spec, style
Task owners(none)

Summary

Complete and stabilize field safety tooling (RFC3458).

Motivation

The absence of a mechanism for denoting the presence of library safety invariants increases both the risk of working with unsafe code and the difficulty of evaluating its soundness.

The status quo

Presently, Rust lacks mechanisms for denoting when fields carry library safety invariants, and for enforcing extra care around their use. Consequently, to evaluate the soundness of unsafe code (i.e., code which relies on safety invariants being upheld), it is not enough to check the contents of unsafe blocks — one must check all places (including safe contexts) in which safety invariants might be violated. (See The Scope of Unsafe)

For example, consider this idealized Vec:

#![allow(unused)]
fn main() {
pub struct Vec<T> {
    data: Box<[MaybeUninit<T>]>,
    len: usize,
}
}

Although len is bound by a safety invariant, it is trivial to violate its invariant in entirely safe code:

#![allow(unused)]
fn main() {
impl Vec<T> {
    pub fn evil(&mut self) {
        self.len += 2;
    }
}
}

Rust cannot enforce that modifications of len require unsafe, because the language does not provide the programmer a way of communicating to the compiler that len carries safety invariants.

After more than a decade of discussion, an RFC for field safety tooling has been accepted and a preliminary implementation is available with #![feature(unsafe_fields)]. Instability and gaps in supporting tooling (i.e., clippy, rustdoc, and rustfmt) prevent this feature from being utilized widely.

The “shiny future” we are working towards

Rust programmers will use the unsafe keyword to denote fields that carry library safety invariants; e.g.:

#![allow(unused)]
fn main() {
struct Vec<T> {
    // SAFETY: The elements `data[i]` for
    // `i < len` are in a valid state.
    unsafe data: Box<[MaybeUninit<T>]>,
    unsafe len: usize,
}
}

Rust will require that usages of unsafe fields which could violate their safety invariants must only occur within unsafe contexts.

Work items over the next year

Over the next year, we will complete tooling support, documentation, and stabilization of Unsafe Fields according to the steps documented in Tracking issue for RFC 3458: Unsafe fields:

TaskOwner(s)Notes
Implement clippy support.Jack Wrenn
Implement rustdoc support.Jack Wrenn
Implement rustfmt support.Jack Wrenn
Add Book documentation.Jack Wrenn
Add Standard Library documentation.Jack Wrenn
Add Reference documentation.Jack Wrenn
Add Style Guide documentation.Jack Wrenn
Write Stabilization Report.Jack Wrenn
StabilizeJack Wrenn

Team asks

TeamSupport levelNotes
bookSmallWill need approval for book changes.
clippySmallWill need approval for clippy support.
langSmallWill need approval for stabilization.
libsSmallWill need approval for documentation changes.
specSmallWill need approval for reference changes.
styleSmallWill need approval for style guide changes.
rustdocSmallWill need approval for rustdoc support.
rustfmtSmallWill need approval for rustfmt support.