From 9bfd1c4bdb5a8c4ee86c9d4ef4d4b17fa9694b99 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Thu, 2 Nov 2023 05:25:57 -0700 Subject: [PATCH 1/4] Expand mem::offset_of! docs Makes progress on #106655 --- library/core/src/mem/mod.rs | 64 +++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 8792134cdc8..05f039fdc98 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1294,13 +1294,64 @@ impl SizedTypeProperties for T {} /// /// Structs, enums, unions and tuples are supported. /// -/// Nested field accesses may be used, but not array indexes like in `C`'s `offsetof`. +/// Nested field accesses may be used, but not array indexes. /// /// Enum variants may be traversed as if they were fields. Variants themselves do /// not have an offset. /// +/// Visibility is respected - all types and fields must be visible to the call site: +/// +/// ``` +/// #![feature(offset_of)] +/// +/// mod nested { +/// #[repr(C)] +/// pub struct Struct { +/// private: u8, +/// } +/// } +/// +/// // assert_eq!(mem::offset_of!(nested::Struct, private), 0); +/// // ^^^ error[E0616]: field `private` of struct `Struct` is private +/// ``` +/// /// Note that type layout is, in general, [subject to change and -/// platform-specific](https://doc.rust-lang.org/reference/type-layout.html). +/// platform-specific](https://doc.rust-lang.org/reference/type-layout.html). If +/// layout stability is required, consider using an [explicit `repr` attribute]. +/// +/// Rust guarantees that the offset of a given field within a given type will not +/// change over the lifetime of the program. However, two different compilations of +/// the same program may result in different layouts. Also, even within a single +/// program execution, no guarantees are made about types which are *similar* but +/// not *identical*, e.g.: +/// +/// ``` +/// #![feature(offset_of)] +/// +/// use std::mem; +/// struct Wrapper(T, U); +/// +/// type A = Wrapper; +/// type B = Wrapper; +/// +/// // Not necessarily identical even though `u8` and `i8` have the same layout! +/// // assert!(mem::offset_of!(A, 1), mem::offset_of!(B, 1)); +/// +/// #[repr(transparent)] +/// struct U8(u8); +/// +/// type C = Wrapper; +/// +/// // Not necessarily identical even though `u8` and `U8` have the same layout! +/// // assert!(mem::offset_of!(A, 1), mem::offset_of!(C, 1)); +/// +/// struct Empty(PhantomData); +/// +/// // Not necessarily identical even though `PhantomData` always has the same layout! +/// // assert!(mem::offset_of!(Empty, 0), mem::offset_of!(Empty, 0)); +/// ``` +/// +/// [explicit `repr` attribute]: https://doc.rust-lang.org/reference/type-layout.html#representations /// /// # Examples /// @@ -1329,6 +1380,15 @@ impl SizedTypeProperties for T {} /// /// assert_eq!(mem::offset_of!(NestedA, b.0), 0); /// +/// #[repr(u8)] +/// enum Enum { +/// A(u8, u16), +/// B { one: u8, two: u16 }, +/// } +/// +/// assert_eq!(mem::offset_of!(Enum, A.0), 1); +/// assert_eq!(mem::offset_of!(Enum, B.two), 2); +/// /// # #[cfg(not(bootstrap))] /// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0); /// ``` From ec7996df7c4225162f407098beef213ce53b1c76 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Thu, 2 Nov 2023 05:35:08 -0700 Subject: [PATCH 2/4] Remove trailing space --- library/core/src/mem/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 05f039fdc98..cbbf23e289b 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1310,7 +1310,7 @@ impl SizedTypeProperties for T {} /// private: u8, /// } /// } -/// +/// /// // assert_eq!(mem::offset_of!(nested::Struct, private), 0); /// // ^^^ error[E0616]: field `private` of struct `Struct` is private /// ``` From 9cf1a485998401cde281b5922dcfced238d31b94 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Thu, 2 Nov 2023 05:57:31 -0700 Subject: [PATCH 3/4] Update mod.rs --- library/core/src/mem/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index cbbf23e289b..70d74b5c459 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1328,7 +1328,6 @@ impl SizedTypeProperties for T {} /// ``` /// #![feature(offset_of)] /// -/// use std::mem; /// struct Wrapper(T, U); /// /// type A = Wrapper; @@ -1345,7 +1344,7 @@ impl SizedTypeProperties for T {} /// // Not necessarily identical even though `u8` and `U8` have the same layout! /// // assert!(mem::offset_of!(A, 1), mem::offset_of!(C, 1)); /// -/// struct Empty(PhantomData); +/// struct Empty(core::marker::PhantomData); /// /// // Not necessarily identical even though `PhantomData` always has the same layout! /// // assert!(mem::offset_of!(Empty, 0), mem::offset_of!(Empty, 0)); From 2cc92e666faacbeeaaf5b6e92b0a07566ac4ad69 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Thu, 2 Nov 2023 06:45:32 -0700 Subject: [PATCH 4/4] Update mod.rs --- library/core/src/mem/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 70d74b5c459..c88d71f8e54 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1385,7 +1385,9 @@ impl SizedTypeProperties for T {} /// B { one: u8, two: u16 }, /// } /// +/// # #[cfg(not(bootstrap))] /// assert_eq!(mem::offset_of!(Enum, A.0), 1); +/// # #[cfg(not(bootstrap))] /// assert_eq!(mem::offset_of!(Enum, B.two), 2); /// /// # #[cfg(not(bootstrap))]