Skip to content

Commit 803aca7

Browse files
committed
unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract
1 parent d00435f commit 803aca7

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

library/std/src/keyword_docs.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,6 +2109,7 @@ mod type_keyword {}
21092109
/// impl Indexable for i32 {
21102110
/// const LEN: usize = 1;
21112111
///
2112+
/// /// See `Indexable` for the safety contract.
21122113
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
21132114
/// debug_assert_eq!(idx, 0);
21142115
/// *self
@@ -2120,6 +2121,7 @@ mod type_keyword {}
21202121
/// impl Indexable for [i32; 42] {
21212122
/// const LEN: usize = 42;
21222123
///
2124+
/// /// See `Indexable` for the safety contract.
21232125
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
21242126
/// // SAFETY: As per this trait's documentation, the caller ensures
21252127
/// // that `idx < 42`.
@@ -2132,6 +2134,7 @@ mod type_keyword {}
21322134
/// impl Indexable for ! {
21332135
/// const LEN: usize = 0;
21342136
///
2137+
/// /// See `Indexable` for the safety contract.
21352138
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
21362139
/// // SAFETY: As per this trait's documentation, the caller ensures
21372140
/// // that `idx < 0`, which is impossible, so this is dead code.
@@ -2153,11 +2156,15 @@ mod type_keyword {}
21532156
/// contract of `idx_unchecked`. Implementing `Indexable` is safe because when writing
21542157
/// `idx_unchecked`, we don't have to worry: our *callers* need to discharge a proof obligation
21552158
/// (like `use_indexable` does), but the *implementation* of `get_unchecked` has no proof obligation
2156-
/// to contend with. Of course, the implementation of `Indexable` may choose to call other unsafe
2157-
/// operations, and then it needs an `unsafe` *block* to indicate it discharged the proof
2158-
/// obligations of its callees. (We enabled `unsafe_op_in_unsafe_fn`, so the body of `idx_unchecked`
2159-
/// is not implicitly an unsafe block.) For that purpose it can make use of the contract that all
2160-
/// its callers must uphold -- the fact that `idx < LEN`.
2159+
/// to contend with. Note that unlike normal `unsafe fn`, an `unsafe fn` in a trait implementation
2160+
/// does not get to just pick an arbitrary safety contract! It *has* to use the safety contract
2161+
/// defined by the trait (or a stronger contract, i.e., weaker preconditions).
2162+
///
2163+
/// Of course, the implementation may choose to call other unsafe operations, and then it needs an
2164+
/// `unsafe` *block* to indicate it discharged the proof obligations of its callees. (We enabled
2165+
/// `unsafe_op_in_unsafe_fn`, so the body of `idx_unchecked` is not implicitly an unsafe block.) For
2166+
/// that purpose it can make use of the contract that all its callers must uphold -- the fact that
2167+
/// `idx < LEN`.
21612168
///
21622169
/// Formally speaking, an `unsafe fn` in a trait is a function with *preconditions* that go beyond
21632170
/// those encoded by the argument types (such as `idx < LEN`), whereas an `unsafe trait` can declare

0 commit comments

Comments
 (0)