@@ -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