review feedback

This commit is contained in:
Ralf Jung 2022-10-07 15:21:47 +02:00
parent 595e192274
commit c30dcff97a

View File

@ -1992,6 +1992,7 @@ mod type_keyword {}
/// ```rust /// ```rust
/// # #![allow(dead_code)] /// # #![allow(dead_code)]
/// #![deny(unsafe_op_in_unsafe_fn)] /// #![deny(unsafe_op_in_unsafe_fn)]
///
/// /// Dereference the given pointer. /// /// Dereference the given pointer.
/// /// /// ///
/// /// # Safety /// /// # Safety
@ -2020,22 +2021,22 @@ mod type_keyword {}
/// /// /// ///
/// /// `make_even` must return an even number. /// /// `make_even` must return an even number.
/// unsafe trait MakeEven { /// unsafe trait MakeEven {
/// fn make_even(&self) -> i32; /// fn make_even(&self) -> i32;
/// } /// }
/// ///
/// // SAFETY: Our `make_even` always returns something even. /// // SAFETY: Our `make_even` always returns something even.
/// unsafe impl MakeEven for i32 { /// unsafe impl MakeEven for i32 {
/// fn make_even(&self) -> i32 { /// fn make_even(&self) -> i32 {
/// self << 1 /// self << 1
/// } /// }
/// } /// }
/// ///
/// fn use_make_even(x: impl MakeEven) { /// fn use_make_even(x: impl MakeEven) {
/// if x.make_even() % 2 == 1 { /// if x.make_even() % 2 == 1 {
/// // SAFETY: this can never happen, because all `MakeEven` implementations /// // SAFETY: this can never happen, because all `MakeEven` implementations
/// // ensure that `make_even` returns something even. /// // ensure that `make_even` returns something even.
/// unsafe { std::hint::unreachable_unchecked() }; /// unsafe { std::hint::unreachable_unchecked() };
/// } /// }
/// } /// }
/// ``` /// ```
/// ///
@ -2053,55 +2054,55 @@ mod type_keyword {}
/// #![deny(unsafe_op_in_unsafe_fn)] /// #![deny(unsafe_op_in_unsafe_fn)]
/// ///
/// trait Indexable { /// trait Indexable {
/// const LEN: usize; /// const LEN: usize;
/// ///
/// /// # Safety /// /// # Safety
/// /// /// ///
/// /// The caller must ensure that `idx < LEN`. /// /// The caller must ensure that `idx < LEN`.
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32; /// unsafe fn idx_unchecked(&self, idx: usize) -> i32;
/// } /// }
/// ///
/// // The implementation for `i32` doesn't need to do any contract reasoning. /// // The implementation for `i32` doesn't need to do any contract reasoning.
/// impl Indexable for i32 { /// impl Indexable for i32 {
/// const LEN: usize = 1; /// const LEN: usize = 1;
/// ///
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
/// debug_assert_eq!(idx, 0); /// debug_assert_eq!(idx, 0);
/// *self /// *self
/// } /// }
/// } /// }
/// ///
/// // The implementation for arrays exploits the function contract to /// // The implementation for arrays exploits the function contract to
/// // make use of `get_unchecked` on slices and avoid a run-time check. /// // make use of `get_unchecked` on slices and avoid a run-time check.
/// impl Indexable for [i32; 42] { /// impl Indexable for [i32; 42] {
/// const LEN: usize = 42; /// const LEN: usize = 42;
/// ///
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
/// // SAFETY: As per this trait's documentation, the caller ensures /// // SAFETY: As per this trait's documentation, the caller ensures
/// // that `idx < 42`. /// // that `idx < 42`.
/// unsafe { *self.get_unchecked(idx) } /// unsafe { *self.get_unchecked(idx) }
/// } /// }
/// } /// }
/// ///
/// // The implementation for the never type declares a length of 0, /// // The implementation for the never type declares a length of 0,
/// // which means `idx_unchecked` can never be called. /// // which means `idx_unchecked` can never be called.
/// impl Indexable for ! { /// impl Indexable for ! {
/// const LEN: usize = 0; /// const LEN: usize = 0;
/// ///
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
/// // SAFETY: As per this trait's documentation, the caller ensures /// // SAFETY: As per this trait's documentation, the caller ensures
/// // that `idx < 0`, which is impossible, so this is dead code. /// // that `idx < 0`, which is impossible, so this is dead code.
/// unsafe { std::hint::unreachable_unchecked() } /// unsafe { std::hint::unreachable_unchecked() }
/// } /// }
/// } /// }
/// ///
/// fn use_indexable<I: Indexable>(x: I, idx: usize) -> i32 { /// fn use_indexable<I: Indexable>(x: I, idx: usize) -> i32 {
/// if idx < I::LEN { /// if idx < I::LEN {
/// // SAFETY: We have checked that `idx < I::LEN`. /// // SAFETY: We have checked that `idx < I::LEN`.
/// unsafe { x.idx_unchecked(idx) } /// unsafe { x.idx_unchecked(idx) }
/// } else { /// } else {
/// panic!("index out-of-bounds") /// panic!("index out-of-bounds")
/// } /// }
/// } /// }
/// ``` /// ```
/// ///
@ -2115,11 +2116,11 @@ mod type_keyword {}
/// is not implicitly an unsafe block.) For that purpose it can make use of the contract that all /// is not implicitly an unsafe block.) For that purpose it can make use of the contract that all
/// its callers must uphold -- the fact that `idx < LEN`. /// its callers must uphold -- the fact that `idx < LEN`.
/// ///
/// Formally speaking, an `unsafe fn` in a trait is a function with extra /// Formally speaking, an `unsafe fn` in a trait is a function with *preconditions* that go beyond
/// *preconditions* (such as `idx < LEN`), whereas an `unsafe trait` can declare /// those encoded by the argument types (such as `idx < LEN`), whereas an `unsafe trait` can declare
/// that some of its functions have extra *postconditions* (such as returning an /// that some of its functions have *postconditions* that go beyond those encoded in the return type
/// even integer). If a trait needs a function with both extra precondition and /// (such as returning an even integer). If a trait needs a function with both extra precondition
/// extra postcondition, then it needs an `unsafe fn` in an `unsafe trait`. /// and extra postcondition, then it needs an `unsafe fn` in an `unsafe trait`.
/// ///
/// [`extern`]: keyword.extern.html /// [`extern`]: keyword.extern.html
/// [`trait`]: keyword.trait.html /// [`trait`]: keyword.trait.html