Stabilize simple offset_of

This commit is contained in:
George Bateman 2023-12-05 22:15:26 +00:00
parent 88189a71e4
commit 615946db4f
No known key found for this signature in database
GPG Key ID: C417AA9C4039EFCF
30 changed files with 134 additions and 49 deletions

View File

@ -3,7 +3,7 @@ Invalid argument for the `offset_of!` macro.
Erroneous code example: Erroneous code example:
```compile_fail,E0795 ```compile_fail,E0795
#![feature(offset_of, offset_of_enum)] #![feature(offset_of_enum, offset_of_nested)]
let x = std::mem::offset_of!(Option<u8>, Some); 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`: the field name `0`:
``` ```
#![feature(offset_of, offset_of_enum)] #![feature(offset_of_enum, offset_of_nested)]
let x: usize = std::mem::offset_of!(Option<u8>, Some.0); let x: usize = std::mem::offset_of!(Option<u8>, Some.0);
``` ```

View File

@ -550,6 +550,8 @@ declare_features! (
(unstable, object_safe_for_dispatch, "1.40.0", Some(43561)), (unstable, object_safe_for_dispatch, "1.40.0", Some(43561)),
/// Allows using enums in offset_of! /// Allows using enums in offset_of!
(unstable, offset_of_enum, "1.75.0", Some(106655)), (unstable, offset_of_enum, "1.75.0", Some(106655)),
/// Allows using multiple nested field accesses in offset_of!
(unstable, offset_of_nested, "CURRENT_RUSTC_VERSION", Some(106655)),
/// Allows using `#[optimize(X)]`. /// Allows using `#[optimize(X)]`.
(unstable, optimize_attribute, "1.34.0", Some(54882)), (unstable, optimize_attribute, "1.34.0", Some(54882)),
/// Allows macro attributes on expressions, statements and non-inline modules. /// Allows macro attributes on expressions, statements and non-inline modules.

View File

@ -3246,6 +3246,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let container = self.to_ty(container).normalized; let container = self.to_ty(container).normalized;
if let Some(ident_2) = fields.get(1)
&& !self.tcx.features().offset_of_nested
{
rustc_session::parse::feature_err(
&self.tcx.sess.parse_sess,
sym::offset_of_nested,
ident_2.span,
"only a single ident or integer is stable as the field in offset_of",
)
.emit();
}
let mut field_indices = Vec::with_capacity(fields.len()); let mut field_indices = Vec::with_capacity(fields.len());
let mut current_container = container; let mut current_container = container;
let mut fields = fields.into_iter(); let mut fields = fields.into_iter();

View File

