diff --git a/src/biguint.rs b/src/biguint.rs index 1554eb0f..b12c6b94 100644 --- a/src/biguint.rs +++ b/src/biguint.rs @@ -1,5 +1,5 @@ use crate::big_digit::{self, BigDigit}; -use crate::std_alloc::{String, Vec}; +use crate::std_alloc::{Cow, String, Vec}; use core::cmp; use core::cmp::Ordering; @@ -36,7 +36,7 @@ pub use self::iter::{U32Digits, U64Digits}; /// A big unsigned integer type. pub struct BigUint { - data: Vec, + data: Cow<'static, [BigDigit]>, } // Note: derived `Clone` doesn't specialize `clone_from`, @@ -146,12 +146,19 @@ impl fmt::Octal for BigUint { impl Zero for BigUint { #[inline] fn zero() -> BigUint { - BigUint { data: Vec::new() } + BigUint { + data: Cow::Borrowed(&[]), + } } #[inline] fn set_zero(&mut self) { - self.data.clear(); + match &mut self.data { + Cow::Borrowed(s) => { + *s = &[]; + } + Cow::Owned(v) => v.clear(), + } } #[inline] @@ -163,13 +170,22 @@ impl Zero for BigUint { impl One for BigUint { #[inline] fn one() -> BigUint { - BigUint { data: vec![1] } + BigUint { + data: Cow::Borrowed(&[1]), + } } #[inline] fn set_one(&mut self) { - self.data.clear(); - self.data.push(1); + match &mut self.data { + Cow::Borrowed(s) => { + *s = &[1]; + } + Cow::Owned(v) => { + v.clear(); + v.push(1); + } + } } #[inline] @@ -515,7 +531,10 @@ pub trait ToBigUint { /// The digits are in little-endian base matching `BigDigit`. #[inline] pub(crate) fn biguint_from_vec(digits: Vec) -> BigUint { - BigUint { data: digits }.normalized() + BigUint { + data: Cow::Owned(digits), + } + .normalized() } impl BigUint { @@ -553,13 +572,15 @@ impl BigUint { /// The base 232 digits are ordered least significant digit first. #[inline] pub fn assign_from_slice(&mut self, slice: &[u32]) { - self.data.clear(); + let mut data = Vec::new(); #[cfg(not(u64_digit))] - self.data.extend_from_slice(slice); + data.extend_from_slice(slice); #[cfg(u64_digit)] - self.data.extend(slice.chunks(2).map(u32_chunk_to_u64)); + data.extend(slice.chunks(2).map(u32_chunk_to_u64)); + + self.data = Cow::Owned(data); self.normalize(); } @@ -755,7 +776,10 @@ impl BigUint { /// ``` #[inline] pub fn iter_u32_digits(&self) -> U32Digits<'_> { - U32Digits::new(self.data.as_slice()) + U32Digits::new(match &self.data { + Cow::Borrowed(v) => v, + Cow::Owned(v) => v.as_slice(), + }) } /// Returns an iterator of `u64` digits representation of the [`BigUint`] ordered least @@ -774,7 +798,10 @@ impl BigUint { /// ``` #[inline] pub fn iter_u64_digits(&self) -> U64Digits<'_> { - U64Digits::new(self.data.as_slice()) + U64Digits::new(match &self.data { + Cow::Borrowed(v) => v, + Cow::Owned(v) => v.as_slice(), + }) } /// Returns the integer formatted as a string in the given radix. @@ -851,10 +878,15 @@ impl BigUint { fn normalize(&mut self) { if let Some(&0) = self.data.last() { let len = self.data.iter().rposition(|&d| d != 0).map_or(0, |i| i + 1); - self.data.truncate(len); + self.data.to_mut().truncate(len); } - if self.data.len() < self.data.capacity() / 4 { - self.data.shrink_to_fit(); + match &mut self.data { + Cow::Owned(v) => { + if v.len() < v.capacity() / 4 { + v.shrink_to_fit(); + } + } + _ => {} } } @@ -948,11 +980,11 @@ impl BigUint { if value { if digit_index >= self.data.len() { let new_len = digit_index.saturating_add(1); - self.data.resize(new_len, 0); + self.data.to_mut().resize(new_len, 0); } - self.data[digit_index] |= bit_mask; + self.data.to_mut()[digit_index] |= bit_mask; } else if digit_index < self.data.len() { - self.data[digit_index] &= !bit_mask; + self.data.to_mut()[digit_index] &= !bit_mask; // the top bit may have been cleared, so normalize self.normalize(); } @@ -998,7 +1030,7 @@ impl IntDigits for BigUint { } #[inline] fn digits_mut(&mut self) -> &mut Vec { - &mut self.data + self.data.to_mut() } #[inline] fn normalize(&mut self) { @@ -1006,7 +1038,10 @@ impl IntDigits for BigUint { } #[inline] fn capacity(&self) -> usize { - self.data.capacity() + match &self.data { + Cow::Borrowed(v) => v.len(), + Cow::Owned(v) => v.capacity(), + } } #[inline] fn len(&self) -> usize { diff --git a/src/biguint/addition.rs b/src/biguint/addition.rs index ac6c0dde..936a4cd9 100644 --- a/src/biguint/addition.rs +++ b/src/biguint/addition.rs @@ -99,14 +99,16 @@ impl AddAssign<&BigUint> for BigUint { fn add_assign(&mut self, other: &BigUint) { let self_len = self.data.len(); let carry = if self_len < other.data.len() { - let lo_carry = __add2(&mut self.data[..], &other.data[..self_len]); - self.data.extend_from_slice(&other.data[self_len..]); - __add2(&mut self.data[self_len..], &[lo_carry]) + let lo_carry = __add2(&mut self.data.to_mut()[..], &other.data[..self_len]); + self.data + .to_mut() + .extend_from_slice(&other.data[self_len..]); + __add2(&mut self.data.to_mut()[self_len..], &[lo_carry]) } else { - __add2(&mut self.data[..], &other.data[..]) + __add2(&mut self.data.to_mut()[..], &other.data[..]) }; if carry != 0 { - self.data.push(carry); + self.data.to_mut().push(carry); } } } @@ -132,12 +134,12 @@ impl AddAssign for BigUint { fn add_assign(&mut self, other: u32) { if other != 0 { if self.data.is_empty() { - self.data.push(0); + self.data.to_mut().push(0); } - let carry = __add2(&mut self.data, &[other as BigDigit]); + let carry = __add2(&mut self.data.to_mut(), &[other as BigDigit]); if carry != 0 { - self.data.push(carry); + self.data.to_mut().push(carry); } } } @@ -177,12 +179,12 @@ impl AddAssign for BigUint { fn add_assign(&mut self, other: u64) { if other != 0 { if self.data.is_empty() { - self.data.push(0); + self.data.to_mut().push(0); } - let carry = __add2(&mut self.data, &[other as BigDigit]); + let carry = __add2(&mut self.data.to_mut(), &[other as BigDigit]); if carry != 0 { - self.data.push(carry); + self.data.to_mut().push(carry); } } } @@ -233,12 +235,12 @@ impl AddAssign for BigUint { *self += lo; } else { while self.data.len() < 2 { - self.data.push(0); + self.data.to_mut().push(0); } - let carry = __add2(&mut self.data, &[lo, hi]); + let carry = __add2(&mut self.data.to_mut(), &[lo, hi]); if carry != 0 { - self.data.push(carry); + self.data.to_mut().push(carry); } } } diff --git a/src/biguint/arbitrary.rs b/src/biguint/arbitrary.rs index 6fa91c0f..6e9a7850 100644 --- a/src/biguint/arbitrary.rs +++ b/src/biguint/arbitrary.rs @@ -1,9 +1,9 @@ use super::{biguint_from_vec, BigUint}; use crate::big_digit::BigDigit; -#[cfg(feature = "quickcheck")] -use crate::std_alloc::Box; use crate::std_alloc::Vec; +#[cfg(feature = "quickcheck")] +use crate::std_alloc::{Box, Cow}; #[cfg(feature = "quickcheck")] impl quickcheck::Arbitrary for BigUint { @@ -14,7 +14,13 @@ impl quickcheck::Arbitrary for BigUint { fn shrink(&self) -> Box> { // Use shrinker from Vec - Box::new(self.data.shrink().map(biguint_from_vec)) + Box::new( + match &self.data { + Cow::Owned(v) => v.shrink(), + Cow::Borrowed(v) => v.to_vec().shrink(), + } + .map(biguint_from_vec), + ) } } diff --git a/src/biguint/bits.rs b/src/biguint/bits.rs index 42d7ec0c..8326b551 100644 --- a/src/biguint/bits.rs +++ b/src/biguint/bits.rs @@ -35,10 +35,10 @@ impl BitAnd<&BigUint> for BigUint { impl BitAndAssign<&BigUint> for BigUint { #[inline] fn bitand_assign(&mut self, other: &BigUint) { - for (ai, &bi) in self.data.iter_mut().zip(other.data.iter()) { + for (ai, &bi) in self.data.to_mut().iter_mut().zip(other.data.iter()) { *ai &= bi; } - self.data.truncate(other.data.len()); + self.data.to_mut().truncate(other.data.len()); self.normalize(); } } @@ -57,12 +57,12 @@ impl BitOr<&BigUint> for BigUint { impl BitOrAssign<&BigUint> for BigUint { #[inline] fn bitor_assign(&mut self, other: &BigUint) { - for (ai, &bi) in self.data.iter_mut().zip(other.data.iter()) { + for (ai, &bi) in self.data.to_mut().iter_mut().zip(other.data.iter()) { *ai |= bi; } if other.data.len() > self.data.len() { let extra = &other.data[self.data.len()..]; - self.data.extend(extra.iter().cloned()); + self.data.to_mut().extend(extra.iter().cloned()); } } } @@ -81,12 +81,12 @@ impl BitXor<&BigUint> for BigUint { impl BitXorAssign<&BigUint> for BigUint { #[inline] fn bitxor_assign(&mut self, other: &BigUint) { - for (ai, &bi) in self.data.iter_mut().zip(other.data.iter()) { + for (ai, &bi) in self.data.to_mut().iter_mut().zip(other.data.iter()) { *ai ^= bi; } if other.data.len() > self.data.len() { let extra = &other.data[self.data.len()..]; - self.data.extend(extra.iter().cloned()); + self.data.to_mut().extend(extra.iter().cloned()); } self.normalize(); } diff --git a/src/biguint/convert.rs b/src/biguint/convert.rs index f19bc758..189f4c10 100644 --- a/src/biguint/convert.rs +++ b/src/biguint/convert.rs @@ -498,7 +498,7 @@ impl From for BigUint { let mut ret: BigUint = Zero::zero(); while n != 0 { - ret.data.push(n as BigDigit); + ret.data.to_mut().push(n as BigDigit); // don't overflow if BITS is 64: n = (n >> 1) >> (big_digit::BITS - 1); } @@ -513,7 +513,7 @@ impl From for BigUint { let mut ret: BigUint = Zero::zero(); while n != 0 { - ret.data.push(n as BigDigit); + ret.data.to_mut().push(n as BigDigit); n >>= big_digit::BITS; } @@ -644,7 +644,7 @@ fn to_inexact_bitwise_digits_le(u: &BigUint, bits: u8) -> Vec { let mut r = 0; let mut rbits = 0; - for c in &u.data { + for c in u.data.iter() { r |= *c << rbits; rbits += big_digit::BITS; diff --git a/src/biguint/division.rs b/src/biguint/division.rs index 29998382..0604640b 100644 --- a/src/biguint/division.rs +++ b/src/biguint/division.rs @@ -4,6 +4,7 @@ use super::u32_to_u128; use super::{cmp_slice, BigUint}; use crate::big_digit::{self, BigDigit, DoubleBigDigit}; +use crate::std_alloc::Cow; use crate::UsizePromotion; use core::cmp::Ordering::{Equal, Greater, Less}; @@ -48,13 +49,13 @@ pub(super) fn div_rem_digit(mut a: BigUint, b: BigDigit) -> (BigUint, BigDigit) let mut rem = 0; if b <= big_digit::HALF { - for d in a.data.iter_mut().rev() { + for d in a.data.to_mut().iter_mut().rev() { let (q, r) = div_half(rem, *d, b); *d = q; rem = r; } } else { - for d in a.data.iter_mut().rev() { + for d in a.data.to_mut().iter_mut().rev() { let (q, r) = div_wide(rem, *d, b); *d = q; rem = r; @@ -125,12 +126,15 @@ fn div_rem(mut u: BigUint, mut d: BigUint) -> (BigUint, BigUint) { } if d.data.len() == 1 { - if d.data == [1] { + if d.data[0] == 1 { return (u, Zero::zero()); } let (div, rem) = div_rem_digit(u, d.data[0]); // reuse d - d.data.clear(); + match &mut d.data { + Cow::Borrowed(v) => *v = &[], + Cow::Owned(v) => v.clear(), + } d += rem; return (div, d); } @@ -172,7 +176,7 @@ pub(super) fn div_rem_ref(u: &BigUint, d: &BigUint) -> (BigUint, BigUint) { } if d.data.len() == 1 { - if d.data == [1] { + if d.data[0] == 1 { return (u.clone(), Zero::zero()); } @@ -237,7 +241,7 @@ fn div_rem_core(mut a: BigUint, b: &[BigDigit]) -> (BigUint, BigUint) { let q_len = a.data.len() - b.len() + 1; let mut q = BigUint { - data: vec![0; q_len], + data: Cow::Owned(vec![0; q_len]), }; for j in (0..q_len).rev() { @@ -277,22 +281,22 @@ fn div_rem_core(mut a: BigUint, b: &[BigDigit]) -> (BigUint, BigUint) { // q0 is now either the correct quotient digit, or in rare cases 1 too large. // Subtract (q0 << j) from a. This may overflow, in which case we will have to correct. - let mut borrow = sub_mul_digit_same_len(&mut a.data[j..], b, q0); + let mut borrow = sub_mul_digit_same_len(&mut a.data.to_mut()[j..], b, q0); if borrow > a0 { // q0 is too large. We need to add back one multiple of b. q0 -= 1; - borrow -= __add2(&mut a.data[j..], b); + borrow -= __add2(&mut a.data.to_mut()[j..], b); } // The top digit of a, stored in a0, has now been zeroed. debug_assert!(borrow == a0); - q.data[j] = q0; + q.data.to_mut()[j] = q0; // Pop off the next top digit of a. - a0 = a.data.pop().unwrap(); + a0 = a.data.to_mut().pop().unwrap(); } - a.data.push(a0); + a.data.to_mut().push(a0); a.normalize(); debug_assert_eq!(cmp_slice(&a.data, b), Less); diff --git a/src/biguint/monty.rs b/src/biguint/monty.rs index abaca50c..fe4952af 100644 --- a/src/biguint/monty.rs +++ b/src/biguint/monty.rs @@ -5,6 +5,7 @@ use num_traits::{One, Zero}; use crate::big_digit::{self, BigDigit, DoubleBigDigit, SignedDoubleBigDigit}; use crate::biguint::BigUint; +use crate::std_alloc::Cow; struct MontyReducer { n0inv: BigDigit, @@ -57,16 +58,16 @@ fn montgomery(x: &BigUint, y: &BigUint, m: &BigUint, k: BigDigit, n: usize) -> B ); let mut z = BigUint::zero(); - z.data.resize(n * 2, 0); + z.data.to_mut().resize(n * 2, 0); let mut c: BigDigit = 0; for i in 0..n { - let c2 = add_mul_vvw(&mut z.data[i..n + i], &x.data, y.data[i]); + let c2 = add_mul_vvw(&mut z.data.to_mut()[i..n + i], &x.data, y.data[i]); let t = z.data[i].wrapping_mul(k); - let c3 = add_mul_vvw(&mut z.data[i..n + i], &m.data, t); + let c3 = add_mul_vvw(&mut z.data.to_mut()[i..n + i], &m.data, t); let cx = c.wrapping_add(c2); let cy = cx.wrapping_add(c3); - z.data[n + i] = cy; + z.data.to_mut()[n + i] = cy; if cx < c2 || cy < c3 { c = 1; } else { @@ -75,13 +76,13 @@ fn montgomery(x: &BigUint, y: &BigUint, m: &BigUint, k: BigDigit, n: usize) -> B } if c == 0 { - z.data = z.data[n..].to_vec(); + z.data = Cow::Owned(z.data[n..].to_vec()); } else { { - let (first, second) = z.data.split_at_mut(n); + let (first, second) = z.data.to_mut().split_at_mut(n); sub_vv(first, second, &m.data); } - z.data = z.data[..n].to_vec(); + z.data = Cow::Owned(z.data[..n].to_vec()); } z @@ -147,18 +148,18 @@ pub(super) fn monty_modpow(x: &BigUint, y: &BigUint, m: &BigUint) -> BigUint { // Note: now len(x) <= numWords, not guaranteed ==. } if x.data.len() < num_words { - x.data.resize(num_words, 0); + x.data.to_mut().resize(num_words, 0); } // rr = 2**(2*_W*len(m)) mod m let mut rr = BigUint::one(); rr = (rr.shl(2 * num_words as u64 * u64::from(big_digit::BITS))) % m; if rr.data.len() < num_words { - rr.data.resize(num_words, 0); + rr.data.to_mut().resize(num_words, 0); } // one = 1, with equal length to that of m let mut one = BigUint::one(); - one.data.resize(num_words, 0); + one.data.to_mut().resize(num_words, 0); let n = 4; // powers[i] contains x^i @@ -172,9 +173,9 @@ pub(super) fn monty_modpow(x: &BigUint, y: &BigUint, m: &BigUint) -> BigUint { // initialize z = 1 (Montgomery 1) let mut z = powers[0].clone(); - z.data.resize(num_words, 0); + z.data.to_mut().resize(num_words, 0); let mut zz = BigUint::zero(); - zz.data.resize(num_words, 0); + zz.data.to_mut().resize(num_words, 0); // same windowed exponent, but with Montgomery multiplications for i in (0..y.data.len()).rev() { diff --git a/src/biguint/multiplication.rs b/src/biguint/multiplication.rs index 4d7f1f21..ff952bd5 100644 --- a/src/biguint/multiplication.rs +++ b/src/biguint/multiplication.rs @@ -5,6 +5,7 @@ use super::u32_from_u128; use super::{biguint_from_vec, cmp_slice, BigUint, IntDigits}; use crate::big_digit::{self, BigDigit, DoubleBigDigit}; +use crate::std_alloc::Cow; use crate::Sign::{self, Minus, NoSign, Plus}; use crate::{BigInt, UsizePromotion}; @@ -175,10 +176,12 @@ fn mac3(mut acc: &mut [BigDigit], mut b: &[BigDigit], mut c: &[BigDigit]) { // We reuse the same BigUint for all the intermediate multiplies and have to size p // appropriately here: x1.len() >= x0.len and y1.len() >= y0.len(): let len = x1.len() + y1.len() + 1; - let mut p = BigUint { data: vec![0; len] }; + let mut p = BigUint { + data: Cow::Owned(vec![0; len]), + }; // p2 = x1 * y1 - mac3(&mut p.data, x1, y1); + mac3(&mut p.data.to_mut(), x1, y1); // Not required, but the adds go faster if we drop any unneeded 0s from the end: p.normalize(); @@ -187,11 +190,11 @@ fn mac3(mut acc: &mut [BigDigit], mut b: &[BigDigit], mut c: &[BigDigit]) { add2(&mut acc[b * 2..], &p.data); // Zero out p before the next multiply: - p.data.truncate(0); - p.data.resize(len, 0); + p.data.to_mut().truncate(0); + p.data.to_mut().resize(len, 0); // p0 = x0 * y0 - mac3(&mut p.data, x0, y0); + mac3(&mut p.data.to_mut(), x0, y0); p.normalize(); add2(acc, &p.data); @@ -204,10 +207,10 @@ fn mac3(mut acc: &mut [BigDigit], mut b: &[BigDigit], mut c: &[BigDigit]) { match j0_sign * j1_sign { Plus => { - p.data.truncate(0); - p.data.resize(len, 0); + p.data.to_mut().truncate(0); + p.data.to_mut().resize(len, 0); - mac3(&mut p.data, &j0.data, &j1.data); + mac3(&mut p.data.to_mut(), &j0.data, &j1.data); p.normalize(); sub2(&mut acc[b..], &p.data); @@ -351,9 +354,11 @@ fn mac3(mut acc: &mut [BigDigit], mut b: &[BigDigit], mut c: &[BigDigit]) { fn mul3(x: &[BigDigit], y: &[BigDigit]) -> BigUint { let len = x.len() + y.len() + 1; - let mut prod = BigUint { data: vec![0; len] }; + let mut prod = BigUint { + data: Cow::Owned(vec![0; len]), + }; - mac3(&mut prod.data, x, y); + mac3(&mut prod.data.to_mut(), x, y); prod.normalized() } @@ -366,11 +371,11 @@ fn scalar_mul(a: &mut BigUint, b: BigDigit) { *a <<= b.trailing_zeros(); } else { let mut carry = 0; - for a in a.data.iter_mut() { + for a in a.data.to_mut().iter_mut() { *a = mul_with_carry(*a, b, &mut carry); } if carry != 0 { - a.data.push(carry as BigDigit); + a.data.to_mut().push(carry as BigDigit); } } } diff --git a/src/biguint/shift.rs b/src/biguint/shift.rs index 00326bb5..27b9df1e 100644 --- a/src/biguint/shift.rs +++ b/src/biguint/shift.rs @@ -23,7 +23,7 @@ fn biguint_shl(n: Cow<'_, BigUint>, shift: T) -> BigUint { fn biguint_shl2(n: Cow<'_, BigUint>, digits: usize, shift: u8) -> BigUint { let mut data = match digits { - 0 => n.into_owned().data, + 0 => n.into_owned().data.into_owned(), _ => { let len = digits.saturating_add(n.data.len() + 1); let mut data = Vec::with_capacity(len); @@ -72,8 +72,8 @@ fn biguint_shr2(n: Cow<'_, BigUint>, digits: usize, shift: u8) -> BigUint { let mut data = match n { Cow::Borrowed(n) => n.data[digits..].to_vec(), Cow::Owned(mut n) => { - n.data.drain(..digits); - n.data + n.data.to_mut().drain(..digits); + n.data.into_owned() } }; diff --git a/src/biguint/subtraction.rs b/src/biguint/subtraction.rs index b7cf59dd..244592e0 100644 --- a/src/biguint/subtraction.rs +++ b/src/biguint/subtraction.rs @@ -118,7 +118,7 @@ impl Sub<&BigUint> for BigUint { } impl SubAssign<&BigUint> for BigUint { fn sub_assign(&mut self, other: &BigUint) { - sub2(&mut self.data[..], &other.data[..]); + sub2(&mut self.data.to_mut()[..], &other.data[..]); self.normalize(); } } @@ -129,13 +129,16 @@ impl Sub for &BigUint { fn sub(self, mut other: BigUint) -> BigUint { let other_len = other.data.len(); if other_len < self.data.len() { - let lo_borrow = __sub2rev(&self.data[..other_len], &mut other.data); - other.data.extend_from_slice(&self.data[other_len..]); + let lo_borrow = __sub2rev(&self.data[..other_len], &mut other.data.to_mut()); + other + .data + .to_mut() + .extend_from_slice(&self.data[other_len..]); if lo_borrow != 0 { - sub2(&mut other.data[other_len..], &[1]) + sub2(&mut other.data.to_mut()[other_len..], &[1]) } } else { - sub2rev(&self.data[..], &mut other.data[..]); + sub2rev(&self.data[..], &mut other.data.to_mut()[..]); } other.normalized() } @@ -159,7 +162,7 @@ impl Sub for BigUint { impl SubAssign for BigUint { fn sub_assign(&mut self, other: u32) { - sub2(&mut self.data[..], &[other as BigDigit]); + sub2(&mut self.data.to_mut()[..], &[other as BigDigit]); self.normalize(); } } @@ -182,9 +185,9 @@ impl Sub for u32 { #[inline] fn sub(self, mut other: BigUint) -> BigUint { if other.data.is_empty() { - other.data.push(self as BigDigit); + other.data.to_mut().push(self as BigDigit); } else { - sub2rev(&[self as BigDigit], &mut other.data[..]); + sub2rev(&[self as BigDigit], &mut other.data.to_mut()[..]); } other.normalized() } @@ -212,7 +215,7 @@ impl SubAssign for BigUint { #[cfg(u64_digit)] #[inline] fn sub_assign(&mut self, other: u64) { - sub2(&mut self.data[..], &[other as BigDigit]); + sub2(&mut self.data.to_mut()[..], &[other as BigDigit]); self.normalize(); } } @@ -236,9 +239,9 @@ impl Sub for u64 { #[inline] fn sub(self, mut other: BigUint) -> BigUint { if other.data.is_empty() { - other.data.push(self); + other.data.to_mut().push(self); } else { - sub2rev(&[self], &mut other.data[..]); + sub2rev(&[self], &mut other.data.to_mut()[..]); } other.normalized() } @@ -267,7 +270,7 @@ impl SubAssign for BigUint { #[inline] fn sub_assign(&mut self, other: u128) { let (hi, lo) = big_digit::from_doublebigdigit(other); - sub2(&mut self.data[..], &[lo, hi]); + sub2(&mut self.data.to_mut()[..], &[lo, hi]); self.normalize(); } } @@ -291,11 +294,11 @@ impl Sub for u128 { #[inline] fn sub(self, mut other: BigUint) -> BigUint { while other.data.len() < 2 { - other.data.push(0); + other.data.to_mut().push(0); } let (hi, lo) = big_digit::from_doublebigdigit(self); - sub2rev(&[lo, hi], &mut other.data[..]); + sub2rev(&[lo, hi], &mut other.data.to_mut()[..]); other.normalized() } }