Skip to content

Commit 8a610fb

Browse files
authored
Merge pull request #708 from tgross35/raskyld/master
fix(int): avoid infinite recursion on left shift #707
2 parents 96851fd + 87077a9 commit 8a610fb

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

Diff for: src/int/big.rs

+8
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ impl HInt for u128 {
222222
fn widen_mul(self, rhs: Self) -> Self::D {
223223
self.zero_widen_mul(rhs)
224224
}
225+
226+
fn widen_hi(self) -> Self::D {
227+
self.widen() << <Self as MinInt>::BITS
228+
}
225229
}
226230

227231
impl HInt for i128 {
@@ -247,6 +251,10 @@ impl HInt for i128 {
247251
fn widen_mul(self, rhs: Self) -> Self::D {
248252
unimplemented!("signed i128 widening multiply is not used")
249253
}
254+
255+
fn widen_hi(self) -> Self::D {
256+
self.widen() << <Self as MinInt>::BITS
257+
}
250258
}
251259

252260
impl DInt for u256 {

Diff for: src/int/mod.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -313,15 +313,17 @@ pub(crate) trait HInt: Int {
313313
/// Integer that is double the bit width of the integer this trait is implemented for
314314
type D: DInt<H = Self> + MinInt;
315315

316+
// NB: some of the below methods could have default implementations (e.g. `widen_hi`), but for
317+
// unknown reasons this can cause infinite recursion when optimizations are disabled. See
318+
// <https://github.com/rust-lang/compiler-builtins/pull/707> for context.
319+
316320
/// Widens (using default extension) the integer to have double bit width
317321
fn widen(self) -> Self::D;
318322
/// Widens (zero extension only) the integer to have double bit width. This is needed to get
319323
/// around problems with associated type bounds (such as `Int<Othersign: DInt>`) being unstable
320324
fn zero_widen(self) -> Self::D;
321325
/// Widens the integer to have double bit width and shifts the integer into the higher bits
322-
fn widen_hi(self) -> Self::D {
323-
self.widen() << <Self as MinInt>::BITS
324-
}
326+
fn widen_hi(self) -> Self::D;
325327
/// Widening multiplication with zero widening. This cannot overflow.
326328
fn zero_widen_mul(self, rhs: Self) -> Self::D;
327329
/// Widening multiplication. This cannot overflow.
@@ -364,6 +366,9 @@ macro_rules! impl_h_int {
364366
fn widen_mul(self, rhs: Self) -> Self::D {
365367
self.widen().wrapping_mul(rhs.widen())
366368
}
369+
fn widen_hi(self) -> Self::D {
370+
(self as $X) << <Self as MinInt>::BITS
371+
}
367372
}
368373
)*
369374
};

0 commit comments

Comments
 (0)