From 584d1bd4e1a90fc14d79c8b2a119a144dfbe8daf Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Tue, 5 Jul 2022 08:03:06 +0100 Subject: [PATCH 1/2] Creating uninitialized integers is UB --- core/src/mem/maybe_uninit.rs | 3 --- core/src/mem/mod.rs | 11 +++-------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/core/src/mem/maybe_uninit.rs b/core/src/mem/maybe_uninit.rs index 997494c76..2490c0767 100644 --- a/core/src/mem/maybe_uninit.rs +++ b/core/src/mem/maybe_uninit.rs @@ -54,9 +54,6 @@ use crate::slice; /// // The equivalent code with `MaybeUninit`: /// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! ⚠️ /// ``` -/// (Notice that the rules around uninitialized integers are not finalized yet, but -/// until they are, it is advisable to avoid them.) -/// /// On top of that, remember that most types have additional invariants beyond merely /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] /// is considered initialized (under the current implementation; this does not constitute diff --git a/core/src/mem/mod.rs b/core/src/mem/mod.rs index 20b2d5e26..20be406c0 100644 --- a/core/src/mem/mod.rs +++ b/core/src/mem/mod.rs @@ -665,14 +665,9 @@ pub unsafe fn zeroed() -> T { /// correctly: it has the same effect as [`MaybeUninit::uninit().assume_init()`][uninit]. /// As the [`assume_init` documentation][assume_init] explains, /// [the Rust compiler assumes][inv] that values are properly initialized. -/// As a consequence, calling e.g. `mem::uninitialized::()` causes immediate -/// undefined behavior for returning a `bool` that is not definitely either `true` -/// or `false`. Worse, truly uninitialized memory like what gets returned here -/// is special in that the compiler knows that it does not have a fixed value. -/// This makes it undefined behavior to have uninitialized data in a variable even -/// if that variable has an integer type. -/// (Notice that the rules around uninitialized integers are not finalized yet, but -/// until they are, it is advisable to avoid them.) +/// +/// Therefore, it is immediate undefined behavior to call this function on nearly all types, +/// including integer types and arrays of integer types, and even if the result is unused. /// /// [uninit]: MaybeUninit::uninit /// [assume_init]: MaybeUninit::assume_init From ae4961ad4aa7d7ab1428b4a3809590f3fcbbd2e4 Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Tue, 5 Jul 2022 17:50:33 +0100 Subject: [PATCH 2/2] Re-add some justification --- core/src/mem/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/mem/mod.rs b/core/src/mem/mod.rs index 20be406c0..d2dd2941d 100644 --- a/core/src/mem/mod.rs +++ b/core/src/mem/mod.rs @@ -666,6 +666,11 @@ pub unsafe fn zeroed() -> T { /// As the [`assume_init` documentation][assume_init] explains, /// [the Rust compiler assumes][inv] that values are properly initialized. /// +/// Truly uninitialized memory like what gets returned here +/// is special in that the compiler knows that it does not have a fixed value. +/// This makes it undefined behavior to have uninitialized data in a variable even +/// if that variable has an integer type. +/// /// Therefore, it is immediate undefined behavior to call this function on nearly all types, /// including integer types and arrays of integer types, and even if the result is unused. ///