Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update auto traits design notes with recent discussion #237

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 34 additions & 5 deletions src/design_notes/auto_traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ 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][freeze 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.
to be added or stabilized. See [discussion][freeze 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.
Expand All @@ -30,8 +31,36 @@ 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 is
currently unlikely.
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][Ungil] 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][AutoreleaseSafe] in a similar
manner to `pyo3`'s `Ungil`.

[As of October 2023][2020-10-03 triage meeting], the lang team no longer feels
that stabilizing any form of auto traits is entirely out of the question.

[rust-lang/rust#13231]: https://github.com/rust-lang/rust/issues/13231
[freeze discussion]: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Freeze.20stabilization.20and.20auto-trait.20backcompat/near/214251682
[Ungil]: https://docs.rs/pyo3/0.20.0/pyo3/marker/trait.Ungil.html
[AutoreleaseSafe]: https://docs.rs/objc2/latest/objc2/rc/trait.AutoreleaseSafe.html]
[2020-10-03 triage meeting]: https://hackmd.io/tRjWZXdJQyOoD1d9rLeRGQ?view#%E2%80%9CPrepare-removal-of-auto-trait-syntax-in-favor-of-new-attribute-rustc_auto_trait%E2%80%9D-rust116126