@@ -202,18 +202,23 @@ mod sealed {
202
202
impl < T > Sealed for * const T { }
203
203
}
204
204
205
- /// Trait which permits the allowed types to be used with [`VaListImpl::arg`].
205
+ /// Types that are valid to read using [`VaListImpl::arg`].
206
206
///
207
207
/// # Safety
208
208
///
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.
210
212
///
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.
214
216
///
215
217
/// [`c_int`]: core::ffi::c_int
216
218
/// [`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.
217
222
pub unsafe trait VaArgSafe : sealed:: Sealed { }
218
223
219
224
// 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 {}
233
238
unsafe impl < T > VaArgSafe for * const T { }
234
239
235
240
impl < ' 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
237
254
#[ inline]
238
255
pub unsafe fn arg < T : VaArgSafe > ( & mut self ) -> T {
239
256
// SAFETY: the caller must uphold the safety contract for `va_arg`.
0 commit comments