@@ -2109,6 +2109,7 @@ mod type_keyword {}
2109
2109
/// impl Indexable for i32 {
2110
2110
/// const LEN: usize = 1;
2111
2111
///
2112
+ /// /// See `Indexable` for the safety contract.
2112
2113
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
2113
2114
/// debug_assert_eq!(idx, 0);
2114
2115
/// *self
@@ -2120,6 +2121,7 @@ mod type_keyword {}
2120
2121
/// impl Indexable for [i32; 42] {
2121
2122
/// const LEN: usize = 42;
2122
2123
///
2124
+ /// /// See `Indexable` for the safety contract.
2123
2125
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
2124
2126
/// // SAFETY: As per this trait's documentation, the caller ensures
2125
2127
/// // that `idx < 42`.
@@ -2132,6 +2134,7 @@ mod type_keyword {}
2132
2134
/// impl Indexable for ! {
2133
2135
/// const LEN: usize = 0;
2134
2136
///
2137
+ /// /// See `Indexable` for the safety contract.
2135
2138
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
2136
2139
/// // SAFETY: As per this trait's documentation, the caller ensures
2137
2140
/// // that `idx < 0`, which is impossible, so this is dead code.
@@ -2153,11 +2156,15 @@ mod type_keyword {}
2153
2156
/// contract of `idx_unchecked`. Implementing `Indexable` is safe because when writing
2154
2157
/// `idx_unchecked`, we don't have to worry: our *callers* need to discharge a proof obligation
2155
2158
/// (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`.
2161
2168
///
2162
2169
/// Formally speaking, an `unsafe fn` in a trait is a function with *preconditions* that go beyond
2163
2170
/// those encoded by the argument types (such as `idx < LEN`), whereas an `unsafe trait` can declare
0 commit comments