Skip to content

Commit ba98b35

Browse files
authored
Rollup merge of #152613 - RalfJung:unsafe-keyword-docs, r=traviscross
unsafe keyword docs: bring back unsafe_op_in_unsafe_fn lint discussion @traviscross in #141471 you asked me to also update the text to account for the edition change. Apparently I did that by entirely removing this part of the discussion (except for a dangling forward reference, a "see below"). Given that old editions still exist and given that `unsafe_op_in_unsafe_fn` is just a lint so the old behavior also still exists on new editions, I am no longer sure that was a good idea, so this brings back the old text with some editing to explain the current situation.
2 parents 56ecb15 + ae3b150 commit ba98b35

1 file changed

Lines changed: 20 additions & 4 deletions

File tree

library/std/src/keyword_docs.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,10 +2042,19 @@ mod type_keyword {}
20422042
/// system.
20432043
///
20442044
/// The `unsafe` keyword has two uses:
2045-
/// - to declare the existence of contracts the compiler can't check (`unsafe fn` and `unsafe
2046-
/// trait`),
2047-
/// - and to declare that a programmer has checked that these contracts have been upheld (`unsafe
2048-
/// {}` and `unsafe impl`, but also `unsafe fn` -- see below).
2045+
/// - to declare the existence of contracts the compiler can't check,
2046+
/// - and to declare that a programmer has checked that these contracts have been upheld.
2047+
///
2048+
/// Typically, each `unsafe` is either of the first or second kind: `unsafe fn` and `unsafe trait`
2049+
/// declare the existence of an unsafe contract; `unsafe {}` and `unsafe impl` declare that an
2050+
/// unsafe contract (which must have been declared elsewhere) is being upheld.
2051+
///
2052+
/// However, historically, these two are not mutually exclusive: the body of an `unsafe fn` is, on
2053+
/// old editions, treated like an unsafe block, which means that this use of `unsafe` both declares
2054+
/// the existence of a contract to call the current function, and declares that the contracts of the
2055+
/// unsafe operations inside this function are being upheld. The `unsafe_op_in_unsafe_fn` lint can
2056+
/// be enabled to change that and make `unsafe fn` only play the former role. That lint is enabled
2057+
/// by default since edition 2024.
20492058
///
20502059
/// # Unsafe abilities
20512060
///
@@ -2088,6 +2097,13 @@ mod type_keyword {}
20882097
/// - `unsafe impl`: the contract necessary to implement the trait has been
20892098
/// checked by the programmer and is guaranteed to be respected.
20902099
///
2100+
/// On old editions, `unsafe fn` also acts like an `unsafe {}` block around the code inside the
2101+
/// function. This means it is not just a signal to the caller, but also promises that the
2102+
/// preconditions for the operations inside the function are upheld. Mixing these two meanings can
2103+
/// be confusing, so the `unsafe_op_in_unsafe_fn` lint has been introduced and enabled by default
2104+
/// since edition 2024 to warn against that and require explicit unsafe blocks even inside `unsafe
2105+
/// fn`.
2106+
///
20912107
/// See the [Rustonomicon] and the [Reference] for more information.
20922108
///
20932109
/// # Examples

0 commit comments

Comments
 (0)