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.)
This commit is contained in:
Scott McMurray 2023-02-20 23:56:04 -08:00
parent f715e430aa
commit 5c7ae251b1
2 changed files with 46 additions and 36 deletions

View File

@ -3,21 +3,26 @@ macro_rules! int_impl {
Self = $SelfT:ty, Self = $SelfT:ty,
ActualT = $ActualT:ident, ActualT = $ActualT:ident,
UnsignedT = $UnsignedT:ty, UnsignedT = $UnsignedT:ty,
BITS = $BITS:expr,
BITS_MINUS_ONE = $BITS_MINUS_ONE:expr, // There are all for use *only* in doc comments.
Min = $Min:expr, // As such, they're all passed as literals -- passing them as a string
Max = $Max:expr, // literal is fine if they need to be multiple code tokens.
rot = $rot:expr, // In non-comments, use the associated constants rather than these.
rot_op = $rot_op:expr, BITS = $BITS:literal,
rot_result = $rot_result:expr, BITS_MINUS_ONE = $BITS_MINUS_ONE:literal,
swap_op = $swap_op:expr, Min = $Min:literal,
swapped = $swapped:expr, Max = $Max:literal,
reversed = $reversed:expr, rot = $rot:literal,
le_bytes = $le_bytes:expr, rot_op = $rot_op:literal,
be_bytes = $be_bytes:expr, rot_result = $rot_result:literal,
swap_op = $swap_op:literal,
swapped = $swapped:literal,
reversed = $reversed:literal,
le_bytes = $le_bytes:literal,
be_bytes = $be_bytes:literal,
to_xe_bytes_doc = $to_xe_bytes_doc:expr, to_xe_bytes_doc = $to_xe_bytes_doc:expr,
from_xe_bytes_doc = $from_xe_bytes_doc:expr, from_xe_bytes_doc = $from_xe_bytes_doc:expr,
bound_condition = $bound_condition:expr, bound_condition = $bound_condition:literal,
) => { ) => {
/// The smallest value that can be represented by this integer type /// The smallest value that can be represented by this integer type
#[doc = concat!("(&minus;2<sup>", $BITS_MINUS_ONE, "</sup>", $bound_condition, ").")] #[doc = concat!("(&minus;2<sup>", $BITS_MINUS_ONE, "</sup>", $bound_condition, ").")]
@ -30,7 +35,7 @@ macro_rules! int_impl {
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN, ", stringify!($Min), ");")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN, ", stringify!($Min), ");")]
/// ``` /// ```
#[stable(feature = "assoc_int_consts", since = "1.43.0")] #[stable(feature = "assoc_int_consts", since = "1.43.0")]
pub const MIN: Self = !0 ^ ((!0 as $UnsignedT) >> 1) as Self; pub const MIN: Self = !Self::MAX;
/// The largest value that can be represented by this integer type /// The largest value that can be represented by this integer type
#[doc = concat!("(2<sup>", $BITS_MINUS_ONE, "</sup> &minus; 1", $bound_condition, ").")] #[doc = concat!("(2<sup>", $BITS_MINUS_ONE, "</sup> &minus; 1", $bound_condition, ").")]
@ -43,7 +48,7 @@ macro_rules! int_impl {
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($Max), ");")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($Max), ");")]
/// ``` /// ```
#[stable(feature = "assoc_int_consts", since = "1.43.0")] #[stable(feature = "assoc_int_consts", since = "1.43.0")]
pub const MAX: Self = !Self::MIN; pub const MAX: Self = (<$UnsignedT>::MAX >> 1) as Self;
/// The size of this integer type in bits. /// The size of this integer type in bits.
/// ///
@ -53,7 +58,7 @@ macro_rules! int_impl {
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")]
/// ``` /// ```
#[stable(feature = "int_bits_const", since = "1.53.0")] #[stable(feature = "int_bits_const", since = "1.53.0")]
pub const BITS: u32 = $BITS; pub const BITS: u32 = <$UnsignedT>::BITS;
/// Converts a string slice in a given base to an integer. /// Converts a string slice in a given base to an integer.
/// ///
@ -1380,7 +1385,7 @@ macro_rules! int_impl {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift // SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds // out of bounds
unsafe { unsafe {
self.unchecked_shl(rhs & ($BITS - 1)) self.unchecked_shl(rhs & (Self::BITS - 1))
} }
} }
@ -1410,7 +1415,7 @@ macro_rules! int_impl {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift // SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds // out of bounds
unsafe { unsafe {
self.unchecked_shr(rhs & ($BITS - 1)) self.unchecked_shr(rhs & (Self::BITS - 1))
} }
} }
@ -1916,7 +1921,7 @@ macro_rules! int_impl {
without modifying the original"] without modifying the original"]
#[inline] #[inline]
pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) { pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shl(rhs), (rhs > ($BITS - 1))) (self.wrapping_shl(rhs), rhs >= Self::BITS)
} }
/// Shifts self right by `rhs` bits. /// Shifts self right by `rhs` bits.
@ -1939,7 +1944,7 @@ macro_rules! int_impl {
without modifying the original"] without modifying the original"]
#[inline] #[inline]
pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) { pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shr(rhs), (rhs > ($BITS - 1))) (self.wrapping_shr(rhs), rhs >= Self::BITS)
} }
/// Computes the absolute value of `self`. /// Computes the absolute value of `self`.

