From 17e9160a2bcb4840b307f3d023c5205ace574fd8 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 19 Aug 2025 11:37:45 -0700 Subject: [PATCH 1/5] Clarify that safe extern items do not require unsafe This clarifies items.extern.fn-safety that it only applies to unsafe items. `safe` items do not require an unsafe context. I think this was just missed in https://github.com/rust-lang/reference/pull/1536. --- src/items/external-blocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index c6163b07c..57c82407b 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -29,7 +29,7 @@ Two kinds of item _declarations_ are allowed in external blocks: [functions] and [statics]. r[items.extern.fn-safety] -Calling functions or accessing statics that are declared in external blocks is only allowed in an `unsafe` context. +Calling unsafe functions or accessing unsafe statics that are declared in external blocks is only allowed in an `unsafe` context. r[items.extern.namespace] The external block defines its functions and statics in the [value namespace] of the module or block where it is located. From dd47cde9d7bd7271fab6910ecd43ad564e994263 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 19 Aug 2025 11:43:54 -0700 Subject: [PATCH 2/5] Rename items.extern.fn-safety This rule applies to both fn and static, so remove the "fn" part of the rule name. --- src/items/external-blocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 57c82407b..15a428ac9 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -28,7 +28,7 @@ r[items.extern.allowed-kinds] Two kinds of item _declarations_ are allowed in external blocks: [functions] and [statics]. -r[items.extern.fn-safety] +r[items.extern.safety] Calling unsafe functions or accessing unsafe statics that are declared in external blocks is only allowed in an `unsafe` context. r[items.extern.namespace] From 6b197e9dec572f4011430acc97db26ca7361829d Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 19 Aug 2025 21:22:10 +0000 Subject: [PATCH 3/5] Revise unsafety chapter for `unsafe extern` In light of `unsafe extern`, we need to note that only unsafe extern statics need `unsafe { .. }` and to clarify that not all foreign functions are necessarily unsafe to call. Co-authored-by: ehuss --- src/unsafety.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/unsafety.md b/src/unsafety.md index 352edec47..7353bcc60 100644 --- a/src/unsafety.md +++ b/src/unsafety.md @@ -13,13 +13,13 @@ r[safety.unsafe-deref] - Dereferencing a [raw pointer]. r[safety.unsafe-static] -- Reading or writing a [mutable] or [external] static variable. +- Reading or writing a [mutable] or unsafe [external] static variable. r[safety.unsafe-union-access] - Accessing a field of a [`union`], other than to assign to it. r[safety.unsafe-call] -- Calling an unsafe function (including an intrinsic or foreign function). +- Calling an unsafe function. r[safety.unsafe-target-feature-call] - Calling a safe function marked with a [`target_feature`][attributes.codegen.target_feature] from a function that does not have a `target_feature` attribute enabling the same features (see [attributes.codegen.target_feature.safety-restrictions]). From b9a373526bf1d5e819cc9f78eecacc11f62d32a7 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 19 Aug 2025 21:23:56 +0000 Subject: [PATCH 4/5] Add unsafe contexts cross-link in extern blocks chapter Co-authored-by: ehuss --- src/items/external-blocks.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 15a428ac9..27eee726d 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -29,7 +29,7 @@ Two kinds of item _declarations_ are allowed in external blocks: [functions] and [statics]. r[items.extern.safety] -Calling unsafe functions or accessing unsafe statics that are declared in external blocks is only allowed in an `unsafe` context. +Calling unsafe functions or accessing unsafe statics that are declared in external blocks is only allowed in an [`unsafe` context]. r[items.extern.namespace] The external block defines its functions and statics in the [value namespace] of the module or block where it is located. @@ -465,6 +465,7 @@ restrictions as [regular function parameters]. [WebAssembly module]: https://webassembly.github.io/spec/core/syntax/modules.html [`bundle` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-bundle [`dylib` versus `raw-dylib`]: #dylib-versus-raw-dylib +[`unsafe` context]: ../unsafe-keyword.md [`verbatim` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-verbatim [`whole-archive` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive [attributes]: ../attributes.md From 3b88b41d0c8863c4c4b43a68a9ca058a7414ee57 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 19 Aug 2025 21:24:44 +0000 Subject: [PATCH 5/5] Revise `unsafe` keyword chapter In light of `unsafe extern`, we need to note that this is another position that `unsafe` is allowed. While we're here, let's make some further revisions to clean up the start of this chapter, including separating off into a rule these allowed positions. Co-authored-by: ehuss --- src/unsafe-keyword.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/unsafe-keyword.md b/src/unsafe-keyword.md index e10862b75..7658c1f5c 100644 --- a/src/unsafe-keyword.md +++ b/src/unsafe-keyword.md @@ -2,15 +2,27 @@ r[unsafe] # The `unsafe` keyword r[unsafe.intro] -The `unsafe` keyword can occur in several different contexts: -unsafe functions (`unsafe fn`), unsafe blocks (`unsafe {}`), unsafe traits (`unsafe trait`), unsafe trait implementations (`unsafe impl`), unsafe external blocks (`unsafe extern`), and unsafe attributes (`#[unsafe(attr)]`). -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`], `unsafe extern`, `#[unsafe(attr)]`) +The `unsafe` keyword is used to create or discharge the obligation to prove something safe. Specifically: + +- It is used to mark code that *defines* extra safety conditions that must be upheld elsewhere. + - This includes `unsafe fn`, `unsafe static`, and `unsafe trait`. +- It is used to mark code that the programmer *asserts* satisfies safety conditions defined elsewhere. + - This includes `unsafe {}`, `unsafe impl`, `unsafe fn` without [`unsafe_op_in_unsafe_fn`], `unsafe extern`, and `#[unsafe(attr)]`. The following discusses each of these cases. See the [keyword documentation][keyword] for some illustrative examples. +r[unsafe.positions] +The `unsafe` keyword can occur in several different contexts: + +- unsafe functions (`unsafe fn`) +- unsafe blocks (`unsafe {}`) +- unsafe traits (`unsafe trait`) +- unsafe trait implementations (`unsafe impl`) +- unsafe external blocks (`unsafe extern`) +- unsafe external statics (`unsafe static`) +- unsafe attributes (`#[unsafe(attr)]`) + r[unsafe.fn] ## Unsafe functions (`unsafe fn`)