Skip to content

Stabilize offset_of_enum #143954

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions compiler/rustc_error_codes/src/error_codes/E0795.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>, Some);
```

Expand All @@ -16,8 +14,6 @@ The offset of the contained `u8` in the `Option<u8>` can be found by specifying
the field name `0`:

```
#![feature(offset_of_enum)]

let x: usize = std::mem::offset_of!(Option<u8>, Some.0);
```

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`).
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,6 @@ declare_features! (
(unstable, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554)),
/// Allows `for<T>` 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)]`.
Expand Down
10 changes: 0 additions & 10 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
1 change: 0 additions & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
13 changes: 11 additions & 2 deletions library/core/src/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1365,7 +1365,6 @@ impl<T> 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
Expand All @@ -1392,10 +1391,20 @@ impl<T> 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)]
Expand Down
29 changes: 0 additions & 29 deletions src/doc/unstable-book/src/language-features/offset-of-enum.md

This file was deleted.

2 changes: 0 additions & 2 deletions tests/mir-opt/const_prop/offset_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
13 changes: 0 additions & 13 deletions tests/ui/feature-gates/feature-gate-offset-of-enum.rs

This file was deleted.

39 changes: 0 additions & 39 deletions tests/ui/feature-gates/feature-gate-offset-of-enum.stderr

This file was deleted.

2 changes: 0 additions & 2 deletions tests/ui/layout/randomize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
//@ revisions: normal randomize-layout
//@ [randomize-layout]compile-flags: -Zrandomize-layout -Zlayout-seed=2

#![feature(offset_of_enum)]

use std::ptr;


Expand Down
2 changes: 0 additions & 2 deletions tests/ui/offset-of/offset-of-enum.rs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: is this missing test coverage for array indexing cases, e.g.

#![feature(offset_of_enum)]

enum Alpha {
    One([u8; 1]),
}

fn main() {
    println!("{}", std::mem::offset_of!(Alpha, One.0[0]));
    //~^ ERROR array indexing not supported in offset_of
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that error is missing a test yes - should be easy enough to add a line as in your example to one of these files. (I won't open a separate PR for that test as it would merge-conflict with this one.)

Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(offset_of_enum)]

use std::mem::offset_of;

enum Alpha {
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/offset-of/offset-of-enum.stderr
Original file line number Diff line number Diff line change
@@ -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);
| ^^^^^^^^^^
Expand All @@ -8,35 +8,35 @@ 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
| |
| 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
| |
| 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
Expand Down
4 changes: 1 addition & 3 deletions tests/ui/offset-of/offset-of-private.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(offset_of_enum)]

use std::mem::offset_of;

mod m {
Expand Down Expand Up @@ -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
Expand Down
16 changes: 8 additions & 8 deletions tests/ui/offset-of/offset-of-private.stderr
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading