Skip to content

Commit 3d2319f

Browse files
authored
Rollup merge of #108299 - scottmcm:literal-bits, r=Nilstrieb
Require `literal`s for some `(u)int_impl!` parameters The point of these is to be seen *lexically* in the docs, so they should always be passed as the correct literal, not as an expression. (Otherwise we could just compute `Min`/`Max` from `BITS`, for example.) r? Nilstrieb
2 parents 2bc553c + 5c7ae25 commit 3d2319f

File tree

2 files changed

+46
-36
lines changed

2 files changed

+46
-36
lines changed

library/core/src/num/int_macros.rs

+25-20
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,26 @@ macro_rules! int_impl {
33
Self = $SelfT:ty,
44
ActualT = $ActualT:ident,
55
UnsignedT = $UnsignedT:ty,
6-
BITS = $BITS:expr,
7-
BITS_MINUS_ONE = $BITS_MINUS_ONE:expr,
8-
Min = $Min:expr,
9-
Max = $Max:expr,
10-
rot = $rot:expr,
11-
rot_op = $rot_op:expr,
12-
rot_result = $rot_result:expr,
13-
swap_op = $swap_op:expr,
14-
swapped = $swapped:expr,
15-
reversed = $reversed:expr,
16-
le_bytes = $le_bytes:expr,
17-
be_bytes = $be_bytes:expr,
6+
7+
// There are all for use *only* in doc comments.
8+
// As such, they're all passed as literals -- passing them as a string
9+
// literal is fine if they need to be multiple code tokens.
10+
// In non-comments, use the associated constants rather than these.
11+
BITS = $BITS:literal,
12+
BITS_MINUS_ONE = $BITS_MINUS_ONE:literal,
13+
Min = $Min:literal,
14+
Max = $Max:literal,
15+
rot = $rot:literal,
16+
rot_op = $rot_op:literal,
17+
rot_result = $rot_result:literal,
18+
swap_op = $swap_op:literal,
19+
swapped = $swapped:literal,
20+
reversed = $reversed:literal,
21+
le_bytes = $le_bytes:literal,
22+
be_bytes = $be_bytes:literal,
1823
to_xe_bytes_doc = $to_xe_bytes_doc:expr,
1924
from_xe_bytes_doc = $from_xe_bytes_doc:expr,
20-
bound_condition = $bound_condition:expr,
25+
bound_condition = $bound_condition:literal,
2126
) => {
2227
/// The smallest value that can be represented by this integer type
2328
#[doc = concat!("(&minus;2<sup>", $BITS_MINUS_ONE, "</sup>", $bound_condition, ").")]
@@ -30,7 +35,7 @@ macro_rules! int_impl {
3035
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN, ", stringify!($Min), ");")]
3136
/// ```
3237
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
33-
pub const MIN: Self = !0 ^ ((!0 as $UnsignedT) >> 1) as Self;
38+
pub const MIN: Self = !Self::MAX;
3439

3540
/// The largest value that can be represented by this integer type
3641
#[doc = concat!("(2<sup>", $BITS_MINUS_ONE, "</sup> &minus; 1", $bound_condition, ").")]
@@ -43,7 +48,7 @@ macro_rules! int_impl {
4348
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($Max), ");")]
4449
/// ```
4550
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
46-
pub const MAX: Self = !Self::MIN;
51+
pub const MAX: Self = (<$UnsignedT>::MAX >> 1) as Self;
4752

