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