View File

@ -4,19 +4,24 @@ macro_rules! uint_impl {
ActualT = $ActualT:ident, ActualT = $ActualT:ident,
SignedT = $SignedT:ident, SignedT = $SignedT:ident,
NonZeroT = $NonZeroT:ident, NonZeroT = $NonZeroT:ident,
BITS = $BITS:expr,
MAX = $MaxV:expr, // There are all for use *only* in doc comments.
rot = $rot:expr, // As such, they're all passed as literals -- passing them as a string
rot_op = $rot_op:expr, // literal is fine if they need to be multiple code tokens.
rot_result = $rot_result:expr, // In non-comments, use the associated constants rather than these.
swap_op = $swap_op:expr, BITS = $BITS:literal,
swapped = $swapped:expr, MAX = $MaxV:literal,
reversed = $reversed:expr, rot = $rot:literal,
le_bytes = $le_bytes:expr, rot_op = $rot_op:literal,
be_bytes = $be_bytes:expr, rot_result = $rot_result:literal,
swap_op = $swap_op:literal,
swapped = $swapped:literal,
reversed = $reversed:literal,
le_bytes = $le_bytes:literal,
be_bytes = $be_bytes:literal,
to_xe_bytes_doc = $to_xe_bytes_doc:expr, to_xe_bytes_doc = $to_xe_bytes_doc:expr,
from_xe_bytes_doc = $from_xe_bytes_doc:expr, from_xe_bytes_doc = $from_xe_bytes_doc:expr,
bound_condition = $bound_condition:expr, bound_condition = $bound_condition:literal,
) => { ) => {
/// The smallest value that can be represented by this integer type. /// The smallest value that can be represented by this integer type.
/// ///
@ -51,7 +56,7 @@ macro_rules! uint_impl {
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")]
/// ``` /// ```
#[stable(feature = "int_bits_const", since = "1.53.0")] #[stable(feature = "int_bits_const", since = "1.53.0")]
pub const BITS: u32 = $BITS; pub const BITS: u32 = Self::MAX.count_ones();
/// Converts a string slice in a given base to an integer. /// Converts a string slice in a given base to an integer.
/// ///
@ -1403,7 +1408,7 @@ macro_rules! uint_impl {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift // SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds // out of bounds
unsafe { unsafe {
self.unchecked_shl(rhs & ($BITS - 1)) self.unchecked_shl(rhs & (Self::BITS - 1))
} }
} }
@ -1436,7 +1441,7 @@ macro_rules! uint_impl {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift // SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds // out of bounds
unsafe { unsafe {
self.unchecked_shr(rhs & ($BITS - 1)) self.unchecked_shr(rhs & (Self::BITS - 1))
} }
} }
@ -1860,7 +1865,7 @@ macro_rules! uint_impl {
without modifying the original"] without modifying the original"]
#[inline(always)] #[inline(always)]
pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) { pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shl(rhs), (rhs > ($BITS - 1))) (self.wrapping_shl(rhs), rhs >= Self::BITS)
} }
/// Shifts self right by `rhs` bits. /// Shifts self right by `rhs` bits.
@ -1885,7 +1890,7 @@ macro_rules! uint_impl {
without modifying the original"] without modifying the original"]
#[inline(always)] #[inline(always)]
pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) { pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shr(rhs), (rhs > ($BITS - 1))) (self.wrapping_shr(rhs), rhs >= Self::BITS)
} }
/// Raises self to the power of `exp`, using exponentiation by squaring. /// Raises self to the power of `exp`, using exponentiation by squaring.