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

Auto traits

Auto traits permit automatically implementing a trait for types which contain fields implementing the trait. That is, they are fairly close to an automatic derive. They describe properties of types rather than behaviors; current stable Rust has several auto traits: Send, Sync, Unpin, UnwindSafe, RefUnwindSafe.

Freeze is also an auto trait indirectly observable on stable; it is used by the compiler to determine which types can be placed in read-only memory, for example.

Auto traits are tracked in rust-lang/rust#13231, and are also sometimes referred to as OIBITs (“opt-in built-in traits”).

As of November 2020, the language team feels that new auto traits are unlikely to be added or stabilized. See discussion on the addition of Freeze for context. There is a fairly high burden to doing so on the ecosystem, as it becomes a concern of every library author whether to implement the trait or not.

Each auto trait represents a semver compatibility hazard for Rust libraries, as adding private fields can remove the auto trait unintentionally from a type.

Stabilizing the ability to define auto traits also allows “testing” for the absence of a specific type:

auto trait NoString {}
impl !NoString for String {}

This is not something we generally want to allow, as it makes almost any change to types semver breaking. That means that stabilizing defining new auto traits with no restrictions on negative impls is currently unlikely.

Restrictions on negative impls

Not all use-cases for auto traits require unrestricted “type absence testing” capabilities. pyo3’s Ungil trait provides a good case study. pyo3 is a Python interoperability library, and it uses the Ungil trait to denote types that are safe to access when the Python Global Interpeter Lock (GIL) is not held. pyo3 provides explicit !Ungil impls only for types defined in the pyo3 crate itself. Because of this, all types that do not implement Ungil are defined either by pyo3 itself, or by downstream dependencies of pyo3. As long as pyo3 does not introduce new negative impls for existing types in new minor versions of itself, the backward compatibility hazard is mostly avoided.

However, there is still one problematic case. Trait objects only implement the traits they list explicitly, so even with the restrictions described previously, downstream crates would be able to test for the presence of trait objects inside upstream types. One potential solution is to change dyn Trait to mean dyn Trait + AllAutoTraitsDefinedInDownstreamCrates or dyn Trait + AllAutoTraitsDefinedOutsideOfCore.

obj2c uses its AutoreleaseSafe auto trait in a similar manner to pyo3’s Ungil.

As of October 2023, the lang team no longer feels that stabilizing any form of auto traits is entirely out of the question.