Skip to content

Commit 6268598

Browse files
authored
Rollup merge of #117512 - joshlf:patch-8, r=dtolnay
Expand mem::offset_of! docs Makes progress on #106655
2 parents 67b5187 + 2cc92e6 commit 6268598

File tree

1 file changed

+63
-2
lines changed

1 file changed

+63
-2
lines changed

library/core/src/mem/mod.rs

+63-2
Original file line numberDiff line numberDiff line change
@@ -1294,13 +1294,63 @@ impl<T> SizedTypeProperties for T {}
12941294
///
12951295
/// Structs, enums, unions and tuples are supported.
12961296
///
1297-
/// Nested field accesses may be used, but not array indexes like in `C`'s `offsetof`.
1297+
/// Nested field accesses may be used, but not array indexes.
12981298
///
12991299
/// Enum variants may be traversed as if they were fields. Variants themselves do
13001300
/// not have an offset.
13011301
///
1302+
/// Visibility is respected - all types and fields must be visible to the call site:
1303+
///
1304+
/// ```
1305+
/// #![feature(offset_of)]
1306+
///
1307+
/// mod nested {
1308+
/// #[repr(C)]
1309+
/// pub struct Struct {
1310+
/// private: u8,
1311+
/// }
1312+
/// }
1313+
///
1314+
/// // assert_eq!(mem::offset_of!(nested::Struct, private), 0);
1315+
/// // ^^^ error[E0616]: field `private` of struct `Struct` is private
1316+
/// ```
1317+
///
13021318
/// Note that type layout is, in general, [subject to change and
1303-
/// platform-specific](https://doc.rust-lang.org/reference/type-layout.html).
1319+
/// platform-specific](https://doc.rust-lang.org/reference/type-layout.html). If
1320+
/// layout stability is required, consider using an [explicit `repr` attribute].
1321+
///
1322+
/// Rust guarantees that the offset of a given field within a given type will not
1323+
/// change over the lifetime of the program. However, two different compilations of
1324+
/// the same program may result in different layouts. Also, even within a single
1325+
/// program execution, no guarantees are made about types which are *similar* but
1326+
/// not *identical*, e.g.:
1327+
///
1328+
/// ```
1329+
/// #![feature(offset_of)]
1330+
///
1331+
/// struct Wrapper<T, U>(T, U);
1332+
///
1333+
/// type A = Wrapper<u8, u8>;
1334+
/// type B = Wrapper<u8, i8>;
1335+
///
1336+
/// // Not necessarily identical even though `u8` and `i8` have the same layout!
1337+
/// // assert!(mem::offset_of!(A, 1), mem::offset_of!(B, 1));
1338+
///
1339+
/// #[repr(transparent)]
1340+
/// struct U8(u8);
1341+
///
1342+
/// type C = Wrapper<u8, U8>;
1343+
///
1344+
/// // Not necessarily identical even though `u8` and `U8` have the same layout!
1345+
/// // assert!(mem::offset_of!(A, 1), mem::offset_of!(C, 1));
1346+
///
1347+
/// struct Empty<T>(core::marker::PhantomData<T>);
1348+
///
1349+
/// // Not necessarily identical even though `PhantomData` always has the same layout!
1350+
/// // assert!(mem::offset_of!(Empty<u8>, 0), mem::offset_of!(Empty<i8>, 0));
1351+
/// ```
1352+
///
1353+
/// [explicit `repr` attribute]: https://doc.rust-lang.org/reference/type-layout.html#representations
13041354
///
13051355
/// # Examples
13061356
///
@@ -1329,6 +1379,17 @@ impl<T> SizedTypeProperties for T {}
13291379
///
13301380
/// assert_eq!(mem::offset_of!(NestedA, b.0), 0);
13311381
///
1382+
/// #[repr(u8)]
1383+
/// enum Enum {
1384+
/// A(u8, u16),
1385+
/// B { one: u8, two: u16 },
1386+
/// }
1387+
///
1388+
/// # #[cfg(not(bootstrap))]
1389+
/// assert_eq!(mem::offset_of!(Enum, A.0), 1);
1390+
/// # #[cfg(not(bootstrap))]
1391+
/// assert_eq!(mem::offset_of!(Enum, B.two), 2);
1392+
///
13321393
/// # #[cfg(not(bootstrap))]
13331394
/// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0);
13341395
/// ```

0 commit comments

Comments
 (0)