Skip to content

Commit 5c7ae25

Browse files
committed
Require literals 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.)
1 parent f715e43 commit 5c7ae25

File tree

2 files changed

+46
-36
lines changed

2 files changed

+46
-36
lines changed

library/core/src/num/int_macros.rs

Lines changed: 25 additions & 20 deletions
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

Lines changed: 21 additions & 16 deletions
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)