Skip to content

Commit 636a6c2

Browse files
authored
Unrolled build for #141471
Rollup merge of #141471 - RalfJung:unsafe-fn-in-trait, r=traviscross unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract Inspired by discussion in #139368. Cc `@hanna-kruppe`
2 parents 868bf2d + 910a59d commit 636a6c2

File tree

1 file changed

+11
-16
lines changed

1 file changed

+11
-16
lines changed

library/std/src/keyword_docs.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,10 +1916,6 @@ mod type_keyword {}
19161916
/// - and to declare that a programmer has checked that these contracts have been upheld (`unsafe
19171917
/// {}` and `unsafe impl`, but also `unsafe fn` -- see below).
19181918
///
1919-
/// They are not mutually exclusive, as can be seen in `unsafe fn`: the body of an `unsafe fn` is,
1920-
/// by default, treated like an unsafe block. The `unsafe_op_in_unsafe_fn` lint can be enabled to
1921-
/// change that.
1922-
///
19231919
/// # Unsafe abilities
19241920
///
19251921
/// **No matter what, Safe Rust can't cause Undefined Behavior**. This is
@@ -1961,13 +1957,6 @@ mod type_keyword {}
19611957
/// - `unsafe impl`: the contract necessary to implement the trait has been
19621958
/// checked by the programmer and is guaranteed to be respected.
19631959
///
1964-
/// By default, `unsafe fn` also acts like an `unsafe {}` block
1965-
/// around the code inside the function. This means it is not just a signal to
1966-
/// the caller, but also promises that the preconditions for the operations
1967-
/// inside the function are upheld. Mixing these two meanings can be confusing, so the
1968-
/// `unsafe_op_in_unsafe_fn` lint can be enabled to warn against that and require explicit unsafe
1969-
/// blocks even inside `unsafe fn`.
1970-
///
19711960
/// See the [Rustonomicon] and the [Reference] for more information.
19721961
///
19731962
/// # Examples
@@ -2109,6 +2098,7 @@ mod type_keyword {}
21092098
/// impl Indexable for i32 {
21102099
/// const LEN: usize = 1;
21112100
///
2101+
/// /// See `Indexable` for the safety contract.
21122102
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
21132103
/// debug_assert_eq!(idx, 0);
21142104
/// *self
@@ -2120,6 +2110,7 @@ mod type_keyword {}
21202110
/// impl Indexable for [i32; 42] {
21212111
/// const LEN: usize = 42;
21222112
///
2113+
/// /// See `Indexable` for the safety contract.
21232114
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
21242115
/// // SAFETY: As per this trait's documentation, the caller ensures
21252116
/// // that `idx < 42`.
@@ -2132,6 +2123,7 @@ mod type_keyword {}
21322123
/// impl Indexable for ! {
21332124
/// const LEN: usize = 0;
21342125
///
2126+
/// /// See `Indexable` for the safety contract.
21352127
/// unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
21362128
/// // SAFETY: As per this trait's documentation, the caller ensures
21372129
/// // that `idx < 0`, which is impossible, so this is dead code.
@@ -2153,11 +2145,14 @@ mod type_keyword {}
21532145
/// contract of `idx_unchecked`. Implementing `Indexable` is safe because when writing
21542146
/// `idx_unchecked`, we don't have to worry: our *callers* need to discharge a proof obligation
21552147
/// (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`.
2148+
/// to contend with. Of course, the implementation may choose to call other unsafe operations, and
2149+
/// then it needs an `unsafe` *block* to indicate it discharged the proof obligations of its
2150+
/// callees. For that purpose it can make use of the contract that all its callers must uphold --
2151+
/// the fact that `idx < LEN`.
2152+
///
2153+
/// Note that unlike normal `unsafe fn`, an `unsafe fn` in a trait implementation does not get to
2154+
/// just pick an arbitrary safety contract! It *has* to use the safety contract defined by the trait
2155+
/// (or one with weaker preconditions).
21612156
///
21622157
/// Formally speaking, an `unsafe fn` in a trait is a function with *preconditions* that go beyond
21632158
/// those encoded by the argument types (such as `idx < LEN`), whereas an `unsafe trait` can declare

0 commit comments

Comments
 (0)