From f24b8d4ca7aeb5340db673c7364b19e056b4de48 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 28 Sep 2022 17:31:50 +0200 Subject: [PATCH 1/3] merge unsafe-block and unsafe-function into one page --- book.toml | 2 ++ src/SUMMARY.md | 3 +-- src/attributes/codegen.md | 2 +- src/types/function-pointer.md | 2 +- src/unsafe-functions.md | 5 ----- src/{unsafe-blocks.md => unsafe-keyword.md} | 10 +++++++++- 6 files changed, 14 insertions(+), 10 deletions(-) delete mode 100644 src/unsafe-functions.md rename src/{unsafe-blocks.md => unsafe-keyword.md} (79%) diff --git a/book.toml b/book.toml index 19b9afc79..9fb3730c8 100644 --- a/book.toml +++ b/book.toml @@ -10,6 +10,8 @@ edit-url-template = "https://github.com/rust-lang/reference/edit/master/{path}" [output.html.redirect] "/expressions/enum-variant-expr.html" = "struct-expr.html" +"/unsafe-blocks.html" = "unsafe-keyword.html" +"/unsafe-functions.html" = "unsafe-keyword.html" [rust] edition = "2021" diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 82d70d043..4d9cc1d76 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -118,8 +118,7 @@ - [Inline assembly](inline-assembly.md) - [Unsafety](unsafety.md) - - [Unsafe functions](unsafe-functions.md) - - [Unsafe blocks](unsafe-blocks.md) + - [The `unsafe` keyword](unsafe-keyword.md) - [Behavior considered undefined](behavior-considered-undefined.md) - [Behavior not considered unsafe](behavior-not-considered-unsafe.md) diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index 4ebabaccf..3a36a10ca 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -347,7 +347,7 @@ trait object whose methods are attributed. [target architecture]: ../conditional-compilation.md#target_arch [trait]: ../items/traits.md [undefined behavior]: ../behavior-considered-undefined.md -[unsafe function]: ../unsafe-functions.md +[unsafe function]: ../unsafe-keyword.md [rust-abi]: ../items/external-blocks.md#abi [`core::intrinsics::caller_location`]: ../../core/intrinsics/fn.caller_location.html [`core::panic::Location::caller`]: ../../core/panic/struct.Location.html#method.caller diff --git a/src/types/function-pointer.md b/src/types/function-pointer.md index a51f76135..82103beaa 100644 --- a/src/types/function-pointer.md +++ b/src/types/function-pointer.md @@ -62,5 +62,5 @@ restrictions as [regular function parameters]. [closures]: closure.md [extern function]: ../items/functions.md#extern-function-qualifier [function items]: function-item.md -[unsafe function]: ../unsafe-functions.md +[unsafe function]: ../unsafe-keyword.md [regular function parameters]: ../items/functions.md#attributes-on-function-parameters diff --git a/src/unsafe-functions.md b/src/unsafe-functions.md deleted file mode 100644 index 7a5064c08..000000000 --- a/src/unsafe-functions.md +++ /dev/null @@ -1,5 +0,0 @@ -# Unsafe functions - -Unsafe functions are functions that are not safe in all contexts and/or for all -possible inputs. Such a function must be prefixed with the keyword `unsafe` and -can only be called from an `unsafe` block or another `unsafe` function. diff --git a/src/unsafe-blocks.md b/src/unsafe-keyword.md similarity index 79% rename from src/unsafe-blocks.md rename to src/unsafe-keyword.md index 754278445..1c7b4c848 100644 --- a/src/unsafe-blocks.md +++ b/src/unsafe-keyword.md @@ -1,4 +1,12 @@ -# Unsafe blocks +# The `unsafe` keyword + +## Unsafe functions + +Unsafe functions are functions that are not safe in all contexts and/or for all +possible inputs. Such a function must be prefixed with the keyword `unsafe` and +can only be called from an `unsafe` block or another `unsafe` function. + +## Unsafe blocks A block of code can be prefixed with the `unsafe` keyword, to permit calling `unsafe` functions or dereferencing raw pointers within a safe function. From 1423936cc4a847e2e5fa0b49d08b39a80f90e872 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 29 Sep 2022 15:45:27 +0200 Subject: [PATCH 2/3] update unsafe docs --- src/unsafe-keyword.md | 81 ++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 28 deletions(-) diff --git a/src/unsafe-keyword.md b/src/unsafe-keyword.md index 1c7b4c848..71e055ca0 100644 --- a/src/unsafe-keyword.md +++ b/src/unsafe-keyword.md @@ -1,30 +1,55 @@ # The `unsafe` keyword -## Unsafe functions - -Unsafe functions are functions that are not safe in all contexts and/or for all -possible inputs. Such a function must be prefixed with the keyword `unsafe` and -can only be called from an `unsafe` block or another `unsafe` function. - -## Unsafe blocks - -A block of code can be prefixed with the `unsafe` keyword, to permit calling -`unsafe` functions or dereferencing raw pointers within a safe function. - -When a programmer has sufficient conviction that a sequence of potentially -unsafe operations is actually safe, they can encapsulate that sequence (taken -as a whole) within an `unsafe` block. The compiler will consider uses of such -code safe, in the surrounding context. - -Unsafe blocks are used to wrap foreign libraries, make direct use of hardware -or implement features not directly present in the language. For example, Rust -provides the language features necessary to implement memory-safe concurrency -in the language but the implementation of threads and message passing is in the -standard library. - -Rust's type system is a conservative approximation of the dynamic safety -requirements, so in some cases there is a performance cost to using safe code. -For example, a doubly-linked list is not a tree structure and can only be -represented with reference-counted pointers in safe code. By using `unsafe` -blocks to represent the reverse links as raw pointers, it can be implemented -with only boxes. +The `unsafe` keyword can occur in several different contexts: +unsafe functions (`unsafe fn`), unsafe blocks (`unsafe {}`), unsafe traits (`unsafe trait`), and unsafe trait implementations (`unsafe impl`). +It plays several different roles, depending on where it is used and whether the `unsafe_op_in_unsafe_fn` lint is enabled: +- it is used to mark code that *defines* extra safety conditions (`unsafe fn`, `unsafe trait`) +- it is used to mark code that needs to *satisfy* extra safety conditions (`unsafe {}`, `unsafe impl`, `unsafe fn` without `unsafe_op_in_unsafe_fn`) + +The following discusses each of these cases. +See the [keyword documentation][keyword] for some illustrative examples. + +[keyword]: ../std/keyword.unsafe.html + +## Unsafe functions (`unsafe fn`) + +Unsafe functions are functions that are not safe in all contexts and/or for all possible inputs. +We say they have *extra safety conditions*, which are requirements that must be upheld by all callers and that the compiler does not check. +For example, `get_unchecked` has the extra safety condition that the index must be in-bounds. +The module defining an unsafe function is responsible for documenting what those extra safety conditions are. + +Such a function must be prefixed with the keyword `unsafe` and can only be called from inside an `unsafe` block. + +## Unsafe blocks (`unsafe {}`) + +A block of code can be prefixed with the `unsafe` keyword, to permit calling `unsafe` functions or dereferencing raw pointers. +By default, the body of an unsafe function is also considered to be an unsafe block; +this can be changed by enabling the `unsafe_op_in_unsafe_fn` lint. + +By putting operations into an unsafe block, the programmer states that they have taken care of satisfying the extra safety conditions of all operations inside that block. + +Unsafe blocks are the logical dual to unsafe functions: +where unsafe functions define a proof obligation that callers must uphold, unsafe blocks state that all relevant proof obligations have been discharged. +There are many ways to discharge proof obligations; +for example, there could be run-time checks or data structure invariants that guarantee that certain properties are definitely true, or the unsafe block could be inside an `unsafe fn` and use its own proof obligations to discharge the proof obligations of its callees. + +Unsafe blocks are used to wrap foreign libraries, make direct use of hardware or implement features not directly present in the language. +For example, Rust provides the language features necessary to implement memory-safe concurrency in the language but the implementation of threads and message passing in the standard library uses unsafe blocks. + +Rust's type system is a conservative approximation of the dynamic safety requirements, so in some cases there is a performance cost to using safe code. +For example, a doubly-linked list is not a tree structure and can only be represented with reference-counted pointers in safe code. +By using `unsafe` blocks to represent the reverse links as raw pointers, it can be implemented without reference counting. + +## Unsafe traits (`unsafe trait`) + +An unsafe trait is a trait that comes with extra safety conditions that must be upheld by *implementations* of the trait. +The module defining an unsafe trait is responsible for documenting what those extra safety conditions are. + +Such a trait must be prefixed with the keyword `unsafe` and can only be implemented by `unsafe impl` blocks. + +## Unsafe trait implementations (`unsafe impl`) + +When implementing an unsafe trait, the implementation needs to be prefixed with the `unsafe` keyword. +By writing `unsafe impl`, the programmer states that they have taken care of satisfying the extra safety conditions required by the trait. + +Unsafe trait implementations are the logical dual to unsafe traits: where unsafe traits define a proof obligation that implementations must uphold, unsafe implementations state that all relevant proof obligations have been discharged. From d1e4ea12affb7f0b5abf733d5150bc62905a9c94 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 30 Sep 2022 11:09:25 +0200 Subject: [PATCH 3/3] apply feedback --- src/unsafe-keyword.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/unsafe-keyword.md b/src/unsafe-keyword.md index 71e055ca0..5fa5deea6 100644 --- a/src/unsafe-keyword.md +++ b/src/unsafe-keyword.md @@ -4,27 +4,25 @@ The `unsafe` keyword can occur in several different contexts: unsafe functions (`unsafe fn`), unsafe blocks (`unsafe {}`), unsafe traits (`unsafe trait`), and unsafe trait implementations (`unsafe impl`). It plays several different roles, depending on where it is used and whether the `unsafe_op_in_unsafe_fn` lint is enabled: - it is used to mark code that *defines* extra safety conditions (`unsafe fn`, `unsafe trait`) -- it is used to mark code that needs to *satisfy* extra safety conditions (`unsafe {}`, `unsafe impl`, `unsafe fn` without `unsafe_op_in_unsafe_fn`) +- it is used to mark code that needs to *satisfy* extra safety conditions (`unsafe {}`, `unsafe impl`, `unsafe fn` without [`unsafe_op_in_unsafe_fn`]) The following discusses each of these cases. See the [keyword documentation][keyword] for some illustrative examples. -[keyword]: ../std/keyword.unsafe.html - ## Unsafe functions (`unsafe fn`) Unsafe functions are functions that are not safe in all contexts and/or for all possible inputs. We say they have *extra safety conditions*, which are requirements that must be upheld by all callers and that the compiler does not check. -For example, `get_unchecked` has the extra safety condition that the index must be in-bounds. -The module defining an unsafe function is responsible for documenting what those extra safety conditions are. +For example, [`get_unchecked`] has the extra safety condition that the index must be in-bounds. +The unsafe function should come with documentation explaining what those extra safety conditions are. -Such a function must be prefixed with the keyword `unsafe` and can only be called from inside an `unsafe` block. +Such a function must be prefixed with the keyword `unsafe` and can only be called from inside an `unsafe` block, or inside `unsafe fn` without the [`unsafe_op_in_unsafe_fn`] lint. ## Unsafe blocks (`unsafe {}`) A block of code can be prefixed with the `unsafe` keyword, to permit calling `unsafe` functions or dereferencing raw pointers. By default, the body of an unsafe function is also considered to be an unsafe block; -this can be changed by enabling the `unsafe_op_in_unsafe_fn` lint. +this can be changed by enabling the [`unsafe_op_in_unsafe_fn`] lint. By putting operations into an unsafe block, the programmer states that they have taken care of satisfying the extra safety conditions of all operations inside that block. @@ -39,11 +37,12 @@ For example, Rust provides the language features necessary to implement memory-s Rust's type system is a conservative approximation of the dynamic safety requirements, so in some cases there is a performance cost to using safe code. For example, a doubly-linked list is not a tree structure and can only be represented with reference-counted pointers in safe code. By using `unsafe` blocks to represent the reverse links as raw pointers, it can be implemented without reference counting. +(See ["Learn Rust With Entirely Too Many Linked Lists"](https://rust-unofficial.github.io/too-many-lists/) for a more in-depth exploration of this particular example.) ## Unsafe traits (`unsafe trait`) An unsafe trait is a trait that comes with extra safety conditions that must be upheld by *implementations* of the trait. -The module defining an unsafe trait is responsible for documenting what those extra safety conditions are. +The unsafe trait should come with documentation explaining what those extra safety conditions are. Such a trait must be prefixed with the keyword `unsafe` and can only be implemented by `unsafe impl` blocks. @@ -53,3 +52,7 @@ When implementing an unsafe trait, the implementation needs to be prefixed with By writing `unsafe impl`, the programmer states that they have taken care of satisfying the extra safety conditions required by the trait. Unsafe trait implementations are the logical dual to unsafe traits: where unsafe traits define a proof obligation that implementations must uphold, unsafe implementations state that all relevant proof obligations have been discharged. + +[keyword]: ../std/keyword.unsafe.html +[`get_unchecked`]: ../std/primitive.slice.html#method.get_unchecked +[`unsafe_op_in_unsafe_fn`]: ../rustc/lints/listing/allowed-by-default.html#unsafe-op-in-unsafe-fn