4853
/// The size of this integer type in bits.
4954
///
@@ -53,7 +58,7 @@ macro_rules! int_impl {
5358
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")]
5459
/// ```
5560
#[stable(feature = "int_bits_const", since = "1.53.0")]
56-
pub const BITS: u32 = $BITS;
61+
pub const BITS: u32 = <$UnsignedT>::BITS;
5762

5863
/// Converts a string slice in a given base to an integer.
5964
///
@@ -1380,7 +1385,7 @@ macro_rules! int_impl {
13801385
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
13811386
// out of bounds
13821387
unsafe {
1383-
self.unchecked_shl(rhs & ($BITS - 1))
1388+
self.unchecked_shl(rhs & (Self::BITS - 1))
13841389
}
13851390
}
13861391

@@ -1410,7 +1415,7 @@ macro_rules! int_impl {
14101415
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
14111416
// out of bounds
14121417
unsafe {
1413-
self.unchecked_shr(rhs & ($BITS - 1))
1418+
self.unchecked_shr(rhs & (Self::BITS - 1))
14141419
}
14151420
}
14161421

@@ -1916,7 +1921,7 @@ macro_rules! int_impl {
19161921
without modifying the original"]
19171922
#[inline]
19181923
pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
1919-
(self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
1924+
(self.wrapping_shl(rhs), rhs >= Self::BITS)
19201925
}
19211926

19221927
/// Shifts self right by `rhs` bits.
@@ -1939,7 +1944,7 @@ macro_rules! int_impl {
19391944
without modifying the original"]
19401945
#[inline]
19411946
pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
1942-
(self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
1947+
(self.wrapping_shr(rhs), rhs >= Self::BITS)
19431948
}
19441949

19451950
/// Computes the absolute value of `self`.

library/core/src/num/uint_macros.rs

+21-16
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,24 @@ macro_rules! uint_impl {
44
ActualT = $ActualT:ident,
55
SignedT = $SignedT:ident,
66
NonZeroT = $NonZeroT:ident,
7-
BITS = $BITS:expr,
8-
MAX = $MaxV:expr,
9-
rot = $rot:expr,
10-
rot_op = $rot_op:expr,
11-
rot_result = $rot_result:expr,
12-
swap_op = $swap_op:expr,
13-
swapped = $swapped:expr,
14-
reversed = $reversed:expr,
15-
le_bytes = $le_bytes:expr,
16-
be_bytes = $be_bytes:expr,
7+
8+
// There are all for use *only* in doc comments.
9+
// As such, they're all passed as literals -- passing them as a string
10+
// literal is fine if they need to be multiple code tokens.
11+
// In non-comments, use the associated constants rather than these.
12+
BITS = $BITS:literal,
13+
MAX = $MaxV:literal,
14+
rot = $rot:literal,
15+
rot_op = $rot_op:literal,
16+
rot_result = $rot_result:literal,
17+
swap_op = $swap_op:literal,
18+
swapped = $swapped:literal,
19+
reversed = $reversed:literal,
20+
le_bytes = $le_bytes:literal,
21+
be_bytes = $be_bytes:literal,
1722
to_xe_bytes_doc = $to_xe_bytes_doc:expr,
1823
from_xe_bytes_doc = $from_xe_bytes_doc:expr,
19-
bound_condition = $bound_condition:expr,
24+
bound_condition = $bound_condition:literal,
2025
) => {
2126
/// The smallest value that can be represented by this integer type.
2227
///
@@ -51,7 +56,7 @@ macro_rules! uint_impl {
5156
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")]
5257
/// ```
5358
#[stable(feature = "int_bits_const", since = "1.53.0")]
54-
pub const BITS: u32 = $BITS;
59+
pub const BITS: u32 = Self::MAX.count_ones();
5560

5661
/// Converts a string slice in a given base to an integer.
5762
///
@@ -1403,7 +1408,7 @@ macro_rules! uint_impl {
14031408
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
14041409
// out of bounds
14051410
unsafe {
1406-
self.unchecked_shl(rhs & ($BITS - 1))
1411+
self.unchecked_shl(rhs & (Self::BITS - 1))
14071412
}
14081413
}
14091414

@@ -1436,7 +1441,7 @@ macro_rules! uint_impl {
14361441
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
14371442
// out of bounds
14381443
unsafe {
1439-
self.unchecked_shr(rhs & ($BITS - 1))
1444+
self.unchecked_shr(rhs & (Self::BITS - 1))
14401445
}
14411446
}
14421447

@@ -1860,7 +1865,7 @@ macro_rules! uint_impl {
18601865
without modifying the original"]
18611866
#[inline(always)]
18621867
pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
1863-
(self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
1868+
(self.wrapping_shl(rhs), rhs >= Self::BITS)
18641869
}
18651870

18661871
/// Shifts self right by `rhs` bits.
@@ -1885,7 +1890,7 @@ macro_rules! uint_impl {
18851890
without modifying the original"]
18861891
#[inline(always)]
18871892
pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
1888-
(self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
1893+
(self.wrapping_shr(rhs), rhs >= Self::BITS)
18891894
}
18901895

18911896
/// Raises self to the power of `exp`, using exponentiation by squaring.

0 commit comments

Comments
 (0)