@ -1153,6 +1153,7 @@ symbols! {
offset, offset,
offset_of, offset_of,
offset_of_enum, offset_of_enum,
offset_of_nested,
ok_or_else, ok_or_else,
omit_gdb_pretty_printer_section, omit_gdb_pretty_printer_section,
on, on,

View File

@ -111,6 +111,7 @@
// //
// Library features: // Library features:
// tidy-alphabetical-start // tidy-alphabetical-start
#![cfg_attr(not(bootstrap), feature(offset_of_nested))]
#![feature(char_indices_offset)] #![feature(char_indices_offset)]
#![feature(const_align_of_val)] #![feature(const_align_of_val)]
#![feature(const_align_of_val_raw)] #![feature(const_align_of_val_raw)]
@ -176,7 +177,6 @@
#![feature(isqrt)] #![feature(isqrt)]
#![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_uninit_array)]
#![feature(non_null_convenience)] #![feature(non_null_convenience)]
#![feature(offset_of)]
#![feature(offset_of_enum)] #![feature(offset_of_enum)]
#![feature(panic_internals)] #![feature(panic_internals)]
#![feature(ptr_alignment_type)] #![feature(ptr_alignment_type)]

View File

@ -1303,11 +1303,12 @@ impl<T> SizedTypeProperties for T {}
/// Enum variants may be traversed as if they were fields. Variants themselves do /// Enum variants may be traversed as if they were fields. Variants themselves do
/// not have an offset. /// not have an offset.
/// ///
/// However, on stable only a single field name is supported, which blocks the use of
/// enum support.
///
/// Visibility is respected - all types and fields must be visible to the call site: /// Visibility is respected - all types and fields must be visible to the call site:
/// ///
/// ``` /// ```
/// #![feature(offset_of)]
///
/// mod nested { /// mod nested {
/// #[repr(C)] /// #[repr(C)]
/// pub struct Struct { /// pub struct Struct {
@ -1330,8 +1331,6 @@ impl<T> SizedTypeProperties for T {}
/// not *identical*, e.g.: /// not *identical*, e.g.:
/// ///
/// ``` /// ```
/// #![feature(offset_of)]
///
/// struct Wrapper<T, U>(T, U); /// struct Wrapper<T, U>(T, U);
/// ///
/// type A = Wrapper<u8, u8>; /// type A = Wrapper<u8, u8>;
@ -1359,8 +1358,7 @@ impl<T> SizedTypeProperties for T {}
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(offset_of)] /// #![feature(offset_of_enum, offset_of_nested)]
/// # #![feature(offset_of_enum)]
/// ///
/// use std::mem; /// use std::mem;
/// #[repr(C)] /// #[repr(C)]
@ -1396,7 +1394,7 @@ impl<T> SizedTypeProperties for T {}
/// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0); /// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0);
/// ``` /// ```
#[cfg(not(bootstrap))] #[cfg(not(bootstrap))]
#[unstable(feature = "offset_of", issue = "106655")] #[stable(feature = "offset_of", since = "CURRENT_RUSTC_VERSION")]
#[allow_internal_unstable(builtin_syntax, hint_must_use)] #[allow_internal_unstable(builtin_syntax, hint_must_use)]
pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) { pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) {
// The `{}` is for better error messages // The `{}` is for better error messages
@ -1404,7 +1402,7 @@ pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) {
} }
#[cfg(bootstrap)] #[cfg(bootstrap)]
#[unstable(feature = "offset_of", issue = "106655")] #[stable(feature = "offset_of", since = "CURRENT_RUSTC_VERSION")]
#[allow_internal_unstable(builtin_syntax, hint_must_use)] #[allow_internal_unstable(builtin_syntax, hint_must_use)]
#[allow(missing_docs)] #[allow(missing_docs)]
pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) { pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) {

View File

@ -115,7 +115,6 @@
#![feature(utf8_chunks)] #![feature(utf8_chunks)]
#![feature(is_ascii_octdigit)] #![feature(is_ascii_octdigit)]
#![feature(get_many_mut)] #![feature(get_many_mut)]
#![feature(offset_of)]
#![feature(iter_map_windows)] #![feature(iter_map_windows)]
#![allow(internal_features)] #![allow(internal_features)]
#![deny(unsafe_op_in_unsafe_fn)] #![deny(unsafe_op_in_unsafe_fn)]

View File

@ -329,7 +329,6 @@
#![feature(maybe_uninit_slice)] #![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_write_slice)] #![feature(maybe_uninit_write_slice)]
#![feature(offset_of)]
#![feature(panic_can_unwind)] #![feature(panic_can_unwind)]
#![feature(panic_info_message)] #![feature(panic_info_message)]
#![feature(panic_internals)] #![feature(panic_internals)]

View File

@ -1,4 +1,4 @@
#![feature(offset_of)] #![feature(offset_of_nested)]
use std::mem::offset_of; use std::mem::offset_of;

View File

@ -0,0 +1,28 @@
#![feature(offset_of_enum)]
use std::mem::offset_of;
struct S {
a: u8,
b: (u8, u8),
c: T,
}
struct T {
t: &'static str,
}
enum Alpha {
One(u8),
Two(u8),
}
fn main() {
offset_of!(Alpha, Two.0); //~ ERROR only a single ident or integer is stable as the field in offset_of
offset_of!(S, a);
offset_of!((u8, S), 1);
offset_of!((u32, (S, T)), 1.1); //~ ERROR only a single ident or integer is stable as the field in offset_of
offset_of!(S, b.0); //~ ERROR only a single ident or integer is stable as the field in offset_of
offset_of!((S, ()), 0.c); //~ ERROR only a single ident or integer is stable as the field in offset_of
offset_of!(S, c.t); //~ ERROR only a single ident or integer is stable as the field in offset_of
}

View File

@ -0,0 +1,55 @@
error[E0658]: only a single ident or integer is stable as the field in offset_of
--> $DIR/feature-gate-offset-of-nested.rs:21:27
|
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_nested)]` to the crate attributes to enable
error[E0658]: only a single ident or integer is stable as the field in offset_of
--> $DIR/feature-gate-offset-of-nested.rs:24:33
|
LL | offset_of!((u32, (S, T)), 1.1);
| _____----------------------------^-
| | |
| | in this macro invocation
LL | | offset_of!(S, b.0);
LL | | offset_of!((S, ()), 0.c);
LL | | offset_of!(S, c.t);
... |
|
= note: see issue #106655 <https://github.com/rust-lang/rust/issues/106655> for more information
= help: add `#![feature(offset_of_nested)]` to the crate attributes to enable
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0658]: only a single ident or integer is stable as the field in offset_of
--> $DIR/feature-gate-offset-of-nested.rs:25:21
|
LL | offset_of!(S, b.0);
| ^
|
= note: see issue #106655 <https://github.com/rust-lang/rust/issues/106655> for more information
= help: add `#![feature(offset_of_nested)]` to the crate attributes to enable
error[E0658]: only a single ident or integer is stable as the field in offset_of
--> $DIR/feature-gate-offset-of-nested.rs:26:27
|
LL | offset_of!((S, ()), 0.c);
| ^
|
= note: see issue #106655 <https://github.com/rust-lang/rust/issues/106655> for more information
= help: add `#![feature(offset_of_nested)]` to the crate attributes to enable
error[E0658]: only a single ident or integer is stable as the field in offset_of
--> $DIR/feature-gate-offset-of-nested.rs:27:21
|
LL | offset_of!(S, c.t);
| ^
|
= note: see issue #106655 <https://github.com/rust-lang/rust/issues/106655> for more information
= help: add `#![feature(offset_of_nested)]` to the crate attributes to enable
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,6 +1,6 @@
// check-pass // check-pass
#![feature(offset_of)] #![feature(offset_of_nested)]
#![deny(dead_code)] #![deny(dead_code)]
// This struct contains a projection that can only be normalized after getting the field type. // This struct contains a projection that can only be normalized after getting the field type.

