about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-11-05 13:44:59 +0000
committerbors <bors@rust-lang.org>2023-11-05 13:44:59 +0000
commit992943dbaeee9d9829e82a95b788ab845ad38d0c (patch)
tree58557fc9acb43fe01f96020691e1beee5a86af32
parent04817ff00cfa1ec00a9babcb2ade1e3f2874d9bd (diff)
parent00a9ed34b1afad45c13c58acc8441ab9442d2cdd (diff)
downloadrust-992943dbaeee9d9829e82a95b788ab845ad38d0c.tar.gz
rust-992943dbaeee9d9829e82a95b788ab845ad38d0c.zip
Auto merge of #117537 - GKFX:offset-of-enum-feature, r=cjgillot
Feature gate enums in offset_of

As requested at https://github.com/rust-lang/rust/issues/106655#issuecomment-1790815262, put enums in offset_of behind their own feature gate.

`@rustbot` label F-offset_of
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0795.md4
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs9
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--library/core/src/mem/mod.rs1
-rw-r--r--tests/mir-opt/const_prop/offset_of.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-offset-of-enum.rs15
-rw-r--r--tests/ui/feature-gates/feature-gate-offset-of-enum.stderr37
-rw-r--r--tests/ui/offset-of/offset-of-enum.rs2
-rw-r--r--tests/ui/offset-of/offset-of-private.rs2
10 files changed, 70 insertions, 5 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0795.md b/compiler/rustc_error_codes/src/error_codes/E0795.md
index 8b4b2dc87fd..20f51441c29 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0795.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0795.md
@@ -3,7 +3,7 @@ Invalid argument for the `offset_of!` macro.
 Erroneous code example:
 
 ```compile_fail,E0795
-#![feature(offset_of)]
+#![feature(offset_of, offset_of_enum)]
 
 let x = std::mem::offset_of!(Option<u8>, Some);
 ```
@@ -16,7 +16,7 @@ The offset of the contained `u8` in the `Option<u8>` can be found by specifying
 the field name `0`:
 
 ```
-#![feature(offset_of)]
+#![feature(offset_of, offset_of_enum)]
 
 let x: usize = std::mem::offset_of!(Option<u8>, Some.0);
 ```
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 11782e33d84..64b5a7d2921 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -526,6 +526,8 @@ declare_features! (
     /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
     /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
     (unstable, object_safe_for_dispatch, "1.40.0", Some(43561), None),
+    /// Allows using enums in offset_of!
+    (unstable, offset_of_enum, "CURRENT_RUSTC_VERSION", Some(106655), None),
     /// Allows using `#[optimize(X)]`.
     (unstable, optimize_attribute, "1.34.0", Some(54882), None),
     /// Allows exhaustive integer pattern matching on `usize` and `isize`.
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index a11fe10c01c..8bcec3273d8 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -3119,6 +3119,15 @@ 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.parse_sess,
+                            sym::offset_of_enum,
+                            ident.span,
+                            "using enums in offset_of is experimental",
+                        ).emit();
+                    }
+
                     let Some((index, variant)) = container_def.variants()
                         .iter_enumerated()
                         .find(|(_, v)| v.ident(self.tcx).normalize_to_macros_2_0() == ident) else {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index ff470ce1fa0..1a1a1668a3c 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1114,6 +1114,7 @@ symbols! {
         off,
         offset,
         offset_of,
+        offset_of_enum,
         omit_gdb_pretty_printer_section,
         on,
         on_unimplemented,
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index caf16827ad0..c964596dd5f 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -1358,6 +1358,7 @@ impl<T> SizedTypeProperties for T {}
 ///
 /// ```
 /// #![feature(offset_of)]
+/// # #![cfg_attr(not(bootstrap), feature(offset_of_enum))]
 ///
 /// use std::mem;
 /// #[repr(C)]
diff --git a/tests/mir-opt/const_prop/offset_of.rs b/tests/mir-opt/const_prop/offset_of.rs
index 8a5289d5899..2571c3856f4 100644
--- a/tests/mir-opt/const_prop/offset_of.rs
+++ b/tests/mir-opt/const_prop/offset_of.rs
@@ -2,7 +2,7 @@
 // unit-test: ConstProp
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 
-#![feature(offset_of)]
+#![feature(offset_of, 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
new file mode 100644
index 00000000000..e19dcf9f6a5
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-offset-of-enum.rs
@@ -0,0 +1,15 @@
+#![feature(offset_of)]
+
+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
new file mode 100644
index 00000000000..893f7870237
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-offset-of-enum.stderr
@@ -0,0 +1,37 @@
+error[E0573]: expected type, found variant `Alpha::One`
+  --> $DIR/feature-gate-offset-of-enum.rs:11: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:12:23
+   |
+LL |     offset_of!(Alpha, One);
+   |                       ^^^
+   |
+   = note: see issue #106655 <https://github.com/rust-lang/rust/issues/106655> for more information
+   = help: add `#![feature(offset_of_enum)]` to the crate attributes to enable
+
+error[E0795]: `One` is an enum variant; expected field at end of `offset_of`
+  --> $DIR/feature-gate-offset-of-enum.rs:12:23
+   |
+LL |     offset_of!(Alpha, One);
+   |                       ^^^ enum variant
+
+error[E0658]: using enums in offset_of is experimental
+  --> $DIR/feature-gate-offset-of-enum.rs:14:23
+   |
+LL |     offset_of!(Alpha, Two.0);
+   |                       ^^^
+   |
+   = note: see issue #106655 <https://github.com/rust-lang/rust/issues/106655> for more information
+   = help: add `#![feature(offset_of_enum)]` to the crate attributes to enable
+
+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/offset-of/offset-of-enum.rs b/tests/ui/offset-of/offset-of-enum.rs
index e8b5a08377b..a2d6aace47d 100644
--- a/tests/ui/offset-of/offset-of-enum.rs
+++ b/tests/ui/offset-of/offset-of-enum.rs
@@ -1,4 +1,4 @@
-#![feature(offset_of)]
+#![feature(offset_of, offset_of_enum)]
 
 use std::mem::offset_of;
 
diff --git a/tests/ui/offset-of/offset-of-private.rs b/tests/ui/offset-of/offset-of-private.rs
index 6fa30d63fb8..b7affdb7943 100644
--- a/tests/ui/offset-of/offset-of-private.rs
+++ b/tests/ui/offset-of/offset-of-private.rs
@@ -1,4 +1,4 @@
-#![feature(offset_of)]
+#![feature(offset_of, offset_of_enum)]
 
 use std::mem::offset_of;