diff options
| author | Folkert de Vries <folkert@folkertdev.nl> | 2025-09-11 23:58:52 +0200 |
|---|---|---|
| committer | Folkert de Vries <folkert@folkertdev.nl> | 2025-09-13 21:04:58 +0200 |
| commit | 61a35937861cae48b9ade326f75c00e387e6376a (patch) | |
| tree | 341e5a26b04b1a034165293513f1b7a6b29e3a38 | |
| parent | f4665ab8368ad2e8a86d4390ae35c28bdd9561bb (diff) | |
| download | rust-61a35937861cae48b9ade326f75c00e387e6376a.tar.gz rust-61a35937861cae48b9ade326f75c00e387e6376a.zip | |
c-variadic: document `core::ffi::VaArgSafe`
and document `VaList::arg`.
| -rw-r--r-- | library/core/src/ffi/va_list.rs | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index 88ad1197777..643bd95df84 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -202,18 +202,23 @@ mod sealed { impl<T> Sealed for *const T {} } -/// Trait which permits the allowed types to be used with [`VaListImpl::arg`]. +/// Types that are valid to read using [`VaListImpl::arg`]. /// /// # Safety /// -/// This trait must only be implemented for types that C passes as varargs without implicit promotion. +/// The standard library implements this trait for primitive types that are +/// expected to have a variable argument application-binary interface (ABI) on all +/// platforms. /// -/// In C varargs, integers smaller than [`c_int`] and floats smaller than [`c_double`] -/// are implicitly promoted to [`c_int`] and [`c_double`] respectively. Implementing this trait for -/// types that are subject to this promotion rule is invalid. +/// When C passes variable arguments, integers smaller than [`c_int`] and floats smaller +/// than [`c_double`] are implicitly promoted to [`c_int`] and [`c_double`] respectively. +/// Implementing this trait for types that are subject to this promotion rule is invalid. /// /// [`c_int`]: core::ffi::c_int /// [`c_double`]: core::ffi::c_double +// We may unseal this trait in the future, but currently our `va_arg` implementations don't support +// types with an alignment larger than 8, or with a non-scalar layout. Inline assembly can be used +// to accept unsupported types in the meantime. pub unsafe trait VaArgSafe: sealed::Sealed {} // i8 and i16 are implicitly promoted to c_int in C, and cannot implement `VaArgSafe`. @@ -233,7 +238,19 @@ unsafe impl<T> VaArgSafe for *mut T {} unsafe impl<T> VaArgSafe for *const T {} impl<'f> VaListImpl<'f> { - /// Advance to the next arg. + /// Advance to and read the next variable argument. + /// + /// # Safety + /// + /// This function is only sound to call when the next variable argument: + /// + /// - has a type that is ABI-compatible with the type `T` + /// - has a value that is a properly initialized value of type `T` + /// + /// Calling this function with an incompatible type, an invalid value, or when there + /// are no more variable arguments, is unsound. + /// + /// [valid]: https://doc.rust-lang.org/nightly/nomicon/what-unsafe-does.html #[inline] pub unsafe fn arg<T: VaArgSafe>(&mut self) -> T { // SAFETY: the caller must uphold the safety contract for `va_arg`. |
