@@ -202,18 +202,23 @@ mod sealed {
202202 impl < T > Sealed for * const T { }
203203}
204204
205- /// Trait which permits the allowed types to be used with [`VaListImpl::arg`].
205+ /// Types that are valid to read using [`VaListImpl::arg`].
206206///
207207/// # Safety
208208///
209- /// This trait must only be implemented for types that C passes as varargs without implicit promotion.
209+ /// The standard library implements this trait for primitive types that are
210+ /// expected to have a variable argument application-binary interface (ABI) on all
211+ /// platforms.
210212///
211- /// In C varargs , integers smaller than [`c_int`] and floats smaller than [`c_double`]
212- /// are implicitly promoted to [`c_int`] and [`c_double`] respectively. Implementing this trait for
213- /// types that are subject to this promotion rule is invalid.
213+ /// When C passes variable arguments , integers smaller than [`c_int`] and floats smaller
214+ /// than [`c_double`] are implicitly promoted to [`c_int`] and [`c_double`] respectively.
215+ /// Implementing this trait for types that are subject to this promotion rule is invalid.
214216///
215217/// [`c_int`]: core::ffi::c_int
216218/// [`c_double`]: core::ffi::c_double
219+ // We may unseal this trait in the future, but currently our `va_arg` implementations don't support
220+ // types with an alignment larger than 8, or with a non-scalar layout. Inline assembly can be used
221+ // to accept unsupported types in the meantime.
217222pub unsafe trait VaArgSafe : sealed:: Sealed { }
218223
219224// 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 {}
233238unsafe impl < T > VaArgSafe for * const T { }
234239
235240impl < ' f > VaListImpl < ' f > {
236- /// Advance to the next arg.
241+ /// Advance to and read the next variable argument.
242+ ///
243+ /// # Safety
244+ ///
245+ /// This function is only sound to call when the next variable argument:
246+ ///
247+ /// - has a type that is ABI-compatible with the type `T`
248+ /// - has a value that is a properly initialized value of type `T`
249+ ///
250+ /// Calling this function with an incompatible type, an invalid value, or when there
251+ /// are no more variable arguments, is unsound.
252+ ///
253+ /// [valid]: https://doc.rust-lang.org/nightly/nomicon/what-unsafe-does.html
237254 #[ inline]
238255 pub unsafe fn arg < T : VaArgSafe > ( & mut self ) -> T {
239256 // SAFETY: the caller must uphold the safety contract for `va_arg`.
0 commit comments