Skip to content
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
14 changes: 10 additions & 4 deletions src/safe-unsafe-meaning.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,13 @@ interfaces built on top of these implementations can be assumed to be safe.
The need for all of this separation boils down to a single fundamental property
of Safe Rust, the *soundness property*:

**No matter what, Safe Rust can't cause Undefined Behavior.**
**No matter what, Safe Rust clients can't cause Undefined Behavior.**

The design of the safe/unsafe split means that there is an asymmetric trust
relationship between Safe and Unsafe Rust. Safe Rust inherently has to
trust that any Unsafe Rust it touches has been written correctly.
On the other hand, Unsafe Rust cannot trust Safe Rust without care.
On the other hand, Unsafe Rust cannot trust Safe Rust without care. It can
trust Safe Rust dependencies but cannot trust Safe Rust clients.
Comment on lines +66 to +67
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe it'd be better to describe what cannot be trusted a bit more specific.

Suggested change
On the other hand, Unsafe Rust cannot trust Safe Rust without care. It can
trust Safe Rust dependencies but cannot trust Safe Rust clients.
On the other hand, Unsafe Rust cannot trust Safe Rust without care. It can
trust specific Safe Rust implementations, but not arbitrary Safe Rust chosen
or supplied by clients.


As an example, Rust has the [`PartialOrd`] and [`Ord`] traits to differentiate
between types which can "just" be compared, and those that provide a "total"
Expand Down Expand Up @@ -91,8 +92,13 @@ can be weighed against the benefit. In this case there's basically zero risk;
if integers and slices are broken, *everyone* is broken. Also, they're maintained
by the same people who maintain `BTreeMap`, so it's easy to keep tabs on them.

On the other hand, `BTreeMap`'s key type is generic. Trusting its `Ord` implementation
means trusting every `Ord` implementation in the past, present, and future.
This difference also holds for arbitrary implementations of one very specific
dependency. Unsafe Rust in crate `foo` (which depends on crate `bar`) may rely on
Safe Rust in crate `bar` to be written correctly, regardless of the actual
implementation.
Comment on lines +95 to +98
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How about this wording? I'd avoid using two words, dependency and crate in the same paragraph.

Suggested change
This difference also holds for arbitrary implementations of one very specific
dependency. Unsafe Rust in crate `foo` (which depends on crate `bar`) may rely on
Safe Rust in crate `bar` to be written correctly, regardless of the actual
implementation.
The same can be true across crate boundaries. Unsafe Rust in crate `foo` may
trust a specific Safe Rust implementation in crate `bar` when that is a
bounded piece of code that can be reviewed.


On the other hand, `BTreeMap`'s key type is generic. Trusting its `Ord`
implementation means trusting the `Ord` implementation of arbitrary clients.
Here the risk is high: someone somewhere is going to make a mistake and mess up
their `Ord` implementation, or even just straight up lie about providing a total
ordering because "it seems to work". When that happens, `BTreeMap` needs to be
Expand Down
Loading