From d27f7a29e244ff19f5a135547b3aeb8ec1361154 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 14 Jul 2025 22:34:16 +0800 Subject: [PATCH] stabilize `offset_of_enum` --- .../src/error_codes/E0795.md | 4 -- compiler/rustc_feature/src/accepted.rs | 2 + compiler/rustc_feature/src/unstable.rs | 2 - compiler/rustc_hir_typeck/src/expr.rs | 10 ----- library/core/src/lib.rs | 1 - library/core/src/mem/mod.rs | 13 ++++++- .../src/language-features/offset-of-enum.md | 29 -------------- tests/mir-opt/const_prop/offset_of.rs | 2 - .../feature-gate-offset-of-enum.rs | 13 ------- .../feature-gate-offset-of-enum.stderr | 39 ------------------- tests/ui/layout/randomize.rs | 2 - tests/ui/offset-of/offset-of-enum.rs | 2 - tests/ui/offset-of/offset-of-enum.stderr | 12 +++--- tests/ui/offset-of/offset-of-private.rs | 4 +- tests/ui/offset-of/offset-of-private.stderr | 16 ++++---- 15 files changed, 28 insertions(+), 123 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/offset-of-enum.md delete mode 100644 tests/ui/feature-gates/feature-gate-offset-of-enum.rs delete mode 100644 tests/ui/feature-gates/feature-gate-offset-of-enum.stderr diff --git a/compiler/rustc_error_codes/src/error_codes/E0795.md b/compiler/rustc_error_codes/src/error_codes/E0795.md index 69e61f7738f79..49eb57024aa9e 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0795.md +++ b/compiler/rustc_error_codes/src/error_codes/E0795.md @@ -3,8 +3,6 @@ Invalid argument for the `offset_of!` macro. Erroneous code example: ```compile_fail,E0795 -#![feature(offset_of_enum)] - let x = std::mem::offset_of!(Option, Some); ``` @@ -16,8 +14,6 @@ The offset of the contained `u8` in the `Option` can be found by specifying the field name `0`: ``` -#![feature(offset_of_enum)] - let x: usize = std::mem::offset_of!(Option, Some.0); ``` diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 83be3241b127c..c85afa9214512 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -328,6 +328,8 @@ declare_features! ( (accepted, non_exhaustive, "1.40.0", Some(44109)), /// Allows `foo.rs` as an alternative to `foo/mod.rs`. (accepted, non_modrs_mods, "1.30.0", Some(44660)), + /// Allows using enums in offset_of! + (accepted, offset_of_enum, "CURRENT_RUSTC_VERSION", Some(120141)), /// Allows using multiple nested field accesses in offset_of! (accepted, offset_of_nested, "1.82.0", Some(120140)), /// Allows the use of or-patterns (e.g., `0 | 1`). diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index efd8bde71d76d..cc741d611d8c7 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -597,8 +597,6 @@ declare_features! ( (unstable, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554)), /// Allows `for` binders in where-clauses (incomplete, non_lifetime_binders, "1.69.0", Some(108185)), - /// Allows using enums in offset_of! - (unstable, offset_of_enum, "1.75.0", Some(120141)), /// Allows using fields with slice type in offset_of! (unstable, offset_of_slice, "1.81.0", Some(126151)), /// Allows using `#[optimize(X)]`. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 067ee0f0eb0b9..8025149aa0ca1 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3847,16 +3847,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (ident, _def_scope) = self.tcx.adjust_ident_and_get_scope(field, container_def.did(), block); - if !self.tcx.features().offset_of_enum() { - rustc_session::parse::feature_err( - &self.tcx.sess, - sym::offset_of_enum, - ident.span, - "using enums in offset_of is experimental", - ) - .emit(); - } - let Some((index, variant)) = container_def .variants() .iter_enumerated() diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 2f701171505c7..e7c9f0772c2ff 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -113,7 +113,6 @@ #![feature(is_ascii_octdigit)] #![feature(lazy_get)] #![feature(link_cfg)] -#![feature(offset_of_enum)] #![feature(panic_internals)] #![feature(ptr_alignment_type)] #![feature(ptr_metadata)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 1bd12d818cfe6..88658581f3b48 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1365,7 +1365,6 @@ impl SizedTypeProperties for T {} /// /// The following unstable features expand the functionality of `offset_of!`: /// -/// * [`offset_of_enum`] — allows `enum` variants to be traversed as if they were fields. /// * [`offset_of_slice`] — allows getting the offset of a field of type `[T]`. /// /// # Examples @@ -1392,10 +1391,20 @@ impl SizedTypeProperties for T {} /// struct NestedB(u8); /// /// 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); +/// +/// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0); /// ``` /// /// [dynamically sized]: https://doc.rust-lang.org/reference/dynamically-sized-types.html -/// [`offset_of_enum`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/offset-of-enum.html /// [`offset_of_slice`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/offset-of-slice.html #[stable(feature = "offset_of", since = "1.77.0")] #[allow_internal_unstable(builtin_syntax)] diff --git a/src/doc/unstable-book/src/language-features/offset-of-enum.md b/src/doc/unstable-book/src/language-features/offset-of-enum.md deleted file mode 100644 index 78c0d87f639ed..0000000000000 --- a/src/doc/unstable-book/src/language-features/offset-of-enum.md +++ /dev/null @@ -1,29 +0,0 @@ -# `offset_of_enum` - -The tracking issue for this feature is: [#120141] - -[#120141]: https://github.com/rust-lang/rust/issues/120141 - ------------------------- - -When the `offset_of_enum` feature is enabled, the [`offset_of!`] macro may be used to obtain the -offsets of fields of `enum`s; to express this, `enum` variants may be traversed as if they were -fields. Variants themselves do not have an offset, so they cannot appear as the last path component. - -```rust -#![feature(offset_of_enum)] -use std::mem; - -#[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); - -assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0); -``` - -[`offset_of!`]: ../../std/mem/macro.offset_of.html diff --git a/tests/mir-opt/const_prop/offset_of.rs b/tests/mir-opt/const_prop/offset_of.rs index c2f5e83d6868f..b39c80d5b2907 100644 --- a/tests/mir-opt/const_prop/offset_of.rs +++ b/tests/mir-opt/const_prop/offset_of.rs @@ -2,8 +2,6 @@ //@ test-mir-pass: GVN // EMIT_MIR_FOR_EACH_PANIC_STRATEGY -#![feature(offset_of_enum)] - use std::marker::PhantomData; use std::mem::offset_of; diff --git a/tests/ui/feature-gates/feature-gate-offset-of-enum.rs b/tests/ui/feature-gates/feature-gate-offset-of-enum.rs deleted file mode 100644 index cc9efeb67f31d..0000000000000 --- a/tests/ui/feature-gates/feature-gate-offset-of-enum.rs +++ /dev/null @@ -1,13 +0,0 @@ -use std::mem::offset_of; - -enum Alpha { - One(u8), - Two(u8), -} - -fn main() { - offset_of!(Alpha::One, 0); //~ ERROR expected type, found variant `Alpha::One` - offset_of!(Alpha, One); //~ ERROR `One` is an enum variant; expected field at end of `offset_of` - //~| ERROR using enums in offset_of is experimental - offset_of!(Alpha, Two.0); //~ ERROR using enums in offset_of is experimental -} diff --git a/tests/ui/feature-gates/feature-gate-offset-of-enum.stderr b/tests/ui/feature-gates/feature-gate-offset-of-enum.stderr deleted file mode 100644 index 8a73abc8cadbe..0000000000000 --- a/tests/ui/feature-gates/feature-gate-offset-of-enum.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0573]: expected type, found variant `Alpha::One` - --> $DIR/feature-gate-offset-of-enum.rs:9:16 - | -LL | offset_of!(Alpha::One, 0); - | ^^^^^^^^^^ - | | - | not a type - | help: try using the variant's enum: `Alpha` - -error[E0658]: using enums in offset_of is experimental - --> $DIR/feature-gate-offset-of-enum.rs:10:23 - | -LL | offset_of!(Alpha, One); - | ^^^ - | - = note: see issue #120141 for more information - = help: add `#![feature(offset_of_enum)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0795]: `One` is an enum variant; expected field at end of `offset_of` - --> $DIR/feature-gate-offset-of-enum.rs:10:23 - | -LL | offset_of!(Alpha, One); - | ^^^ enum variant - -error[E0658]: using enums in offset_of is experimental - --> $DIR/feature-gate-offset-of-enum.rs:12:23 - | -LL | offset_of!(Alpha, Two.0); - | ^^^ - | - = note: see issue #120141 for more information - = help: add `#![feature(offset_of_enum)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0573, E0658, E0795. -For more information about an error, try `rustc --explain E0573`. diff --git a/tests/ui/layout/randomize.rs b/tests/ui/layout/randomize.rs index 27e99327a3196..d2b9b48fe6022 100644 --- a/tests/ui/layout/randomize.rs +++ b/tests/ui/layout/randomize.rs @@ -2,8 +2,6 @@ //@ revisions: normal randomize-layout //@ [randomize-layout]compile-flags: -Zrandomize-layout -Zlayout-seed=2 -#![feature(offset_of_enum)] - use std::ptr; diff --git a/tests/ui/offset-of/offset-of-enum.rs b/tests/ui/offset-of/offset-of-enum.rs index 64850e4782335..f1ecd4bc2f7b4 100644 --- a/tests/ui/offset-of/offset-of-enum.rs +++ b/tests/ui/offset-of/offset-of-enum.rs @@ -1,5 +1,3 @@ -#![feature(offset_of_enum)] - use std::mem::offset_of; enum Alpha { diff --git a/tests/ui/offset-of/offset-of-enum.stderr b/tests/ui/offset-of/offset-of-enum.stderr index 7e7ad41f5b6a9..6806910e9832c 100644 --- a/tests/ui/offset-of/offset-of-enum.stderr +++ b/tests/ui/offset-of/offset-of-enum.stderr @@ -1,5 +1,5 @@ error[E0573]: expected type, found variant `Alpha::One` - --> $DIR/offset-of-enum.rs:11:16 + --> $DIR/offset-of-enum.rs:9:16 | LL | offset_of!(Alpha::One, 0); | ^^^^^^^^^^ @@ -8,19 +8,19 @@ LL | offset_of!(Alpha::One, 0); | help: try using the variant's enum: `Alpha` error[E0412]: cannot find type `Beta` in this scope - --> $DIR/offset-of-enum.rs:17:16 + --> $DIR/offset-of-enum.rs:15:16 | LL | offset_of!(Beta, One); | ^^^^ not found in this scope error[E0795]: `One` is an enum variant; expected field at end of `offset_of` - --> $DIR/offset-of-enum.rs:12:23 + --> $DIR/offset-of-enum.rs:10:23 | LL | offset_of!(Alpha, One); | ^^^ enum variant error[E0609]: no field named `1` on enum variant `Alpha::Two` - --> $DIR/offset-of-enum.rs:14:23 + --> $DIR/offset-of-enum.rs:12:23 | LL | offset_of!(Alpha, Two.1); | ^^^ - ...does not have this field @@ -28,7 +28,7 @@ LL | offset_of!(Alpha, Two.1); | this enum variant... error[E0609]: no field named `foo` on enum variant `Alpha::Two` - --> $DIR/offset-of-enum.rs:15:23 + --> $DIR/offset-of-enum.rs:13:23 | LL | offset_of!(Alpha, Two.foo); | ^^^ --- ...does not have this field @@ -36,7 +36,7 @@ LL | offset_of!(Alpha, Two.foo); | this enum variant... error[E0599]: no variant named `NonExistent` found for enum `Alpha` - --> $DIR/offset-of-enum.rs:16:23 + --> $DIR/offset-of-enum.rs:14:23 | LL | offset_of!(Alpha, NonExistent); | ^^^^^^^^^^^ variant not found diff --git a/tests/ui/offset-of/offset-of-private.rs b/tests/ui/offset-of/offset-of-private.rs index 8b8ffb5e08e90..d6b734b7356c7 100644 --- a/tests/ui/offset-of/offset-of-private.rs +++ b/tests/ui/offset-of/offset-of-private.rs @@ -1,5 +1,3 @@ -#![feature(offset_of_enum)] - use std::mem::offset_of; mod m { @@ -31,7 +29,7 @@ fn main() { offset_of!(m::FooTuple, 1); //~ ERROR field `1` of struct `FooTuple` is private offset_of!(m::Bar, public); //~ ERROR struct `Bar` is private offset_of!(m::Bar, private); //~ ERROR struct `Bar` is private - //~| ERROR field `private` of struct `Bar` is private + //~^ ERROR field `private` of struct `Bar` is private offset_of!(m::Baz, Var1.0.public); offset_of!(m::Baz, Var1.0.private); //~ ERROR field `private` of struct `Foo` is private diff --git a/tests/ui/offset-of/offset-of-private.stderr b/tests/ui/offset-of/offset-of-private.stderr index 930e30e6390f5..ccea9afc0acd8 100644 --- a/tests/ui/offset-of/offset-of-private.stderr +++ b/tests/ui/offset-of/offset-of-private.stderr @@ -1,47 +1,47 @@ error[E0603]: struct `Bar` is private - --> $DIR/offset-of-private.rs:32:19 + --> $DIR/offset-of-private.rs:30:19 | LL | offset_of!(m::Bar, public); | ^^^ private struct | note: the struct `Bar` is defined here - --> $DIR/offset-of-private.rs:16:5 + --> $DIR/offset-of-private.rs:14:5 | LL | struct Bar { | ^^^^^^^^^^ error[E0603]: struct `Bar` is private - --> $DIR/offset-of-private.rs:33:19 + --> $DIR/offset-of-private.rs:31:19 | LL | offset_of!(m::Bar, private); | ^^^ private struct | note: the struct `Bar` is defined here - --> $DIR/offset-of-private.rs:16:5 + --> $DIR/offset-of-private.rs:14:5 | LL | struct Bar { | ^^^^^^^^^^ error[E0616]: field `private` of struct `Foo` is private - --> $DIR/offset-of-private.rs:29:24 + --> $DIR/offset-of-private.rs:27:24 | LL | offset_of!(m::Foo, private); | ^^^^^^^ private field error[E0616]: field `1` of struct `FooTuple` is private - --> $DIR/offset-of-private.rs:31:29 + --> $DIR/offset-of-private.rs:29:29 | LL | offset_of!(m::FooTuple, 1); | ^ private field error[E0616]: field `private` of struct `Bar` is private - --> $DIR/offset-of-private.rs:33:24 + --> $DIR/offset-of-private.rs:31:24 | LL | offset_of!(m::Bar, private); | ^^^^^^^ private field error[E0616]: field `private` of struct `Foo` is private - --> $DIR/offset-of-private.rs:37:31 + --> $DIR/offset-of-private.rs:35:31 | LL | offset_of!(m::Baz, Var1.0.private); | ^^^^^^^ private field