@@ -183,7 +183,44 @@ crate::cfg_select! {
183183 }
184184}
185185
186- /// A variable argument list, equivalent to `va_list` in C.
186+ /// A variable argument list, ABI-compatible with `va_list` in C.
187+ ///
188+ /// This type is created in c-variadic functions when `...` is desugared. A `VaList`
189+ /// is automatically initialized (equivalent to calling `va_start` in C).
190+ ///
191+ /// ```
192+ /// #![feature(c_variadic)]
193+ ///
194+ /// use std::ffi::VaList;
195+ ///
196+ /// /// # Safety
197+ /// /// Must be passed at least `count` arguments of type `i32`.
198+ /// unsafe extern "C" fn my_func(count: u32, ap: ...) -> i32 {
199+ /// unsafe { vmy_func(count, ap) }
200+ /// }
201+ ///
202+ /// /// # Safety
203+ /// /// Must be passed at least `count` arguments of type `i32`.
204+ /// unsafe fn vmy_func(count: u32, mut ap: VaList<'_>) -> i32 {
205+ /// let mut sum = 0;
206+ /// for _ in 0..count {
207+ /// sum += unsafe { ap.arg::<i32>() };
208+ /// }
209+ /// sum
210+ /// }
211+ ///
212+ /// assert_eq!(unsafe { my_func(1, 42i32) }, 42);
213+ /// assert_eq!(unsafe { my_func(3, 42i32, -7i32, 20i32) }, 55);
214+ /// ```
215+ ///
216+ /// The [`VaList::arg`] method can be used to read an argument from the list. This method
217+ /// automatically advances the `VaList` to the next argument. The C equivalent is `va_arg`.
218+ ///
219+ /// Cloning a `VaList` performs the equivalent of C `va_copy`, producing an independent cursor
220+ /// that arguments can be read from without affecting the original. Dropping a `VaList` performs
221+ /// the equivalent of C `va_end`.
222+ ///
223+ /// This can be used across an FFI boundary, and fully matches the platform's `va_list`.
187224#[ repr( transparent) ]
188225#[ lang = "va_list" ]
189226pub struct VaList < ' a > {
@@ -278,20 +315,17 @@ unsafe impl<T> VaArgSafe for *mut T {}
278315unsafe impl < T > VaArgSafe for * const T { }
279316
280317impl < ' f > VaList < ' f > {
281- /// Advance to and read the next variable argument.
318+ /// Read an argument from the variable argument list, and advance to the next argument.
282319 ///
283- /// # Safety
320+ /// Only types that implement [`VaArgSafe`] can be read from a variable argument list.
284321 ///
285- /// This function is only sound to call when:
322+ /// # Safety
286323 ///
287- /// - there is a next variable argument available.
288- /// - the next argument's type must be ABI-compatible with the type `T`.
289- /// - the next argument must have a properly initialized value of type `T`.
324+ /// This function is only sound to call when there is another argument to read, and that
325+ /// argument is a properly initialized value of the type `T`.
290326 ///
291327 /// Calling this function with an incompatible type, an invalid value, or when there
292328 /// are no more variable arguments, is unsound.
293- ///
294- /// [valid]: https://doc.rust-lang.org/nightly/nomicon/what-unsafe-does.html
295329 #[ inline]
296330 #[ rustc_const_unstable( feature = "const_c_variadic" , issue = "151787" ) ]
297331 pub const unsafe fn arg < T : VaArgSafe > ( & mut self ) -> T {
0 commit comments