fix(int): avoid infinite recursion on left shift

Please, see this discussion for the full
context: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/.5Bwasm32.5D.20Infinite.20recursion.20.60compiler-builtins.60.20.60__multi3.60

Signed-off-by: Enzo "raskyld" Nocera <enzo@nocera.eu>

We determined that some recursion problems on SPARC and WASM were due to
infinite recusion. This was introduced at 9c6fcb56e8 ("Split Int into
Int and MinInt") when moving the implementation of `widen_hi` from
something on each `impl` block to a default on the trait. The reasoning
is not fully understood, but undoing this portion of the change seems to
resolve the issue.

[ add the above context - Trevor ]

Signed-off-by: Trevor Gross <tmgross@umich.edu>
This commit is contained in:
Enzo "raskyld" Nocera 2024-10-06 03:45:06 +02:00 committed by Trevor Gross
parent d150d472fe
commit 8153729f91
2 changed files with 12 additions and 3 deletions

View file

@ -222,6 +222,10 @@ impl HInt for u128 {
fn widen_mul(self, rhs: Self) -> Self::D {
self.zero_widen_mul(rhs)
}
fn widen_hi(self) -> Self::D {
self.widen() << <Self as MinInt>::BITS
}
}
impl HInt for i128 {
@ -247,6 +251,10 @@ impl HInt for i128 {
fn widen_mul(self, rhs: Self) -> Self::D {
unimplemented!("signed i128 widening multiply is not used")
}
fn widen_hi(self) -> Self::D {
self.widen() << <Self as MinInt>::BITS
}
}
impl DInt for u256 {

View file

@ -319,9 +319,7 @@ pub(crate) trait HInt: Int {
/// around problems with associated type bounds (such as `Int<Othersign: DInt>`) being unstable
fn zero_widen(self) -> Self::D;
/// Widens the integer to have double bit width and shifts the integer into the higher bits
fn widen_hi(self) -> Self::D {
self.widen() << <Self as MinInt>::BITS
}
fn widen_hi(self) -> Self::D;
/// Widening multiplication with zero widening. This cannot overflow.
fn zero_widen_mul(self, rhs: Self) -> Self::D;
/// Widening multiplication. This cannot overflow.
@ -364,6 +362,9 @@ macro_rules! impl_h_int {
fn widen_mul(self, rhs: Self) -> Self::D {
self.widen().wrapping_mul(rhs.widen())
}
fn widen_hi(self) -> Self::D {
(self as $X) << <Self as MinInt>::BITS
}
}
)*
};