diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 8968c1771e4c5..b1f37451d240f 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -318,6 +318,8 @@ declare_features! ( (accepted, non_modrs_mods, "1.30.0", Some(44660)), /// Allows using multiple nested field accesses in offset_of! (accepted, offset_of_nested, "1.82.0", Some(120140)), + /// Allows using fields with slice type in offset_of! + (accepted, offset_of_slice, "CURRENT_RUSTC_VERSION", Some(126151)), /// Allows the use of or-patterns (e.g., `0 | 1`). (accepted, or_patterns, "1.53.0", Some(54883)), /// Allows using `+bundle,+whole-archive` link modifiers with native libs. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 98213affc5bfc..7acb9460c36e2 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -589,8 +589,6 @@ declare_features! ( (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)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows specifying nop padding on functions for dynamic patching. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index de2f039cb1c86..adadeba7e60ea 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3946,15 +3946,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let field_ty = self.field_ty(expr.span, field, args); - if self.tcx.features().offset_of_slice() { - self.require_type_has_static_alignment(field_ty, expr.span); - } else { - self.require_type_is_sized( - field_ty, - expr.span, - ObligationCauseCode::Misc, - ); - } + self.require_type_has_static_alignment(field_ty, expr.span); if field.vis.is_accessible_from(def_scope, self.tcx) { self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None); @@ -3975,15 +3967,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && field.name == sym::integer(index) { if let Some(&field_ty) = tys.get(index) { - if self.tcx.features().offset_of_slice() { - self.require_type_has_static_alignment(field_ty, expr.span); - } else { - self.require_type_is_sized( - field_ty, - expr.span, - ObligationCauseCode::Misc, - ); - } + self.require_type_has_static_alignment(field_ty, expr.span); field_indices.push((FIRST_VARIANT, index.into())); current_container = field_ty; diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 27387754633d1..14103a6ae3134 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1263,10 +1263,10 @@ impl SizedTypeProperties for T {} /// /// # Offsets of, and in, dynamically sized types /// -/// The field’s type must be [`Sized`], but it may be located in a [dynamically sized] container. -/// If the field type is dynamically sized, then you cannot use `offset_of!` (since the field's -/// alignment, and therefore its offset, may also be dynamic) and must take the offset from an -/// actual pointer to the container instead. +/// The field’s type must have a statically known alignment. In other words, it is [`Sized`], a slice, +/// or some wrapper around a slice. Notably, this is not the case if the field is a trait object. +/// The alignment of trait objects can be different based on what the underlying type is, which can +/// affect the offset of the field. Therefore you cannot use `offset_of!`. /// /// ``` /// # use core::mem; @@ -1281,8 +1281,9 @@ impl SizedTypeProperties for T {} /// #[repr(C, align(4))] /// struct Align4(u32); /// -/// assert_eq!(mem::offset_of!(Struct, a), 0); // OK — Sized field -/// assert_eq!(mem::offset_of!(Struct, b), 4); // OK — not DST +/// assert_eq!(mem::offset_of!(Struct, b), 4); // OK — the last field is Sized +/// assert_eq!(mem::offset_of!(Struct<[u8]>, b), 1); // OK — the last field is a slice +/// assert_eq!(mem::offset_of!(Struct, a), 0); // OK — the struct is unsized, but the field `a` is Sized /// /// // assert_eq!(mem::offset_of!(Struct, b), 1); /// // ^^^ error[E0277]: ... cannot be known at compilation time @@ -1344,7 +1345,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 /// @@ -1374,7 +1374,6 @@ impl SizedTypeProperties for T {} /// /// [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)] pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) { diff --git a/src/doc/unstable-book/src/language-features/offset-of-slice.md b/src/doc/unstable-book/src/language-features/offset-of-slice.md deleted file mode 100644 index c887fa07f67e1..0000000000000 --- a/src/doc/unstable-book/src/language-features/offset-of-slice.md +++ /dev/null @@ -1,30 +0,0 @@ -# `offset_of_slice` - -The tracking issue for this feature is: [#126151] - -[#126151]: https://github.com/rust-lang/rust/issues/126151 - ------------------------- - -When the `offset_of_slice` feature is enabled, the [`offset_of!`] macro may be used to determine -the offset of fields whose type is `[T]`, that is, a slice of dynamic size. - -In general, fields whose type is dynamically sized do not have statically known offsets because -they do not have statically known alignments. However, `[T]` has the same alignment as `T`, so -it specifically may be allowed. - -```rust -#![feature(offset_of_slice)] - -#[repr(C)] -pub struct Struct { - head: u32, - tail: [u8], -} - -fn main() { - assert_eq!(std::mem::offset_of!(Struct, tail), 4); -} -``` - -[`offset_of!`]: ../../std/mem/macro.offset_of.html diff --git a/tests/ui/offset-of/offset-of-slice-normalized.rs b/tests/ui/offset-of/offset-of-slice-normalized.rs index 9d1fd9dd2ee14..db890bf511882 100644 --- a/tests/ui/offset-of/offset-of-slice-normalized.rs +++ b/tests/ui/offset-of/offset-of-slice-normalized.rs @@ -3,8 +3,6 @@ //@[next] compile-flags: -Znext-solver //@ run-pass -#![feature(offset_of_slice)] - use std::mem::offset_of; trait Mirror { diff --git a/tests/ui/offset-of/offset-of-slice.rs b/tests/ui/offset-of/offset-of-slice.rs index e6eb12abd7bbc..7512f02e8d11c 100644 --- a/tests/ui/offset-of/offset-of-slice.rs +++ b/tests/ui/offset-of/offset-of-slice.rs @@ -1,5 +1,4 @@ //@run-pass -#![feature(offset_of_slice)] use std::mem::offset_of;