Skip to content

Commit f62b86b

Browse files
committed
requested changes
1 parent 7a20179 commit f62b86b

File tree

2 files changed

+59
-41
lines changed

2 files changed

+59
-41
lines changed

library/core/src/num/int_macros.rs

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,32 +1413,40 @@ macro_rules! int_impl {
14131413
}
14141414
}
14151415

1416-
/// Exact shift left. Computes `self << rhs`, returning `None` if any bits disagreeing with
1417-
/// the resulting sign bit would be shifted out.
1416+
/// Exact shift left. Computes `self << rhs` as long as it can be reversed losslessly.
1417+
///
1418+
/// Returns `None` if any bits that would be shifted out differ from the resulting sign bit
1419+
/// or if `rhs` >=
1420+
#[doc = concat!("`", stringify!($SelfT), "::BITS`.")]
1421+
/// Otherwise, returns `Some(self << rhs)`.
14181422
///
14191423
/// # Examples
14201424
///
14211425
/// ```
14221426
/// #![feature(exact_bitshifts)]
14231427
///
14241428
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".exact_shl(4), Some(0x10));")]
1425-
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".exact_shl(129), None);")]
1429+
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".exact_shl(", stringify!($SelfT), "::BITS - 2), Some(1 << ", stringify!($SelfT), "::BITS - 2));")]
1430+
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".exact_shl(", stringify!($SelfT), "::BITS - 1), None);")]
1431+
#[doc = concat!("assert_eq!((-0x2", stringify!($SelfT), ").exact_shl(", stringify!($SelfT), "::BITS - 2), Some(-0x2 << ", stringify!($SelfT), "::BITS - 2));")]
1432+
#[doc = concat!("assert_eq!((-0x2", stringify!($SelfT), ").exact_shl(", stringify!($SelfT), "::BITS - 1), None);")]
14261433
/// ```
14271434
#[unstable(feature = "exact_bitshifts", issue = "144336")]
14281435
#[must_use = "this returns the result of the operation, \
14291436
without modifying the original"]
14301437
#[inline]
1431-
pub fn exact_shl(self, rhs: u32) -> Option<$SelfT> {
1432-
if rhs < self.leading_zeros().max(self.leading_ones()) {
1438+
pub const fn exact_shl(self, rhs: u32) -> Option<$SelfT> {
1439+
if rhs < self.leading_zeros() || rhs < self.leading_ones() {
14331440
// SAFETY: rhs is checked above
14341441
Some(unsafe { self.unchecked_shl(rhs) })
14351442
} else {
14361443
None
14371444
}
14381445
}
14391446

1440-
/// Unchecked exact shift left. Computes `self << rhs`, assuming bits disagreeing with the
1441-
/// resulting sign bit cannot be shifted out.
1447+
/// Unchecked exact shift left. Computes `self << rhs`, assuming the operation can be
1448+
/// losslessly reversed and `rhs` cannot be larger than
1449+
#[doc = concat!("`", stringify!($SelfT), "::BITS`.")]
14421450
///
14431451
/// # Safety
14441452
///
@@ -1450,14 +1458,15 @@ macro_rules! int_impl {
14501458
#[must_use = "this returns the result of the operation, \
14511459
without modifying the original"]
14521460
#[inline]
1453-
pub unsafe fn exact_shl_unchecked(self, rhs: u32) -> $SelfT {
1461+
pub const unsafe fn unchecked_exact_shl(self, rhs: u32) -> $SelfT {
14541462
assert_unsafe_precondition!(
14551463
check_language_ub,
1456-
concat!(stringify!($SelfT), "::exact_shl_unchecked cannot shift out non-zero bits"),
1464+
concat!(stringify!($SelfT), "::unchecked_exact_shl cannot shift out non-zero bits"),
14571465
(
1458-
len: u32 = self.leading_zeros().max(self.leading_ones()),
1466+
zeros: u32 = self.leading_zeros(),
1467+
ones: u32 = self.leading_ones(),
14591468
rhs: u32 = rhs,
1460-
) => rhs < len,
1469+
) => rhs < zeros || rhs < ones,
14611470
);
14621471

14631472
// SAFETY: this is guaranteed to be safe by the caller
@@ -1585,33 +1594,35 @@ macro_rules! int_impl {
15851594
}
15861595
}
15871596

1588-
/// Exact shift right. Computes `self >> rhs`, returning `None` if any non-zero bits would be
1589-
/// shifted out or if `rhs` >=
1597+
/// Exact shift right. Computes `self >> rhs` as long as it can be reversed losslessly.
1598+
///
1599+
/// Returns `None` if any non-zero bits would be shifted out or if `rhs` >=
15901600
#[doc = concat!("`", stringify!($SelfT), "::BITS`.")]
1601+
/// Otherwise, returns `Some(self >> rhs)`.
15911602
///
15921603
/// # Examples
15931604
///
15941605
/// ```
15951606
/// #![feature(exact_bitshifts)]
15961607
///
15971608
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".exact_shr(4), Some(0x1));")]
1598-
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".exact_shr(129), None);")]
1609+
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".exact_shr(5), None);")]
15991610
/// ```
16001611
#[unstable(feature = "exact_bitshifts", issue = "144336")]
16011612
#[must_use = "this returns the result of the operation, \
16021613
without modifying the original"]
16031614
#[inline]
1604-
pub fn exact_shr(self, rhs: u32) -> Option<$SelfT> {
1605-
if rhs <= self.trailing_zeros().max(<$SelfT>::BITS - 1) {
1615+
pub const fn exact_shr(self, rhs: u32) -> Option<$SelfT> {
1616+
if rhs <= self.trailing_zeros() && rhs < <$SelfT>::BITS {
16061617
// SAFETY: rhs is checked above
16071618
Some(unsafe { self.unchecked_shr(rhs) })
16081619
} else {
16091620
None
16101621
}
16111622
}
16121623

1613-
/// Unchecked exact shift right. Computes `self >> rhs`, assuming non-zero bits cannot be
1614-
/// shifted out and `rhs` cannot be larger than
1624+
/// Unchecked exact shift right. Computes `self >> rhs`, assuming the operation can be
1625+
/// losslessly reversed and `rhs` cannot be larger than
16151626
#[doc = concat!("`", stringify!($SelfT), "::BITS`.")]
16161627
///
16171628
/// # Safety
@@ -1625,14 +1636,15 @@ macro_rules! int_impl {
16251636
#[must_use = "this returns the result of the operation, \
16261637
without modifying the original"]
16271638
#[inline]
1628-
pub unsafe fn exact_shr_unchecked(self, rhs: u32) -> $SelfT {
1639+
pub const unsafe fn unchecked_exact_shr(self, rhs: u32) -> $SelfT {
16291640
assert_unsafe_precondition!(
16301641
check_language_ub,
1631-
concat!(stringify!($SelfT), "::exact_shr_unchecked cannot shift out non-zero bits"),
1642+
concat!(stringify!($SelfT), "::unchecked_exact_shr cannot shift out non-zero bits"),
16321643
(
1633-
len: u32 = self.trailing_zeros().max(<$SelfT>::BITS - 1),
1644+
zeros: u32 = self.trailing_zeros(),
1645+
bits: u32 = <$SelfT>::BITS,
16341646
rhs: u32 = rhs,
1635-
) => rhs <= len,
1647+
) => rhs <= zeros && rhs < bits,
16361648
);
16371649

16381650
// SAFETY: this is guaranteed to be safe by the caller

library/core/src/num/uint_macros.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,9 +1734,11 @@ macro_rules! uint_impl {
17341734
}
17351735
}
17361736

1737-
/// Exact shift left. Computes `self << rhs`, returning `None` if any non-zero bits would be
1738-
/// shifted out or if `rhs` >=
1737+
/// Exact shift left. Computes `self << rhs` as long as it can be reversed losslessly.
1738+
///
1739+
/// Returns `None` if any non-zero bits would be shifted out or if `rhs` >=
17391740
#[doc = concat!("`", stringify!($SelfT), "::BITS`.")]
1741+
/// Otherwise, returns `Some(self << rhs)`.
17401742
///
17411743
/// # Examples
17421744
///
@@ -1750,17 +1752,17 @@ macro_rules! uint_impl {
17501752
#[must_use = "this returns the result of the operation, \
17511753
without modifying the original"]
17521754
#[inline]
1753-
pub fn exact_shl(self, rhs: u32) -> Option<$SelfT> {
1754-
if rhs <= self.leading_zeros().max(<$SelfT>::BITS - 1) {
1755+
pub const fn exact_shl(self, rhs: u32) -> Option<$SelfT> {
1756+
if rhs <= self.leading_zeros() && rhs < <$SelfT>::BITS {
17551757
// SAFETY: rhs is checked above
17561758
Some(unsafe { self.unchecked_shl(rhs) })
17571759
} else {
17581760
None
17591761
}
17601762
}
17611763

1762-
/// Unchecked exact shift left. Computes `self << rhs`, assuming non-zero bits cannot be
1763-
/// shifted out and `rhs` cannot be larger than
1764+
/// Unchecked exact shift left. Computes `self << rhs`, assuming the operation can be
1765+
/// losslessly reversed `rhs` cannot be larger than
17641766
#[doc = concat!("`", stringify!($SelfT), "::BITS`.")]
17651767
///
17661768
/// # Safety
@@ -1774,14 +1776,15 @@ macro_rules! uint_impl {
17741776
#[must_use = "this returns the result of the operation, \
17751777
without modifying the original"]
17761778
#[inline]
1777-
pub unsafe fn exact_shl_unchecked(self, rhs: u32) -> $SelfT {
1779+
pub const unsafe fn unchecked_exact_shl(self, rhs: u32) -> $SelfT {
17781780
assert_unsafe_precondition!(
17791781
check_language_ub,
17801782
concat!(stringify!($SelfT), "::exact_shl_unchecked cannot shift out non-zero bits"),
17811783
(
1782-
len: u32 = self.leading_zeros().max(<$SelfT>::BITS - 1),
1784+
zeros: u32 = self.leading_zeros(),
1785+
bits: u32 = <$SelfT>::BITS,
17831786
rhs: u32 = rhs,
1784-
) => rhs <= len,
1787+
) => rhs <= zeros && rhs < bits,
17851788
);
17861789

17871790
// SAFETY: this is guaranteed to be safe by the caller
@@ -1903,33 +1906,35 @@ macro_rules! uint_impl {
19031906
}
19041907
}
19051908

1906-
/// Exact shift right. Computes `self >> rhs`, returning `None` if any non-zero bits would be
1907-
/// shifted out or if `rhs` >=
1909+
/// Exact shift right. Computes `self >> rhs` as long as it can be reversed losslessly.
1910+
///
1911+
/// Returns `None` if any non-zero bits would be shifted out or if `rhs` >=
19081912
#[doc = concat!("`", stringify!($SelfT), "::BITS`.")]
1913+
/// Otherwise, returns `Some(self >> rhs)`.
19091914
///
19101915
/// # Examples
19111916
///
19121917
/// ```
19131918
/// #![feature(exact_bitshifts)]
19141919
///
19151920
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".exact_shr(4), Some(0x1));")]
1916-
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".exact_shr(129), None);")]
1921+
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".exact_shr(5), None);")]
19171922
/// ```
19181923
#[unstable(feature = "exact_bitshifts", issue = "144336")]
19191924
#[must_use = "this returns the result of the operation, \
19201925
without modifying the original"]
19211926
#[inline]
1922-
pub fn exact_shr(self, rhs: u32) -> Option<$SelfT> {
1923-
if rhs <= self.trailing_zeros().max(<$SelfT>::BITS - 1) {
1927+
pub const fn exact_shr(self, rhs: u32) -> Option<$SelfT> {
1928+
if rhs <= self.trailing_zeros() && rhs < <$SelfT>::BITS {
19241929
// SAFETY: rhs is checked above
19251930
Some(unsafe { self.unchecked_shr(rhs) })
19261931
} else {
19271932
None
19281933
}
19291934
}
19301935

1931-
/// Unchecked exact shift right. Computes `self >> rhs`, assuming non-zero bits cannot be
1932-
/// shifted out and `rhs` cannot be larger than
1936+
/// Unchecked exact shift right. Computes `self >> rhs`, assuming the operation can be
1937+
/// losslessly reversed and `rhs` cannot be larger than
19331938
#[doc = concat!("`", stringify!($SelfT), "::BITS`.")]
19341939
///
19351940
/// # Safety
@@ -1943,14 +1948,15 @@ macro_rules! uint_impl {
19431948
#[must_use = "this returns the result of the operation, \
19441949
without modifying the original"]
19451950
#[inline]
1946-
pub unsafe fn exact_shr_unchecked(self, rhs: u32) -> $SelfT {
1951+
pub const unsafe fn unchecked_exact_shr(self, rhs: u32) -> $SelfT {
19471952
assert_unsafe_precondition!(
19481953
check_language_ub,
19491954
concat!(stringify!($SelfT), "::exact_shr_unchecked cannot shift out non-zero bits"),
19501955
(
1951-
len: u32 = self.trailing_zeros().max(<$SelfT>::BITS - 1),
1956+
zeros: u32 = self.trailing_zeros(),
1957+
bits: u32 = <$SelfT>::BITS,
19521958
rhs: u32 = rhs,
1953-
) => rhs <= len,
1959+
) => rhs <= zeros && rhs < bits,
19541960
);
19551961

19561962
// SAFETY: this is guaranteed to be safe by the caller

0 commit comments

Comments
 (0)