Skip to content

Commit 4d00d9b

Browse files
committed
stabilize size_of_val_raw, align_of_val_raw, Layout::for_value_raw
1 parent 43a4909 commit 4d00d9b

12 files changed

Lines changed: 55 additions & 31 deletions

File tree

library/alloc/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@
132132
#![feature(inplace_iteration)]
133133
#![feature(iter_advance_by)]
134134
#![feature(iter_next_chunk)]
135-
#![feature(layout_for_ptr)]
136135
#![feature(legacy_receiver_trait)]
137136
#![feature(likely_unlikely)]
138137
#![feature(local_waker)]

library/core/src/alloc/layout.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -230,24 +230,37 @@ impl Layout {
230230
///
231231
/// - If `T` is `Sized`, this function is always safe to call.
232232
/// - If the unsized tail of `T` is:
233-
/// - a [slice], then the length of the slice tail must be an initialized
233+
/// - a [slice] `[U]`, then the length of the slice tail must be an initialized
234234
/// integer, and the size of the *entire value*
235235
/// (dynamic tail length + statically sized prefix) must fit in `isize`.
236236
/// For the special case where the dynamic tail length is 0, this function
237237
/// is safe to call.
238-
/// - a [trait object], then the vtable part of the pointer must point
239-
/// to a valid vtable for the type `T` acquired by an unsizing coercion,
240-
/// and the size of the *entire value*
241-
/// (dynamic tail length + statically sized prefix) must fit in `isize`.
238+
// NOTE: the reason this is safe is that if an overflow were to occur already with size 0,
239+
// then we would stop compilation as even the "statically known" part of the type would
240+
// already be too big (or the call may be in dead code and optimized away, but then it
241+
// doesn't matter).
242+
/// - a [trait object] `dyn Trait`, then the vtable part of the pointer must point
243+
/// to a valid vtable for `Trait`, and the size
244+
/// of the *entire value* (dynamic tail length + statically sized prefix)
245+
/// must fit in `isize`.
242246
/// - an (unstable) [extern type], then this function is always safe to
243247
/// call, but may panic or otherwise return the wrong value, as the
244248
/// extern type's layout is not known. This is the same behavior as
245249
/// [`Layout::for_value`] on a reference to an extern type tail.
246-
/// - otherwise, it is conservatively not allowed to call this function.
250+
/// - No other kind of unsized tail currently exists. If more kinds of unsized tails get
251+
/// introduced in the future, the documentation of this function will have to be extended
252+
/// before it can be used for such types.
253+
///
254+
/// Here, *unsized tail* refers to the type obtained by recursively descending through the last
255+
/// field of a tuple or struct until we arrived at a built-in unsized type.
256+
///
257+
/// As a consequence of these rules, it is the case that whenever it is allowed to convert `val`
258+
/// into a shared reference, then it is also allowed to invoke this function.
247259
///
248260
/// [trait object]: ../../book/ch17-02-trait-objects.html
249261
/// [extern type]: ../../unstable-book/language-features/extern-types.html
250-
#[unstable(feature = "layout_for_ptr", issue = "69835")]
262+
#[stable(feature = "layout_for_ptr", since = "CURRENT_RUSTC_VERSION")]
263+
#[rustc_const_stable(feature = "layout_for_ptr", since = "CURRENT_RUSTC_VERSION")]
251264
#[must_use]
252265
#[inline]
253266
pub const unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {

library/core/src/mem/mod.rs

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,8 @@ pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
414414
/// This function is only safe to call if the following conditions hold:
415415
///
416416
/// - If `T` is `Sized`, this function is always safe to call.
417-
/// - If the unsized tail of `T` is:
418-
/// - a [slice], then the length of the slice tail must be an initialized
417+
/// - If the *unsized tail* of `T` is:
418+
/// - a [slice] `[U]`, then the length of the slice tail must be an initialized
419419
/// integer, and the size of the *entire value*
420420
/// (dynamic tail length + statically sized prefix) must fit in `isize`.
421421
/// For the special case where the dynamic tail length is 0, this function
@@ -424,15 +424,23 @@ pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
424424
// then we would stop compilation as even the "statically known" part of the type would
425425
// already be too big (or the call may be in dead code and optimized away, but then it
426426
// doesn't matter).
427-
/// - a [trait object], then the vtable part of the pointer must point
428-
/// to a valid vtable acquired by an unsizing coercion, and the size
427+
/// - a [trait object] `dyn Trait`, then the vtable part of the pointer must point
428+
/// to a valid vtable for `Trait`, and the size
429429
/// of the *entire value* (dynamic tail length + statically sized prefix)
430430
/// must fit in `isize`.
431431
/// - an (unstable) [extern type], then this function is always safe to
432432
/// call, but may panic or otherwise return the wrong value, as the
433433
/// extern type's layout is not known. This is the same behavior as
434434
/// [`size_of_val`] on a reference to a type with an extern type tail.
435-
/// - otherwise, it is conservatively not allowed to call this function.
435+
/// - No other kind of unsized tail currently exists. If more kinds of unsized tails get
436+
/// introduced in the future, the documentation of this function will have to be extended
437+
/// before it can be used for such types.
438+
///
439+
/// Here, *unsized tail* refers to the type obtained by recursively descending through the last
440+
/// field of a tuple or struct until we arrived at a built-in unsized type.
441+
///
442+
/// As a consequence of these rules, it is the case that whenever it is allowed to convert `val`
443+
/// into a shared reference, then it is also allowed to invoke this function.
436444
///
437445
/// [`size_of::<T>()`]: size_of
438446
/// [trait object]: ../../book/ch17-02-trait-objects.html
@@ -441,7 +449,6 @@ pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
441449
/// # Examples
442450
///
443451
/// ```
444-
/// #![feature(layout_for_ptr)]
445452
/// use std::mem;
446453
///
447454
/// assert_eq!(4, size_of_val(&5i32));
@@ -452,7 +459,8 @@ pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
452459
/// ```
453460
#[inline]
454461
#[must_use]
455-
#[unstable(feature = "layout_for_ptr", issue = "69835")]
462+
#[stable(feature = "layout_for_ptr", since = "CURRENT_RUSTC_VERSION")]
463+
#[rustc_const_stable(feature = "layout_for_ptr", since = "CURRENT_RUSTC_VERSION")]
456464
pub const unsafe fn size_of_val_raw<T: ?Sized>(val: *const T) -> usize {
457465
// SAFETY: the caller must provide a valid raw pointer
458466
unsafe { intrinsics::size_of_val(val) }
@@ -563,35 +571,47 @@ pub const fn align_of_val<T: ?Sized>(val: &T) -> usize {
563571
///
564572
/// - If `T` is `Sized`, this function is always safe to call.
565573
/// - If the unsized tail of `T` is:
566-
/// - a [slice], then the length of the slice tail must be an initialized
574+
/// - a [slice] `[U]`, then the length of the slice tail must be an initialized
567575
/// integer, and the size of the *entire value*
568576
/// (dynamic tail length + statically sized prefix) must fit in `isize`.
569577
/// For the special case where the dynamic tail length is 0, this function
570578
/// is safe to call.
571-
/// - a [trait object], then the vtable part of the pointer must point
572-
/// to a valid vtable acquired by an unsizing coercion, and the size
579+
// NOTE: the reason this is safe is that if an overflow were to occur already with size 0,
580+
// then we would stop compilation as even the "statically known" part of the type would
581+
// already be too big (or the call may be in dead code and optimized away, but then it
582+
// doesn't matter).
583+
/// - a [trait object] `dyn Trait`, then the vtable part of the pointer must point
584+
/// to a valid vtable for `Trait`, and the size
573585
/// of the *entire value* (dynamic tail length + statically sized prefix)
574586
/// must fit in `isize`.
575587
/// - an (unstable) [extern type], then this function is always safe to
576588
/// call, but may panic or otherwise return the wrong value, as the
577589
/// extern type's layout is not known. This is the same behavior as
578590
/// [`align_of_val`] on a reference to a type with an extern type tail.
579-
/// - otherwise, it is conservatively not allowed to call this function.
591+
/// - No other kind of unsized tail currently exists. If more kinds of unsized tails get
592+
/// introduced in the future, the documentation of this function will have to be extended
593+
/// before it can be used for such types.
594+
///
595+
/// Here, *unsized tail* refers to the type obtained by recursively descending through the last
596+
/// field of a tuple or struct until we arrived at a built-in unsized type.
597+
///
598+
/// As a consequence of these rules, it is the case that whenever it is allowed to convert `val`
599+
/// into a shared reference, then it is also allowed to invoke this function.
580600
///
581601
/// [trait object]: ../../book/ch17-02-trait-objects.html
582602
/// [extern type]: ../../unstable-book/language-features/extern-types.html
583603
///
584604
/// # Examples
585605
///
586606
/// ```
587-
/// #![feature(layout_for_ptr)]
588607
/// use std::mem;
589608
///
590609
/// assert_eq!(4, unsafe { mem::align_of_val_raw(&5i32) });
591610
/// ```
592611
#[inline]
593612
#[must_use]
594-
#[unstable(feature = "layout_for_ptr", issue = "69835")]
613+
#[stable(feature = "layout_for_ptr", since = "CURRENT_RUSTC_VERSION")]
614+
#[rustc_const_stable(feature = "layout_for_ptr", since = "CURRENT_RUSTC_VERSION")]
595615
pub const unsafe fn align_of_val_raw<T: ?Sized>(val: *const T) -> usize {
596616
// SAFETY: the caller must provide a valid raw pointer
597617
unsafe { intrinsics::align_of_val(val) }

library/coretests/tests/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@
8282
#![feature(iter_partition_in_place)]
8383
#![feature(iterator_try_collect)]
8484
#![feature(iterator_try_reduce)]
85-
#![feature(layout_for_ptr)]
8685
#![feature(maybe_uninit_fill)]
8786
#![feature(maybe_uninit_uninit_array_transpose)]
8887
#![feature(min_specialization)]

src/tools/miri/tests/pass/intrinsics/intrinsics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//@compile-flags: -Zmiri-permissive-provenance
2-
#![feature(core_intrinsics, layout_for_ptr, ptr_metadata)]
2+
#![feature(core_intrinsics, ptr_metadata)]
33
//! Tests for various intrinsics that do not fit anywhere else.
44
55
use std::intrinsics;

src/tools/miri/tests/pass/issues/issue-3200-packed-field-offset.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![feature(layout_for_ptr)]
21
use std::mem;
32

43
#[repr(packed, C)]

src/tools/miri/tests/pass/issues/issue-3200-packed2-field-offset.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![feature(layout_for_ptr)]
21
use std::mem;
32

43
#[repr(packed(4))]

src/tools/miri/tests/pass/issues/issue-miri-2123.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(ptr_metadata, layout_for_ptr)]
1+
#![feature(ptr_metadata)]
22

33
use std::{mem, ptr};
44

src/tools/miri/tests/pass/slices.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
//@[tree_implicit_writes]compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-implicit-writes
44
//@compile-flags: -Zmiri-strict-provenance
55
#![feature(slice_partition_dedup)]
6-
#![feature(layout_for_ptr)]
76

87
use std::{ptr, slice};
98

tests/ui/consts/const-size_of_val-align_of_val.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
//@ run-pass
22

3-
#![feature(layout_for_ptr)]
4-
53
use std::{mem, ptr};
64

75
struct Foo(#[allow(dead_code)] u32);

0 commit comments

Comments
 (0)