diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index f8888416f19..af13f413899 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -378,7 +378,9 @@ impl Power for U128 { } if exp == one { - return self; + // Manually clone `self`. Otherwise, we may have a `MemoryOverflow` + // issue with code that looks like: `x = x.pow(other)` + return U128::from((self.upper, self.lower)); } while exp & one == zero { diff --git a/sway-lib-std/src/u256.sw b/sway-lib-std/src/u256.sw index 002a636d578..19a69c03150 100644 --- a/sway-lib-std/src/u256.sw +++ b/sway-lib-std/src/u256.sw @@ -370,7 +370,9 @@ impl core::ops::Subtract for U256 { if self == other { return Self::min(); } else if other == Self::min() { - return self; + // Manually clone `self`. Otherwise, we may have a `MemoryOverflow` + // issue with code that looks like: `x = x - other` + return U256::from((self.a, self.b, self.c, self.d)); } // If trying to subtract a larger number, panic. assert(self > other); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_pow_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_pow_test/src/main.sw index 6abfff618b2..4d4e2887994 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_pow_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_pow_test/src/main.sw @@ -43,5 +43,10 @@ fn main() -> bool { pow_of_u_128 = u_128.pow(U128::from((0, 3))); assert(pow_of_u_128 == U128::from((0, 1728))); + // Test reassignment + u_128 = U128::from((0, 13)); + u_128 = u_128.pow(U128::from((0, 1))); + assert(u_128 == U128::from((0, 13))); + true -} \ No newline at end of file +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u256_ops_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u256_ops_test/src/main.sw index 4090c7a971d..45197593b21 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u256_ops_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u256_ops_test/src/main.sw @@ -4,7 +4,7 @@ use std::u256::U256; fn main() -> bool { let first = U256::from((0, 0, 0, 0)); - let second = U256::from((0, 0, 0, 1)); + let mut second = U256::from((0, 0, 0, 1)); let max_u64 = U256::from((0, 0, 0, u64::max())); let one = first + second; @@ -40,6 +40,13 @@ fn main() -> bool { assert(sub_max_again.c == 0); assert(sub_max_again.d == u64::max()); + // Test reassignment + second = second - U256::min(); + assert(second.a == 0); + assert(second.b == 0); + assert(second.c == 0); + assert(second.d == 1); + let zero_in_between = U256::from((0, 1, 0, 10)); let d_nonzero = U256::from((0, 0, 0, 12));