Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8f32547

Browse files
committedMar 11, 2025
Move offset_of_enum documentation to unstable book; add offset_of_slice.
1 parent 58d4395 commit 8f32547

File tree

3 files changed

+68
-17
lines changed

3 files changed

+68
-17
lines changed
 

‎library/core/src/mem/mod.rs

+9-17
Original file line numberDiff line numberDiff line change
@@ -1256,10 +1256,6 @@ impl<T> SizedTypeProperties for T {}
12561256
///
12571257
/// The offset is returned as a [`usize`].
12581258
///
1259-
/// If the nightly-only feature `offset_of_enum` is enabled,
1260-
/// `enum` variants may be traversed as if they were fields.
1261-
/// Variants themselves do not have an offset.
1262-
///
12631259
/// # Offsets of, and in, dynamically sized types
12641260
///
12651261
/// The field’s type must be [`Sized`], but it may be located in a [dynamically sized] container.
@@ -1338,11 +1334,16 @@ impl<T> SizedTypeProperties for T {}
13381334
///
13391335
/// [explicit `repr` attribute]: https://doc.rust-lang.org/reference/type-layout.html#representations
13401336
///
1337+
/// # Unstable features
1338+
///
1339+
/// The following unstable features expand the functionality of `offset_of!`:
1340+
///
1341+
/// * [`offset_of_enum`] — allows `enum` variants to be traversed as if they were fields.
1342+
/// * [`offset_of_slice`] — allows getting the offset of a field of type `[T]`.
1343+
///
13411344
/// # Examples
13421345
///
13431346
/// ```
1344-
/// #![feature(offset_of_enum)]
1345-
///
13461347
/// use std::mem;
13471348
/// #[repr(C)]
13481349
/// struct FieldStruct {
@@ -1364,20 +1365,11 @@ impl<T> SizedTypeProperties for T {}
13641365
/// struct NestedB(u8);
13651366
///
13661367
/// assert_eq!(mem::offset_of!(NestedA, b.0), 0);
1367-
///
1368-
/// #[repr(u8)]
1369-
/// enum Enum {
1370-
/// A(u8, u16),
1371-
/// B { one: u8, two: u16 },
1372-
/// }
1373-
///
1374-
/// assert_eq!(mem::offset_of!(Enum, A.0), 1);
1375-
/// assert_eq!(mem::offset_of!(Enum, B.two), 2);
1376-
///
1377-
/// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0);
13781368
/// ```
13791369
///
13801370
/// [dynamically sized]: https://doc.rust-lang.org/reference/dynamically-sized-types.html
1371+
/// [`offset_of_enum`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/offset-of-enum.html
1372+
/// [`offset_of_slice`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/offset-of-slice.html
13811373
#[stable(feature = "offset_of", since = "1.77.0")]
13821374
#[allow_internal_unstable(builtin_syntax)]
13831375
pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# `offset_of_slice`
2+
3+
The tracking issue for this feature is: [#120141]
4+
5+
[#120141]: https://github.com/rust-lang/rust/issues/120141
6+
7+
------------------------
8+
9+
When the `offset_of_enum` feature is enabled, the [`offset_of!`] macro may be used to obtain the
10+
offsets of fields of `enum`s; to express this, `enum` variants may be traversed as if they were
11+
fields. Variants themselves do not have an offset, so they cannot appear as the last path component.
12+
13+
```rust
14+
#![feature(offset_of_enum)]
15+
use std::mem;
16+
17+
#[repr(u8)]
18+
enum Enum {
19+
A(u8, u16),
20+
B { one: u8, two: u16 },
21+
}
22+
23+
assert_eq!(mem::offset_of!(Enum, A.0), 1);
24+
assert_eq!(mem::offset_of!(Enum, B.two), 2);
25+
26+
assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0);
27+
```
28+
29+
[`offset_of!`]: ../../std/mem/macro.offset_of.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# `offset_of_slice`
2+
3+
The tracking issue for this feature is: [#126151]
4+
5+
[#126151]: https://github.com/rust-lang/rust/issues/126151
6+
7+
------------------------
8+
9+
When the `offset_of_slice` feature is enabled, the [`offset_of!`] macro may be used to determine
10+
the offset of fields whose type is `[T]`, that is, a slice of dynamic size.
11+
12+
In general, fields whose type is dynamically sized do not have statically known offsets because
13+
they do not have statically known alignments. However, `[T]` has the same alignment as `T`, so
14+
it specifically may be allowed.
15+
16+
```rust
17+
#![feature(offset_of_slice)]
18+
19+
#[repr(C)]
20+
pub struct Struct {
21+
head: u32,
22+
tail: [u8],
23+
}
24+
25+
fn main() {
26+
assert_eq!(std::mem::offset_of!(Struct, tail), 4);
27+
}
28+
```
29+
30+
[`offset_of!`]: ../../std/mem/macro.offset_of.html

0 commit comments

Comments
 (0)
Failed to load comments.