Skip to content

Commit 5012d7f

Browse files
committed
Auto merge of #57566 - Centril:const-stabilize-overflowing, r=alexreg
Const-stabilize `const_int_overflowing` Fixes #57237. r? @alexreg
2 parents 75a369c + b172e89 commit 5012d7f

File tree

6 files changed

+58
-30
lines changed

6 files changed

+58
-30
lines changed

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
#![feature(const_slice_len)]
115115
#![feature(const_str_as_bytes)]
116116
#![feature(const_str_len)]
117+
#![cfg_attr(stage0, feature(const_let))]
117118
#![cfg_attr(stage0, feature(const_int_rotate))]
118119
#![feature(const_int_conversion)]
119120
#![feature(const_transmute)]

src/libcore/num/bignum.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,37 @@ macro_rules! impl_full_ops {
4646
($($ty:ty: add($addfn:path), mul/div($bigty:ident);)*) => (
4747
$(
4848
impl FullOps for $ty {
49+
#[cfg(stage0)]
4950
fn full_add(self, other: $ty, carry: bool) -> (bool, $ty) {
50-
// this cannot overflow, the output is between 0 and 2*2^nbits - 1
51-
// FIXME will LLVM optimize this into ADC or similar???
51+
// This cannot overflow; the output is between `0` and `2 * 2^nbits - 1`.
52+
// FIXME: will LLVM optimize this into ADC or similar?
5253
let (v, carry1) = unsafe { intrinsics::add_with_overflow(self, other) };
5354
let (v, carry2) = unsafe {
5455
intrinsics::add_with_overflow(v, if carry {1} else {0})
5556
};
5657
(carry1 || carry2, v)
5758
}
59+
#[cfg(not(stage0))]
60+
fn full_add(self, other: $ty, carry: bool) -> (bool, $ty) {
61+
// This cannot overflow; the output is between `0` and `2 * 2^nbits - 1`.
62+
// FIXME: will LLVM optimize this into ADC or similar?
63+
let (v, carry1) = intrinsics::add_with_overflow(self, other);
64+
let (v, carry2) = intrinsics::add_with_overflow(v, if carry {1} else {0});
65+
(carry1 || carry2, v)
66+
}
5867

5968
fn full_mul(self, other: $ty, carry: $ty) -> ($ty, $ty) {
60-
// this cannot overflow, the output is between 0 and 2^nbits * (2^nbits - 1)
69+
// This cannot overflow;
70+
// the output is between `0` and `2^nbits * (2^nbits - 1)`.
71+
// FIXME: will LLVM optimize this into ADC or similar?
6172
let nbits = mem::size_of::<$ty>() * 8;
6273
let v = (self as $bigty) * (other as $bigty) + (carry as $bigty);
6374
((v >> nbits) as $ty, v as $ty)
6475
}
6576

6677
fn full_mul_add(self, other: $ty, other2: $ty, carry: $ty) -> ($ty, $ty) {
67-
// this cannot overflow, the output is between 0 and 2^(2*nbits) - 1
78+
// This cannot overflow;
79+
// the output is between `0` and `2^nbits * (2^nbits - 1)`.
6880
let nbits = mem::size_of::<$ty>() * 8;
6981
let v = (self as $bigty) * (other as $bigty) + (other2 as $bigty) +
7082
(carry as $bigty);
@@ -73,7 +85,7 @@ macro_rules! impl_full_ops {
7385

7486
fn full_div_rem(self, other: $ty, borrow: $ty) -> ($ty, $ty) {
7587
debug_assert!(borrow < other);
76-
// this cannot overflow, the dividend is between 0 and other * 2^nbits - 1
88+
// This cannot overflow; the output is between `0` and `other * (2^nbits - 1)`.
7789
let nbits = mem::size_of::<$ty>() * 8;
7890
let lhs = ((borrow as $bigty) << nbits) | (self as $bigty);
7991
let rhs = other as $bigty;
@@ -88,7 +100,8 @@ impl_full_ops! {
88100
u8: add(intrinsics::u8_add_with_overflow), mul/div(u16);
89101
u16: add(intrinsics::u16_add_with_overflow), mul/div(u32);
90102
u32: add(intrinsics::u32_add_with_overflow), mul/div(u64);
91-
// u64: add(intrinsics::u64_add_with_overflow), mul/div(u128); // see RFC #521 for enabling this.
103+
// See RFC #521 for enabling this.
104+
// u64: add(intrinsics::u64_add_with_overflow), mul/div(u128);
92105
}
93106

94107
/// Table of powers of 5 representable in digits. Specifically, the largest {u8, u16, u32} value

src/libcore/num/mod.rs

+34-22
Original file line numberDiff line numberDiff line change
@@ -1340,13 +1340,15 @@ assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (", stringify!($Sel
13401340
"::MIN, true));", $EndFeature, "
13411341
```"),
13421342
#[stable(feature = "wrapping", since = "1.7.0")]
1343-
#[rustc_const_unstable(feature = "const_int_overflowing")]
1343+
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
13441344
#[inline]
13451345
pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
1346+
#[cfg(stage0)]
13461347
let (a, b) = unsafe {
1347-
intrinsics::add_with_overflow(self as $ActualT,
1348-
rhs as $ActualT)
1348+
intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT)
13491349
};
1350+
#[cfg(not(stage0))]
1351+
let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
13501352
(a as Self, b)
13511353
}
13521354
}
@@ -1369,13 +1371,15 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_sub(1), (", stringify!($Sel
13691371
"::MAX, true));", $EndFeature, "
13701372
```"),
13711373
#[stable(feature = "wrapping", since = "1.7.0")]
1372-
#[rustc_const_unstable(feature = "const_int_overflowing")]
1374+
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
13731375
#[inline]
13741376
pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
1377+
#[cfg(stage0)]
13751378
let (a, b) = unsafe {
1376-
intrinsics::sub_with_overflow(self as $ActualT,
1377-
rhs as $ActualT)
1379+
intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT)
13781380
};
1381+
#[cfg(not(stage0))]
1382+
let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
13791383
(a as Self, b)
13801384
}
13811385
}
@@ -1396,13 +1400,15 @@ assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true));",
13961400
$EndFeature, "
13971401
```"),
13981402
#[stable(feature = "wrapping", since = "1.7.0")]
1399-
#[rustc_const_unstable(feature = "const_int_overflowing")]
1403+
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
14001404
#[inline]
14011405
pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
1406+
#[cfg(stage0)]
14021407
let (a, b) = unsafe {
1403-
intrinsics::mul_with_overflow(self as $ActualT,
1404-
rhs as $ActualT)
1408+
intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT)
14051409
};
1410+
#[cfg(not(stage0))]
1411+
let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
14061412
(a as Self, b)
14071413
}
14081414
}
@@ -1585,7 +1591,7 @@ assert_eq!(0x1i32.overflowing_shl(36), (0x10, true));",
15851591
$EndFeature, "
15861592
```"),
15871593
#[stable(feature = "wrapping", since = "1.7.0")]
1588-
#[rustc_const_unstable(feature = "const_int_overflowing")]
1594+
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
15891595
#[inline]
15901596
pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
15911597
(self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
@@ -1609,7 +1615,7 @@ assert_eq!(0x10i32.overflowing_shr(36), (0x1, true));",
16091615
$EndFeature, "
16101616
```"),
16111617
#[stable(feature = "wrapping", since = "1.7.0")]
1612-
#[rustc_const_unstable(feature = "const_int_overflowing")]
1618+
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
16131619
#[inline]
16141620
pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
16151621
(self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
@@ -3213,13 +3219,15 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));
32133219
assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));", $EndFeature, "
32143220
```"),
32153221
#[stable(feature = "wrapping", since = "1.7.0")]
3216-
#[rustc_const_unstable(feature = "const_int_overflowing")]
3222+
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
32173223
#[inline]
32183224
pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
3225+
#[cfg(stage0)]
32193226
let (a, b) = unsafe {
3220-
intrinsics::add_with_overflow(self as $ActualT,
3221-
rhs as $ActualT)
3227+
intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT)
32223228
};
3229+
#[cfg(not(stage0))]
3230+
let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
32233231
(a as Self, b)
32243232
}
32253233
}
@@ -3243,13 +3251,15 @@ assert_eq!(0", stringify!($SelfT), ".overflowing_sub(1), (", stringify!($SelfT),
32433251
$EndFeature, "
32443252
```"),
32453253
#[stable(feature = "wrapping", since = "1.7.0")]
3246-
#[rustc_const_unstable(feature = "const_int_overflowing")]
3254+
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
32473255
#[inline]
32483256
pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
3257+
#[cfg(stage0)]
32493258
let (a, b) = unsafe {
3250-
intrinsics::sub_with_overflow(self as $ActualT,
3251-
rhs as $ActualT)
3259+
intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT)
32523260
};
3261+
#[cfg(not(stage0))]
3262+
let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
32533263
(a as Self, b)
32543264
}
32553265
}
@@ -3272,13 +3282,15 @@ $EndFeature, "
32723282
/// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true));
32733283
/// ```
32743284
#[stable(feature = "wrapping", since = "1.7.0")]
3275-
#[rustc_const_unstable(feature = "const_int_overflowing")]
3285+
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
32763286
#[inline]
32773287
pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
3288+
#[cfg(stage0)]
32783289
let (a, b) = unsafe {
3279-
intrinsics::mul_with_overflow(self as $ActualT,
3280-
rhs as $ActualT)
3290+
intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT)
32813291
};
3292+
#[cfg(not(stage0))]
3293+
let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
32823294
(a as Self, b)
32833295
}
32843296

@@ -3436,7 +3448,7 @@ Basic usage
34363448
assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));", $EndFeature, "
34373449
```"),
34383450
#[stable(feature = "wrapping", since = "1.7.0")]
3439-
#[rustc_const_unstable(feature = "const_int_overflowing")]
3451+
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
34403452
#[inline]
34413453
pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
34423454
(self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
@@ -3461,7 +3473,7 @@ Basic usage
34613473
assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));", $EndFeature, "
34623474
```"),
34633475
#[stable(feature = "wrapping", since = "1.7.0")]
3464-
#[rustc_const_unstable(feature = "const_int_overflowing")]
3476+
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
34653477
#[inline]
34663478
pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
34673479
(self.wrapping_shr(rhs), (rhs > ($BITS - 1)))

