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

Clarify some of the language around marking traits safe/unsafe. #268

Merged
merged 1 commit into from
May 11, 2021
Merged
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
23 changes: 13 additions & 10 deletions src/safe-unsafe-meaning.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,19 @@ trait expects. In this situation, the Unsafe Rust in the internals of
implementation is correct. If it isn't, it's the fault of the unsafe trait
implementation, which is consistent with Rust's safety guarantees.

The decision of whether to mark a trait `unsafe` is an API design choice.
Rust has traditionally avoided doing this because it makes Unsafe
Rust pervasive, which isn't desirable. `Send` and `Sync` are marked unsafe
because thread safety is a *fundamental property* that unsafe code can't
possibly hope to defend against in the way it could defend against a buggy
`Ord` implementation. Similarly, `GlobalAllocator` is keeping accounts of all
the memory in the program and other things like `Box` or `Vec` build on top of
it. If it does something weird (giving the same chunk of memory to another
request when it is still in use), there's no chance to detect that and do
anything about it.
The decision of whether to mark a trait `unsafe` is an API design choice. A
safe trait is easier to implement, but any unsafe code that relies on it must
defend against incorrect behavior. Marking a trait `unsafe` shifts this
responsibility to the implementor. Rust has traditionally avoided marking
traits `unsafe` because it makes Unsafe Rust pervasive, which isn't desirable.

`Send` and `Sync` are marked unsafe because thread safety is a *fundamental
property* that unsafe code can't possibly hope to defend against in the way it
could defend against a buggy `Ord` implementation. Similarly, `GlobalAllocator`
is keeping accounts of all the memory in the program and other things like
`Box` or `Vec` build on top of it. If it does something weird (giving the same
chunk of memory to another request when it is still in use), there's no chance
to detect that and do anything about it.
Comment on lines +130 to +136
Copy link
Contributor Author

@yaymukund yaymukund May 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This second paragraph is unchanged, I just split it out for readability.


The decision of whether to mark your own traits `unsafe` depends on the same
sort of consideration. If `unsafe` code can't reasonably expect to defend
Expand Down