Unsafe Fields - Rust Project Goals (original) (raw)

Summary

Design and implement a mechanism for denoting when fields carry library safety invariants.

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.

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.

The next 6 months

In the next six months, we will iterate on the design and implementation of unsafe fields. An RFC for unsafe fields will be accepted, and a candidate implementation will — at the very least — be ready to enter the stabilization process.

Design axioms

The design of unsafe fields is guided by three axioms:

  1. Unsafe Fields Denote Safety InvariantsA field should be marked unsafe if it carries arbitrary library safety invariants with respect to its enclosing type.
  2. Unsafe Usage is Always UnsafeUses of unsafe fields which could violate their invariants must occur in the scope of an unsafe block.
  3. Safe Usage is Usually SafeUses of unsafe fields which cannot violate their invariants should not require an unsafe block.

Ownership and team asks

Owner: Jack Wrenn

Ongoing discussion on Zulip.

Definitions

Definitions for terms used above:

Frequently asked questions

TBD