src/librustc_mir/transform/qualify_min_const_fn.rs

+3
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ fn is_intrinsic_whitelisted(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool
374374
| "min_align_of"
375375
| "needs_drop"
376376
// Arithmetic:
377+
| "add_with_overflow" // ~> .overflowing_add
378+
| "sub_with_overflow" // ~> .overflowing_sub
379+
| "mul_with_overflow" // ~> .overflowing_mul
377380
| "overflowing_add" // ~> .wrapping_add
378381
| "overflowing_sub" // ~> .wrapping_sub
379382
| "overflowing_mul" // ~> .wrapping_mul

src/librustc_typeck/check/intrinsic.rs

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ fn equate_intrinsic_type<'a, 'tcx>(
7070
pub fn intrisic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
7171
match intrinsic {
7272
"size_of" | "min_align_of" | "needs_drop" |
73+
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" |
7374
"overflowing_add" | "overflowing_sub" | "overflowing_mul" |
7475
"rotate_left" | "rotate_right" |
7576
"ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse"

src/test/run-pass/const-int-overflowing.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(const_int_overflowing)]
2-
31
const ADD_A: (u32, bool) = 5u32.overflowing_add(2);
42
const ADD_B: (u32, bool) = u32::max_value().overflowing_add(1);
53

0 commit comments

Comments
 (0)