@@ -346,43 +346,44 @@ pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
346
346
347
347
/// Returns the size of the pointed-to value in bytes.
348
348
///
349
- /// This is usually the same as [`size_of::<T>()`]. However, when `T` *has* no
350
- /// statically-known size, e.g., a slice [`[T]`][slice] or a [trait object],
351
- /// then `size_of_val_raw` can be used to get the dynamically-known size.
349
+ /// This is an unchecked version of [`size_of_val`] which takes a raw pointer
350
+ /// instead of a reference.
352
351
///
353
352
/// # Safety
354
353
///
355
- /// This function is only safe to call if the following conditions hold:
356
- ///
357
- /// - If `T` is `Sized`, this function is always safe to call.
358
- /// - If the unsized tail of `T` is:
359
- /// - a [slice], then the length of the slice tail must be an initialized
360
- /// integer, and the size of the *entire value*
361
- /// (dynamic tail length + statically sized prefix) must fit in `isize`.
362
- /// - a [trait object], then the vtable part of the pointer must point
363
- /// to a valid vtable acquired by an unsizing coercion, and the size
364
- /// of the *entire value* (dynamic tail length + statically sized prefix)
365
- /// must fit in `isize`.
366
- /// - an (unstable) [extern type], then this function is always safe to
367
- /// call, but may panic or otherwise return the wrong value, as the
368
- /// extern type's layout is not known. This is the same behavior as
369
- /// [`size_of_val`] on a reference to a type with an extern type tail.
370
- /// - otherwise, it is conservatively not allowed to call this function.
354
+ /// The provided (possibly wide) pointer must describe a valid value layout.
355
+ /// Specifically:
356
+ ///
357
+ /// - If `T` is a `Sized` type, this function is always safe to call and is
358
+ /// equivalent to [`size_of::<T>()`][size_of]. The pointer is unused.
359
+ /// - If the unsized tail of `T` is a [slice], then the size of the *entire
360
+ /// value* (statically sized prefix plus dynamic tail) must fit in `isize`.
361
+ /// The pointer does not need to be [valid](crate::ptr#safety) for access,
362
+ /// as only the pointer metadata is used.
363
+ /// - If the unsized tail of `T` is a [trait object], then the wide pointer
364
+ /// metadata (the vtable reference) must originate from an unsizing or trait
365
+ /// upcasting coercion to this trait object tail, and the size of the *entire
366
+ /// value* (statically sized prefix plus dynamic tail) must fit in `isize`.
367
+ /// The pointer does not need to be [valid](crate::ptr#safety) for access,
368
+ /// as only the pointer metadata is used.
369
+ /// - For any other unsized tail kind (for example, unstable [extern types]),
370
+ /// it is *undefined behavior* to call this function. Unknown unsized tail
371
+ /// kinds may impose arbitrary requirements unknowable to current code.
371
372
///
372
- /// [`size_of::<T>()`]: size_of
373
373
/// [trait object]: ../../book/ch17-02-trait-objects.html
374
- /// [extern type]: ../../unstable-book/language-features/extern-types.html
374
+ /// [extern types]: ../../unstable-book/language-features/extern-types.html
375
+ ///
376
+ /// It is important to note that the last point means that it would be *unsound*
377
+ /// to implement `size_of_val` as an unconditional call to `size_of_val_raw`.
375
378
///
376
379
/// # Examples
377
380
///
378
381
/// ```
379
382
/// #![feature(layout_for_ptr)]
380
383
/// use std::mem;
381
384
///
382
- /// assert_eq!(4, mem::size_of_val(&5i32));
383
- ///
384
385
/// let x: [u8; 13] = [0; 13];
385
- /// let y: & [u8] = &x;
386
+ /// let y: *const [u8] = &x;
386
387
/// assert_eq!(13, unsafe { mem::size_of_val_raw(y) });
387
388
/// ```
388
389
#[ inline]
@@ -493,31 +494,37 @@ pub const fn align_of_val<T: ?Sized>(val: &T) -> usize {
493
494
/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to in
494
495
/// bytes.
495
496
///
496
- /// Every reference to a value of the type `T` must be a multiple of this number.
497
+ /// This is an unchecked version of [`align_of_val`] which takes a raw pointer
498
+ /// instead of a reference.
497
499
///
498
500
/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
499
501
///
500
502
/// # Safety
501
503
///
502
- /// This function is only safe to call if the following conditions hold:
503
- ///
504
- /// - If `T` is `Sized`, this function is always safe to call.
505
- /// - If the unsized tail of `T` is:
506
- /// - a [slice], then the length of the slice tail must be an initialized
507
- /// integer, and the size of the *entire value*
508
- /// (dynamic tail length + statically sized prefix) must fit in `isize`.
509
- /// - a [trait object], then the vtable part of the pointer must point
510
- /// to a valid vtable acquired by an unsizing coercion, and the size
511
- /// of the *entire value* (dynamic tail length + statically sized prefix)
512
- /// must fit in `isize`.
513
- /// - an (unstable) [extern type], then this function is always safe to
514
- /// call, but may panic or otherwise return the wrong value, as the
515
- /// extern type's layout is not known. This is the same behavior as
516
- /// [`align_of_val`] on a reference to a type with an extern type tail.
517
- /// - otherwise, it is conservatively not allowed to call this function.
504
+ /// The provided (possibly wide) pointer must describe a valid value layout.
505
+ /// Specifically:
506
+ ///
507
+ /// - If `T` is a `Sized` type, this function is always safe to call and is
508
+ /// equivalent to [`size_of::<T>()`][size_of]. The pointer is unused.
509
+ /// - If the unsized tail of `T` is a [slice], then the size of the *entire
510
+ /// value* (statically sized prefix plus dynamic tail) must fit in `isize`.
511
+ /// The pointer does not need to be [valid](crate::ptr#safety) for access,
512
+ /// as only the pointer metadata is used.
513
+ /// - If the unsized tail of `T` is a [trait object], then the wide pointer
514
+ /// metadata (the vtable reference) must originate from an unsizing or trait
515
+ /// upcasting coercion to this trait object tail, and the size of the *entire
516
+ /// value* (statically sized prefix plus dynamic tail) must fit in `isize`.
517
+ /// The pointer does not need to be [valid](crate::ptr#safety) for access,
518
+ /// as only the pointer metadata is used.
519
+ /// - For any other unsized tail kind (for example, unstable [extern types]),
520
+ /// it is *undefined behavior* to call this function. Unknown unsized tail
521
+ /// kinds may impose arbitrary requirements unknowable to current code.
518
522
///
519
523
/// [trait object]: ../../book/ch17-02-trait-objects.html
520
- /// [extern type]: ../../unstable-book/language-features/extern-types.html
524
+ /// [extern types]: ../../unstable-book/language-features/extern-types.html
525
+ ///
526
+ /// It is important to note that the last point means that it would be *unsound*
527
+ /// to implement `align_of_val` as an unconditional call to `align_of_val_raw`.
521
528
///
522
529
/// # Examples
523
530
///
0 commit comments