View File

@ -1,4 +1,4 @@
#![feature(offset_of)] #![feature(offset_of_nested)]
#![deny(dead_code)] #![deny(dead_code)]
use std::mem::offset_of; use std::mem::offset_of;

View File

@ -1,5 +1,3 @@
#![feature(offset_of)]
use std::mem::offset_of; use std::mem::offset_of;
fn main() { fn main() {

View File

@ -1,5 +1,5 @@
error: unexpected end of macro invocation error: unexpected end of macro invocation
--> $DIR/offset-of-arg-count.rs:6:34 --> $DIR/offset-of-arg-count.rs:4:34
| |
LL | offset_of!(NotEnoughArguments); LL | offset_of!(NotEnoughArguments);
| ^ missing tokens in macro arguments | ^ missing tokens in macro arguments
@ -8,7 +8,7 @@ note: while trying to match `,`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
error: unexpected end of macro invocation error: unexpected end of macro invocation
--> $DIR/offset-of-arg-count.rs:7:45 --> $DIR/offset-of-arg-count.rs:5:45
| |
LL | offset_of!(NotEnoughArgumentsWithAComma, ); LL | offset_of!(NotEnoughArgumentsWithAComma, );
| ^ missing tokens in macro arguments | ^ missing tokens in macro arguments
@ -17,7 +17,7 @@ note: while trying to match meta-variable `$fields:expr`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
error: no rules expected the token `too` error: no rules expected the token `too`
--> $DIR/offset-of-arg-count.rs:8:34 --> $DIR/offset-of-arg-count.rs:6:34
| |
LL | offset_of!(Container, field, too many arguments); LL | offset_of!(Container, field, too many arguments);
| ^^^ no rules expected this token in macro call | ^^^ no rules expected this token in macro call
@ -25,25 +25,25 @@ LL | offset_of!(Container, field, too many arguments);
= note: while trying to match sequence end = note: while trying to match sequence end
error: unexpected token: `)` error: unexpected token: `)`
--> $DIR/offset-of-arg-count.rs:11:21 --> $DIR/offset-of-arg-count.rs:9:21
| |
LL | offset_of!(S, f.); LL | offset_of!(S, f.);
| ^ | ^
error: unexpected token: `,` error: unexpected token: `,`
--> $DIR/offset-of-arg-count.rs:12:21 --> $DIR/offset-of-arg-count.rs:10:21
| |
LL | offset_of!(S, f.,); LL | offset_of!(S, f.,);
| ^ | ^
error: offset_of expects dot-separated field and variant names error: offset_of expects dot-separated field and variant names
--> $DIR/offset-of-arg-count.rs:13:19 --> $DIR/offset-of-arg-count.rs:11:19
| |
LL | offset_of!(S, f..); LL | offset_of!(S, f..);
| ^^^ | ^^^
error: offset_of expects dot-separated field and variant names error: offset_of expects dot-separated field and variant names
--> $DIR/offset-of-arg-count.rs:14:19 --> $DIR/offset-of-arg-count.rs:12:19
| |
LL | offset_of!(S, f..,); LL | offset_of!(S, f..,);
| ^^^ | ^^^

View File

@ -1,4 +1,4 @@
#![feature(offset_of, extern_types)] #![feature(extern_types)]
use std::mem::offset_of; use std::mem::offset_of;

View File

@ -1,4 +1,4 @@
#![feature(offset_of, offset_of_enum)] #![feature(offset_of_enum, offset_of_nested)]
use std::mem::offset_of; use std::mem::offset_of;

View File

@ -1,7 +1,5 @@
// Test that inference types in `offset_of!` don't ICE. // Test that inference types in `offset_of!` don't ICE.
#![feature(offset_of)]
struct Foo<T> { struct Foo<T> {
x: T, x: T,
} }

View File

@ -1,5 +1,5 @@
error[E0282]: type annotations needed error[E0282]: type annotations needed
--> $DIR/offset-of-inference.rs:10:35 --> $DIR/offset-of-inference.rs:8:35
| |
LL | let _ = core::mem::offset_of!(Foo<_>, x); LL | let _ = core::mem::offset_of!(Foo<_>, x);
| ^^^^^^ cannot infer type | ^^^^^^ cannot infer type

View File

@ -1,6 +1,5 @@
// check-pass // check-pass
#![feature(offset_of)]
#![warn(unused)] #![warn(unused)]
fn main() { fn main() {

View File

@ -1,11 +1,11 @@
warning: unused return value of `must_use` that must be used warning: unused return value of `must_use` that must be used
--> $DIR/offset-of-must-use.rs:7:5 --> $DIR/offset-of-must-use.rs:6:5
| |
LL | core::mem::offset_of!((String,), 0); LL | core::mem::offset_of!((String,), 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/offset-of-must-use.rs:4:9 --> $DIR/offset-of-must-use.rs:3:9
| |
LL | #![warn(unused)] LL | #![warn(unused)]
| ^^^^^^ | ^^^^^^

View File

@ -1,5 +1,3 @@
#![feature(offset_of)]
use std::mem::offset_of; use std::mem::offset_of;
struct S { struct S {

View File

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/offset-of-output-type.rs:12:17 --> $DIR/offset-of-output-type.rs:10:17
| |
LL | let _: u8 = offset_of!(S, v); LL | let _: u8 = offset_of!(S, v);
| ^^^^^^^^^^^^^^^^ expected `u8`, found `usize` | ^^^^^^^^^^^^^^^^ expected `u8`, found `usize`
@ -7,7 +7,7 @@ LL | let _: u8 = offset_of!(S, v);
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/offset-of-output-type.rs:13:18 --> $DIR/offset-of-output-type.rs:11:18
| |
LL | let _: u16 = offset_of!(S, v); LL | let _: u16 = offset_of!(S, v);
| ^^^^^^^^^^^^^^^^ expected `u16`, found `usize` | ^^^^^^^^^^^^^^^^ expected `u16`, found `usize`
@ -15,7 +15,7 @@ LL | let _: u16 = offset_of!(S, v);
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/offset-of-output-type.rs:14:18 --> $DIR/offset-of-output-type.rs:12:18
| |
LL | let _: u32 = offset_of!(S, v); LL | let _: u32 = offset_of!(S, v);
| ^^^^^^^^^^^^^^^^ expected `u32`, found `usize` | ^^^^^^^^^^^^^^^^ expected `u32`, found `usize`
@ -23,7 +23,7 @@ LL | let _: u32 = offset_of!(S, v);
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/offset-of-output-type.rs:15:18 --> $DIR/offset-of-output-type.rs:13:18
| |
LL | let _: u64 = offset_of!(S, v); LL | let _: u64 = offset_of!(S, v);
| ^^^^^^^^^^^^^^^^ expected `u64`, found `usize` | ^^^^^^^^^^^^^^^^ expected `u64`, found `usize`
@ -31,7 +31,7 @@ LL | let _: u64 = offset_of!(S, v);
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/offset-of-output-type.rs:16:20 --> $DIR/offset-of-output-type.rs:14:20
| |
LL | let _: isize = offset_of!(S, v); LL | let _: isize = offset_of!(S, v);
| ^^^^^^^^^^^^^^^^ expected `isize`, found `usize` | ^^^^^^^^^^^^^^^^ expected `isize`, found `usize`
@ -39,7 +39,7 @@ LL | let _: isize = offset_of!(S, v);
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/offset-of-output-type.rs:19:5 --> $DIR/offset-of-output-type.rs:17:5
| |
LL | fn main() { LL | fn main() {
| - expected `()` because of default return type | - expected `()` because of default return type

View File

@ -1,4 +1,4 @@
#![feature(offset_of, offset_of_enum)] #![feature(offset_of_enum, offset_of_nested)]
use std::mem::offset_of; use std::mem::offset_of;

View File

@ -1,4 +1,4 @@
#![feature(offset_of)] #![feature(offset_of_nested)]
use std::mem::offset_of; use std::mem::offset_of;

View File

@ -2,7 +2,7 @@
// Test for issue #112204 -- make sure this goes through the entire compilation pipeline, // Test for issue #112204 -- make sure this goes through the entire compilation pipeline,
// similar to why `offset-of-unsized.rs` is also build-pass // similar to why `offset-of-unsized.rs` is also build-pass
#![feature(offset_of)] #![feature(offset_of_nested)]
use std::mem::offset_of; use std::mem::offset_of;

View File

@ -1,4 +1,4 @@
#![feature(offset_of)] #![feature(offset_of_nested)]
#![feature(builtin_syntax)] #![feature(builtin_syntax)]
use std::mem::offset_of; use std::mem::offset_of;

View File

@ -2,8 +2,6 @@
// regression test for #112051, not in `offset-of-dst` as the issue is in codegen, // regression test for #112051, not in `offset-of-dst` as the issue is in codegen,
// and isn't triggered in the presence of typeck errors // and isn't triggered in the presence of typeck errors
#![feature(offset_of)]
struct S<T: ?Sized> { struct S<T: ?Sized> {
a: u64, a: u64,
b: T, b: T,

View File

@ -1,7 +1,7 @@
// check-pass // check-pass
// aux-build:offset-of-staged-api.rs // aux-build:offset-of-staged-api.rs
#![feature(offset_of, unstable_test_feature)] #![feature(offset_of_nested, unstable_test_feature)]
use std::mem::offset_of; use std::mem::offset_of;

View File

@ -1,6 +1,6 @@
// aux-build:offset-of-staged-api.rs // aux-build:offset-of-staged-api.rs
#![feature(offset_of)] #![feature(offset_of_nested)]
use std::mem::offset_of; use std::mem::offset_of;