diff options
Diffstat (limited to 'library/core/src')
| -rw-r--r-- | library/core/src/ffi/va_list.rs | 29 | ||||
| -rw-r--r-- | library/core/src/num/bignum.rs | 37 |
2 files changed, 23 insertions, 43 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`. diff --git a/library/core/src/num/bignum.rs b/library/core/src/num/bignum.rs index e33f58197bb..f21fe0b4438 100644 --- a/library/core/src/num/bignum.rs +++ b/library/core/src/num/bignum.rs @@ -335,43 +335,6 @@ macro_rules! define_bignum { } (self, borrow) } - - /// Divide self by another bignum, overwriting `q` with the quotient and `r` with the - /// remainder. - pub fn div_rem(&self, d: &$name, q: &mut $name, r: &mut $name) { - // Stupid slow base-2 long division taken from - // https://en.wikipedia.org/wiki/Division_algorithm - // FIXME use a greater base ($ty) for the long division. - assert!(!d.is_zero()); - let digitbits = <$ty>::BITS as usize; - for digit in &mut q.base[..] { - *digit = 0; - } - for digit in &mut r.base[..] { - *digit = 0; - } - r.size = d.size; - q.size = 1; - let mut q_is_zero = true; - let end = self.bit_length(); - for i in (0..end).rev() { - r.mul_pow2(1); - r.base[0] |= self.get_bit(i) as $ty; - if &*r >= d { - r.sub(d); - // Set bit `i` of q to 1. - let digit_idx = i / digitbits; - let bit_idx = i % digitbits; - if q_is_zero { - q.size = digit_idx + 1; - q_is_zero = false; - } - q.base[digit_idx] |= 1 << bit_idx; - } - } - debug_assert!(q.base[q.size..].iter().all(|&d| d == 0)); - debug_assert!(r.base[r.size..].iter().all(|&d| d == 0)); - } } impl crate::cmp::PartialEq for $name { |
