Auto merge of #138492 - lcnr:rm-inline_const_pat, r=oli-obk

remove `feature(inline_const_pat)`

Summarizing https://rust-lang.zulipchat.com/#narrow/channel/144729-t-types/topic/remove.20feature.28inline_const_pat.29.20and.20shared.20borrowck.

With https://github.com/rust-lang/types-team/issues/129 we will start to borrowck items together with their typeck parent. This is necessary to correctly support opaque types, blocking the new solver and TAIT/ATPIT stabilization with the old one. This means that we cannot really support `inline_const_pat` as they are implemented right now:

- we want to typeck inline consts together with their parent body to allow inference to flow both ways and to allow the const to refer to local regions of its parent.This means we also need to borrowck the inline const together with its parent as that's necessary to properly support opaque types
- we want the inline const pattern to participate in exhaustiveness checking
- to participate in exhaustiveness checking we need to evaluate it, which requires borrowck, which now relies on borrowck of the typeck root, which ends up checking exhaustiveness again. **This is a query cycle**.

There are 4 possible ways to handle this:
- stop typechecking inline const patterns together with their parent
  - causes inline const patterns to be different than inline const exprs
  - prevents bidirectional inference, we need to either fail to compile `if let const { 1 } = 1u32` or `if let const { 1u32 } = 1`
  - region inference for inline consts will be harder, it feels non-trivial to support inline consts referencing local regions from the parent fn
- inline consts no longer participate in exhaustiveness checking. Treat them like `pat if pat == const { .. }`  instead. We then only evaluate them after borrowck
  - difference between `const { 1 }`  and `const FOO: usize = 1; match x { FOO => () }`. This is confusing
  - do they carry their weight if they are now just equivalent to using an if-guard
- delay exhaustiveness checking until after borrowck
  - should be possible in theory, but is a quite involved change and may have some unexpected challenges
- remove this feature for now

I believe we should either delay exhaustiveness checking or remove the feature entirely. As moving exhaustiveness checking to after borrow checking is quite complex I think the right course of action is to fully remove the feature for now and to add it again once/if we've got that implementation figured out.

`const { .. }`-expressions remain stable. These seem to have been the main motivation for https://github.com/rust-lang/rfcs/issues/2920.

r? types

cc `@rust-lang/types` `@rust-lang/lang` #76001
This commit is contained in:
bors 2025-04-01 14:20:46 +00:00
commit 0b4a81a4ef
59 changed files with 717 additions and 1489 deletions

View file

@ -490,7 +490,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
half_open_range_patterns_in_slices,
"half-open range patterns in slices are unstable"
);
gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
gate_all!(associated_const_equality, "associated const equality is incomplete");
gate_all!(yeet_expr, "`do yeet` expression is experimental");
gate_all!(dyn_star, "`dyn*` trait objects are experimental");

View file

@ -142,6 +142,9 @@ declare_features! (
/// Allows inferring `'static` outlives requirements (RFC 2093).
(removed, infer_static_outlives_requirements, "1.63.0", Some(54185),
Some("removed as it caused some confusion and discussion was inactive for years")),
/// Allow anonymous constants from an inline `const` block in pattern position
(removed, inline_const_pat, "CURRENT_RUSTC_VERSION", Some(76001),
Some("removed due to implementation concerns as it requires significant refactorings")),
/// Lazily evaluate constants. This allows constants to depend on type parameters.
(removed, lazy_normalization_consts, "1.46.0", Some(72219), Some("superseded by `generic_const_exprs`")),
/// Changes `impl Trait` to capture all lifetimes in scope.

View file

@ -531,8 +531,6 @@ declare_features! (
(unstable, import_trait_associated_functions, "1.86.0", Some(134691)),
/// Allows associated types in inherent impls.
(incomplete, inherent_associated_types, "1.52.0", Some(8995)),
/// Allow anonymous constants from an inline `const` block in pattern position
(unstable, inline_const_pat, "1.58.0", Some(76001)),
/// Allows using `pointer` and `reference` in intra-doc links
(unstable, intra_doc_pointers, "1.51.0", Some(80896)),
// Allows using the `kl` and `widekl` target features and the associated intrinsics

View file

@ -838,8 +838,6 @@ parse_unexpected_expr_in_pat_const_sugg = consider extracting the expression int
parse_unexpected_expr_in_pat_create_guard_sugg = consider moving the expression to a match arm guard
parse_unexpected_expr_in_pat_inline_const_sugg = consider wrapping the expression in an inline `const` (requires `{"#"}![feature(inline_const_pat)]`)
parse_unexpected_expr_in_pat_update_guard_sugg = consider moving the expression to the match arm guard
parse_unexpected_if_with_if = unexpected `if` in the condition expression

View file

@ -2769,17 +2769,6 @@ pub(crate) enum UnexpectedExpressionInPatternSugg {
/// The statement's block's indentation.
indentation: String,
},
#[multipart_suggestion(
parse_unexpected_expr_in_pat_inline_const_sugg,
applicability = "maybe-incorrect"
)]
InlineConst {
#[suggestion_part(code = "const {{ ")]
start_span: Span,
#[suggestion_part(code = " }}")]
end_span: Span,
},
}
#[derive(Diagnostic)]

View file

@ -1370,9 +1370,6 @@ impl<'a> Parser<'a> {
/// Parses inline const expressions.
fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, P<Expr>> {
if pat {
self.psess.gated_spans.gate(sym::inline_const_pat, span);
}
self.expect_keyword(exp!(Const))?;
let (attrs, blk) = self.parse_inner_attrs_and_block(None)?;
let anon_const = AnonConst {
@ -1380,7 +1377,17 @@ impl<'a> Parser<'a> {
value: self.mk_expr(blk.span, ExprKind::Block(blk, None)),
};
let blk_span = anon_const.value.span;
Ok(self.mk_expr_with_attrs(span.to(blk_span), ExprKind::ConstBlock(anon_const), attrs))
let kind = if pat {
let guar = self
.dcx()
.struct_span_err(blk_span, "`inline_const_pat` has been removed")
.with_help("use a named `const`-item or an `if`-guard instead")
.emit();
ExprKind::Err(guar)
} else {
ExprKind::ConstBlock(anon_const)
};
Ok(self.mk_expr_with_attrs(span.to(blk_span), kind, attrs))
}
/// Parses mutability (`mut` or nothing).

View file

@ -631,15 +631,6 @@ impl<'a> Parser<'a> {
ident,
indentation,
});
// help: wrap the expr in a `const { expr }`
// FIXME(inline_const_pat): once stabilized, remove this check and remove the `(requires #[feature(inline_const_pat)])` note from the message
if self.parser.psess.unstable_features.is_nightly_build() {
err.subdiagnostic(UnexpectedExpressionInPatternSugg::InlineConst {
start_span: expr_span.shrink_to_lo(),
end_span: expr_span.shrink_to_hi(),
});
}
},
);
}

View file

@ -39,7 +39,6 @@
#![feature(generic_assert_internals)]
#![feature(hasher_prefixfree_extras)]
#![feature(hashmap_internals)]
#![feature(inline_const_pat)]
#![feature(int_roundings)]
#![feature(ip)]
#![feature(ip_from)]
@ -95,16 +94,17 @@
/// Version of `assert_matches` that ignores fancy runtime printing in const context and uses structural equality.
macro_rules! assert_eq_const_safe {
($left:expr, $right:expr) => {
assert_eq_const_safe!($left, $right, concat!(stringify!($left), " == ", stringify!($right)));
($t:ty: $left:expr, $right:expr) => {
assert_eq_const_safe!($t: $left, $right, concat!(stringify!($left), " == ", stringify!($right)));
};
($left:expr, $right:expr$(, $($arg:tt)+)?) => {
($t:ty: $left:expr, $right:expr$(, $($arg:tt)+)?) => {
{
fn runtime() {
assert_eq!($left, $right, $($($arg)*),*);
}
const fn compiletime() {
assert!(matches!($left, const { $right }));
const PAT: $t = $right;
assert!(matches!($left, PAT), $($($arg)*),*);
}
core::intrinsics::const_eval_select((), compiletime, runtime)
}

View file

@ -1,5 +1,6 @@
macro_rules! int_module {
($T:ident, $U:ident) => {
use core::num::ParseIntError;
use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
use core::$T::*;
@ -32,20 +33,20 @@ macro_rules! int_module {
test_runtime_and_compiletime! {
fn test_rem_euclid() {
assert_eq_const_safe!((-1 as $T).rem_euclid(MIN), MAX);
assert_eq_const_safe!($T: (-1 as $T).rem_euclid(MIN), MAX);
}
fn test_abs() {
assert_eq_const_safe!((1 as $T).abs(), 1 as $T);
assert_eq_const_safe!((0 as $T).abs(), 0 as $T);
assert_eq_const_safe!((-1 as $T).abs(), 1 as $T);
assert_eq_const_safe!($T: (1 as $T).abs(), 1 as $T);
assert_eq_const_safe!($T: (0 as $T).abs(), 0 as $T);
assert_eq_const_safe!($T: (-1 as $T).abs(), 1 as $T);
}
fn test_signum() {
assert_eq_const_safe!((1 as $T).signum(), 1 as $T);
assert_eq_const_safe!((0 as $T).signum(), 0 as $T);
assert_eq_const_safe!((-0 as $T).signum(), 0 as $T);
assert_eq_const_safe!((-1 as $T).signum(), -1 as $T);
assert_eq_const_safe!($T: (1 as $T).signum(), 1 as $T);
assert_eq_const_safe!($T: (0 as $T).signum(), 0 as $T);
assert_eq_const_safe!($T: (-0 as $T).signum(), 0 as $T);
assert_eq_const_safe!($T: (-1 as $T).signum(), -1 as $T);
}
fn test_is_positive() {
@ -72,123 +73,123 @@ macro_rules! int_module {
test_runtime_and_compiletime! {
fn test_count_ones() {
assert_eq_const_safe!(A.count_ones(), 3);
assert_eq_const_safe!(B.count_ones(), 2);
assert_eq_const_safe!(C.count_ones(), 5);
assert_eq_const_safe!(u32: A.count_ones(), 3);
assert_eq_const_safe!(u32: B.count_ones(), 2);
assert_eq_const_safe!(u32: C.count_ones(), 5);
}
fn test_count_zeros() {
assert_eq_const_safe!(A.count_zeros(), $T::BITS - 3);
assert_eq_const_safe!(B.count_zeros(), $T::BITS - 2);
assert_eq_const_safe!(C.count_zeros(), $T::BITS - 5);
assert_eq_const_safe!(u32: A.count_zeros(), $T::BITS - 3);
assert_eq_const_safe!(u32: B.count_zeros(), $T::BITS - 2);
assert_eq_const_safe!(u32: C.count_zeros(), $T::BITS - 5);
}
fn test_leading_trailing_ones() {
const A: $T = 0b0101_1111;
assert_eq_const_safe!(A.trailing_ones(), 5);
assert_eq_const_safe!((!A).leading_ones(), $T::BITS - 7);
assert_eq_const_safe!(u32: A.trailing_ones(), 5);
assert_eq_const_safe!(u32: (!A).leading_ones(), $T::BITS - 7);
assert_eq_const_safe!(A.reverse_bits().leading_ones(), 5);
assert_eq_const_safe!(u32: A.reverse_bits().leading_ones(), 5);
assert_eq_const_safe!(_1.leading_ones(), $T::BITS);
assert_eq_const_safe!(_1.trailing_ones(), $T::BITS);
assert_eq_const_safe!(u32: _1.leading_ones(), $T::BITS);
assert_eq_const_safe!(u32: _1.trailing_ones(), $T::BITS);
assert_eq_const_safe!((_1 << 1).trailing_ones(), 0);
assert_eq_const_safe!(MAX.leading_ones(), 0);
assert_eq_const_safe!(u32: (_1 << 1).trailing_ones(), 0);
assert_eq_const_safe!(u32: MAX.leading_ones(), 0);
assert_eq_const_safe!((_1 << 1).leading_ones(), $T::BITS - 1);
assert_eq_const_safe!(MAX.trailing_ones(), $T::BITS - 1);
assert_eq_const_safe!(u32: (_1 << 1).leading_ones(), $T::BITS - 1);
assert_eq_const_safe!(u32: MAX.trailing_ones(), $T::BITS - 1);
assert_eq_const_safe!(_0.leading_ones(), 0);
assert_eq_const_safe!(_0.trailing_ones(), 0);
assert_eq_const_safe!(u32: _0.leading_ones(), 0);
assert_eq_const_safe!(u32: _0.trailing_ones(), 0);
const X: $T = 0b0010_1100;
assert_eq_const_safe!(X.leading_ones(), 0);
assert_eq_const_safe!(X.trailing_ones(), 0);
assert_eq_const_safe!(u32: X.leading_ones(), 0);
assert_eq_const_safe!(u32: X.trailing_ones(), 0);
}
fn test_rotate() {
assert_eq_const_safe!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
assert_eq_const_safe!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
assert_eq_const_safe!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
assert_eq_const_safe!($T: A.rotate_left(6).rotate_right(2).rotate_right(4), A);
assert_eq_const_safe!($T: B.rotate_left(3).rotate_left(2).rotate_right(5), B);
assert_eq_const_safe!($T: C.rotate_left(6).rotate_right(2).rotate_right(4), C);
// Rotating these should make no difference
//
// We test using 124 bits because to ensure that overlong bit shifts do
// not cause undefined behavior. See #10183.
assert_eq_const_safe!(_0.rotate_left(124), _0);
assert_eq_const_safe!(_1.rotate_left(124), _1);
assert_eq_const_safe!(_0.rotate_right(124), _0);
assert_eq_const_safe!(_1.rotate_right(124), _1);
assert_eq_const_safe!($T: _0.rotate_left(124), _0);
assert_eq_const_safe!($T: _1.rotate_left(124), _1);
assert_eq_const_safe!($T: _0.rotate_right(124), _0);
assert_eq_const_safe!($T: _1.rotate_right(124), _1);
// Rotating by 0 should have no effect
assert_eq_const_safe!(A.rotate_left(0), A);
assert_eq_const_safe!(B.rotate_left(0), B);
assert_eq_const_safe!(C.rotate_left(0), C);
assert_eq_const_safe!($T: A.rotate_left(0), A);
assert_eq_const_safe!($T: B.rotate_left(0), B);
assert_eq_const_safe!($T: C.rotate_left(0), C);
// Rotating by a multiple of word size should also have no effect
assert_eq_const_safe!(A.rotate_left(128), A);
assert_eq_const_safe!(B.rotate_left(128), B);
assert_eq_const_safe!(C.rotate_left(128), C);
assert_eq_const_safe!($T: A.rotate_left(128), A);
assert_eq_const_safe!($T: B.rotate_left(128), B);
assert_eq_const_safe!($T: C.rotate_left(128), C);
}
fn test_swap_bytes() {
assert_eq_const_safe!(A.swap_bytes().swap_bytes(), A);
assert_eq_const_safe!(B.swap_bytes().swap_bytes(), B);
assert_eq_const_safe!(C.swap_bytes().swap_bytes(), C);
assert_eq_const_safe!($T: A.swap_bytes().swap_bytes(), A);
assert_eq_const_safe!($T: B.swap_bytes().swap_bytes(), B);
assert_eq_const_safe!($T: C.swap_bytes().swap_bytes(), C);
// Swapping these should make no difference
assert_eq_const_safe!(_0.swap_bytes(), _0);
assert_eq_const_safe!(_1.swap_bytes(), _1);
assert_eq_const_safe!($T: _0.swap_bytes(), _0);
assert_eq_const_safe!($T: _1.swap_bytes(), _1);
}
fn test_le() {
assert_eq_const_safe!($T::from_le(A.to_le()), A);
assert_eq_const_safe!($T::from_le(B.to_le()), B);
assert_eq_const_safe!($T::from_le(C.to_le()), C);
assert_eq_const_safe!($T::from_le(_0), _0);
assert_eq_const_safe!($T::from_le(_1), _1);
assert_eq_const_safe!(_0.to_le(), _0);
assert_eq_const_safe!(_1.to_le(), _1);
assert_eq_const_safe!($T: $T::from_le(A.to_le()), A);
assert_eq_const_safe!($T: $T::from_le(B.to_le()), B);
assert_eq_const_safe!($T: $T::from_le(C.to_le()), C);
assert_eq_const_safe!($T: $T::from_le(_0), _0);
assert_eq_const_safe!($T: $T::from_le(_1), _1);
assert_eq_const_safe!($T: _0.to_le(), _0);
assert_eq_const_safe!($T: _1.to_le(), _1);
}
fn test_be() {
assert_eq_const_safe!($T::from_be(A.to_be()), A);
assert_eq_const_safe!($T::from_be(B.to_be()), B);
assert_eq_const_safe!($T::from_be(C.to_be()), C);
assert_eq_const_safe!($T::from_be(_0), _0);
assert_eq_const_safe!($T::from_be(_1), _1);
assert_eq_const_safe!(_0.to_be(), _0);
assert_eq_const_safe!(_1.to_be(), _1);
assert_eq_const_safe!($T: $T::from_be(A.to_be()), A);
assert_eq_const_safe!($T: $T::from_be(B.to_be()), B);
assert_eq_const_safe!($T: $T::from_be(C.to_be()), C);
assert_eq_const_safe!($T: $T::from_be(_0), _0);
assert_eq_const_safe!($T: $T::from_be(_1), _1);
assert_eq_const_safe!($T: _0.to_be(), _0);
assert_eq_const_safe!($T: _1.to_be(), _1);
}
fn test_signed_checked_div() {
assert_eq_const_safe!((10 as $T).checked_div(2), Some(5));
assert_eq_const_safe!((5 as $T).checked_div(0), None);
assert_eq_const_safe!(isize::MIN.checked_div(-1), None);
assert_eq_const_safe!(Option<$T>: (10 as $T).checked_div(2), Some(5));
assert_eq_const_safe!(Option<$T>: (5 as $T).checked_div(0), None);
assert_eq_const_safe!(Option<$T>: $T::MIN.checked_div(-1), None);
}
fn test_saturating_abs() {
assert_eq_const_safe!((0 as $T).saturating_abs(), 0);
assert_eq_const_safe!((123 as $T).saturating_abs(), 123);
assert_eq_const_safe!((-123 as $T).saturating_abs(), 123);
assert_eq_const_safe!((MAX - 2).saturating_abs(), MAX - 2);
assert_eq_const_safe!((MAX - 1).saturating_abs(), MAX - 1);
assert_eq_const_safe!(MAX.saturating_abs(), MAX);
assert_eq_const_safe!((MIN + 2).saturating_abs(), MAX - 1);
assert_eq_const_safe!((MIN + 1).saturating_abs(), MAX);
assert_eq_const_safe!(MIN.saturating_abs(), MAX);
assert_eq_const_safe!($T: (0 as $T).saturating_abs(), 0);
assert_eq_const_safe!($T: (123 as $T).saturating_abs(), 123);
assert_eq_const_safe!($T: (-123 as $T).saturating_abs(), 123);
assert_eq_const_safe!($T: (MAX - 2).saturating_abs(), MAX - 2);
assert_eq_const_safe!($T: (MAX - 1).saturating_abs(), MAX - 1);
assert_eq_const_safe!($T: MAX.saturating_abs(), MAX);
assert_eq_const_safe!($T: (MIN + 2).saturating_abs(), MAX - 1);
assert_eq_const_safe!($T: (MIN + 1).saturating_abs(), MAX);
assert_eq_const_safe!($T: MIN.saturating_abs(), MAX);
}
fn test_saturating_neg() {
assert_eq_const_safe!((0 as $T).saturating_neg(), 0);
assert_eq_const_safe!((123 as $T).saturating_neg(), -123);
assert_eq_const_safe!((-123 as $T).saturating_neg(), 123);
assert_eq_const_safe!((MAX - 2).saturating_neg(), MIN + 3);
assert_eq_const_safe!((MAX - 1).saturating_neg(), MIN + 2);
assert_eq_const_safe!(MAX.saturating_neg(), MIN + 1);
assert_eq_const_safe!((MIN + 2).saturating_neg(), MAX - 1);
assert_eq_const_safe!((MIN + 1).saturating_neg(), MAX);
assert_eq_const_safe!(MIN.saturating_neg(), MAX);
assert_eq_const_safe!($T: (0 as $T).saturating_neg(), 0);
assert_eq_const_safe!($T: (123 as $T).saturating_neg(), -123);
assert_eq_const_safe!($T: (-123 as $T).saturating_neg(), 123);
assert_eq_const_safe!($T: (MAX - 2).saturating_neg(), MIN + 3);
assert_eq_const_safe!($T: (MAX - 1).saturating_neg(), MIN + 2);
assert_eq_const_safe!($T: MAX.saturating_neg(), MIN + 1);
assert_eq_const_safe!($T: (MIN + 2).saturating_neg(), MAX - 1);
assert_eq_const_safe!($T: (MIN + 1).saturating_neg(), MAX);
assert_eq_const_safe!($T: MIN.saturating_neg(), MAX);
}
}
@ -250,23 +251,23 @@ macro_rules! int_module {
test_runtime_and_compiletime! {
fn test_from_str_radix() {
assert_eq_const_safe!($T::from_str_radix("123", 10), Ok(123 as $T));
assert_eq_const_safe!($T::from_str_radix("1001", 2), Ok(9 as $T));
assert_eq_const_safe!($T::from_str_radix("123", 8), Ok(83 as $T));
assert_eq_const_safe!(i32::from_str_radix("123", 16), Ok(291 as i32));
assert_eq_const_safe!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
assert_eq_const_safe!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
assert_eq_const_safe!($T::from_str_radix("z", 36), Ok(35 as $T));
assert_eq_const_safe!($T::from_str_radix("Z", 36), Ok(35 as $T));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("123", 10), Ok(123 as $T));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("1001", 2), Ok(9 as $T));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("123", 8), Ok(83 as $T));
assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("123", 16), Ok(291 as i32));
assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("ffff", 16), Ok(65535 as i32));
assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("z", 36), Ok(35 as $T));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("Z", 36), Ok(35 as $T));
assert_eq_const_safe!($T::from_str_radix("-123", 10), Ok(-123 as $T));
assert_eq_const_safe!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
assert_eq_const_safe!($T::from_str_radix("-123", 8), Ok(-83 as $T));
assert_eq_const_safe!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
assert_eq_const_safe!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
assert_eq_const_safe!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
assert_eq_const_safe!($T::from_str_radix("-z", 36), Ok(-35 as $T));
assert_eq_const_safe!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("-123", 10), Ok(-123 as $T));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("-1001", 2), Ok(-9 as $T));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("-123", 8), Ok(-83 as $T));
assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("-123", 16), Ok(-291 as i32));
assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
assert_eq_const_safe!(Result<i32, ParseIntError>: i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("-z", 36), Ok(-35 as $T));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("-Z", 36), Ok(-35 as $T));
assert!($T::from_str_radix("Z", 35).is_err());
assert!($T::from_str_radix("-9", 2).is_err());
@ -277,16 +278,16 @@ macro_rules! int_module {
fn test_pow() {
{
const R: $T = 2;
assert_eq_const_safe!(R.pow(2), 4 as $T);
assert_eq_const_safe!(R.pow(0), 1 as $T);
assert_eq_const_safe!(R.wrapping_pow(2), 4 as $T);
assert_eq_const_safe!(R.wrapping_pow(0), 1 as $T);
assert_eq_const_safe!(R.checked_pow(2), Some(4 as $T));
assert_eq_const_safe!(R.checked_pow(0), Some(1 as $T));
assert_eq_const_safe!(R.overflowing_pow(2), (4 as $T, false));
assert_eq_const_safe!(R.overflowing_pow(0), (1 as $T, false));
assert_eq_const_safe!(R.saturating_pow(2), 4 as $T);
assert_eq_const_safe!(R.saturating_pow(0), 1 as $T);
assert_eq_const_safe!($T: R.pow(2), 4 as $T);
assert_eq_const_safe!($T: R.pow(0), 1 as $T);
assert_eq_const_safe!($T: R.wrapping_pow(2), 4 as $T);
assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(4 as $T));
assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (4 as $T, false));
assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
assert_eq_const_safe!($T: R.saturating_pow(2), 4 as $T);
assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
}
{
@ -295,221 +296,227 @@ macro_rules! int_module {
// if itest::MAX == 2^j-1, then itest is a `j` bit int,
// so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
// thussaturating_pow the overflowing result is exactly 1.
assert_eq_const_safe!(R.wrapping_pow(2), 1 as $T);
assert_eq_const_safe!(R.checked_pow(2), None);
assert_eq_const_safe!(R.overflowing_pow(2), (1 as $T, true));
assert_eq_const_safe!(R.saturating_pow(2), MAX);
assert_eq_const_safe!($T: R.wrapping_pow(2), 1 as $T);
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), None);
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (1 as $T, true));
assert_eq_const_safe!($T: R.saturating_pow(2), MAX);
}
{
// test for negative exponent.
const R: $T = -2;
assert_eq_const_safe!(R.pow(2), 4 as $T);
assert_eq_const_safe!(R.pow(3), -8 as $T);
assert_eq_const_safe!(R.pow(0), 1 as $T);
assert_eq_const_safe!(R.wrapping_pow(2), 4 as $T);
assert_eq_const_safe!(R.wrapping_pow(3), -8 as $T);
assert_eq_const_safe!(R.wrapping_pow(0), 1 as $T);
assert_eq_const_safe!(R.checked_pow(2), Some(4 as $T));
assert_eq_const_safe!(R.checked_pow(3), Some(-8 as $T));
assert_eq_const_safe!(R.checked_pow(0), Some(1 as $T));
assert_eq_const_safe!(R.overflowing_pow(2), (4 as $T, false));
assert_eq_const_safe!(R.overflowing_pow(3), (-8 as $T, false));
assert_eq_const_safe!(R.overflowing_pow(0), (1 as $T, false));
assert_eq_const_safe!(R.saturating_pow(2), 4 as $T);
assert_eq_const_safe!(R.saturating_pow(3), -8 as $T);
assert_eq_const_safe!(R.saturating_pow(0), 1 as $T);
assert_eq_const_safe!($T: R.pow(2), 4 as $T);
assert_eq_const_safe!($T: R.pow(3), -8 as $T);
assert_eq_const_safe!($T: R.pow(0), 1 as $T);
assert_eq_const_safe!($T: R.wrapping_pow(2), 4 as $T);
assert_eq_const_safe!($T: R.wrapping_pow(3), -8 as $T);
assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(4 as $T));
assert_eq_const_safe!(Option<$T>: R.checked_pow(3), Some(-8 as $T));
assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (4 as $T, false));
assert_eq_const_safe!(($T, bool): R.overflowing_pow(3), (-8 as $T, false));
assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
assert_eq_const_safe!($T: R.saturating_pow(2), 4 as $T);
assert_eq_const_safe!($T: R.saturating_pow(3), -8 as $T);
assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
}
}
fn test_div_floor() {
const A: $T = 8;
const B: $T = 3;
assert_eq_const_safe!(A.div_floor(B), 2);
assert_eq_const_safe!(A.div_floor(-B), -3);
assert_eq_const_safe!((-A).div_floor(B), -3);
assert_eq_const_safe!((-A).div_floor(-B), 2);
assert_eq_const_safe!($T: A.div_floor(B), 2);
assert_eq_const_safe!($T: A.div_floor(-B), -3);
assert_eq_const_safe!($T: (-A).div_floor(B), -3);
assert_eq_const_safe!($T: (-A).div_floor(-B), 2);
}
fn test_div_ceil() {
const A: $T = 8;
const B: $T = 3;
assert_eq_const_safe!(A.div_ceil(B), 3);
assert_eq_const_safe!(A.div_ceil(-B), -2);
assert_eq_const_safe!((-A).div_ceil(B), -2);
assert_eq_const_safe!((-A).div_ceil(-B), 3);
assert_eq_const_safe!($T: A.div_ceil(B), 3);
assert_eq_const_safe!($T: A.div_ceil(-B), -2);
assert_eq_const_safe!($T: (-A).div_ceil(B), -2);
assert_eq_const_safe!($T: (-A).div_ceil(-B), 3);
}
fn test_next_multiple_of() {
assert_eq_const_safe!((16 as $T).next_multiple_of(8), 16);
assert_eq_const_safe!((23 as $T).next_multiple_of(8), 24);
assert_eq_const_safe!((16 as $T).next_multiple_of(-8), 16);
assert_eq_const_safe!((23 as $T).next_multiple_of(-8), 16);
assert_eq_const_safe!((-16 as $T).next_multiple_of(8), -16);
assert_eq_const_safe!((-23 as $T).next_multiple_of(8), -16);
assert_eq_const_safe!((-16 as $T).next_multiple_of(-8), -16);
assert_eq_const_safe!((-23 as $T).next_multiple_of(-8), -24);
assert_eq_const_safe!(MIN.next_multiple_of(-1), MIN);
assert_eq_const_safe!($T: (16 as $T).next_multiple_of(8), 16);
assert_eq_const_safe!($T: (23 as $T).next_multiple_of(8), 24);
assert_eq_const_safe!($T: (16 as $T).next_multiple_of(-8), 16);
assert_eq_const_safe!($T: (23 as $T).next_multiple_of(-8), 16);
assert_eq_const_safe!($T: (-16 as $T).next_multiple_of(8), -16);
assert_eq_const_safe!($T: (-23 as $T).next_multiple_of(8), -16);
assert_eq_const_safe!($T: (-16 as $T).next_multiple_of(-8), -16);
assert_eq_const_safe!($T: (-23 as $T).next_multiple_of(-8), -24);
assert_eq_const_safe!($T: MIN.next_multiple_of(-1), MIN);
}
fn test_checked_next_multiple_of() {
assert_eq_const_safe!((16 as $T).checked_next_multiple_of(8), Some(16));
assert_eq_const_safe!((23 as $T).checked_next_multiple_of(8), Some(24));
assert_eq_const_safe!((16 as $T).checked_next_multiple_of(-8), Some(16));
assert_eq_const_safe!((23 as $T).checked_next_multiple_of(-8), Some(16));
assert_eq_const_safe!((-16 as $T).checked_next_multiple_of(8), Some(-16));
assert_eq_const_safe!((-23 as $T).checked_next_multiple_of(8), Some(-16));
assert_eq_const_safe!((-16 as $T).checked_next_multiple_of(-8), Some(-16));
assert_eq_const_safe!((-23 as $T).checked_next_multiple_of(-8), Some(-24));
assert_eq_const_safe!((1 as $T).checked_next_multiple_of(0), None);
assert_eq_const_safe!(MAX.checked_next_multiple_of(2), None);
assert_eq_const_safe!(MIN.checked_next_multiple_of(-3), None);
assert_eq_const_safe!(MIN.checked_next_multiple_of(-1), Some(MIN));
assert_eq_const_safe!(Option<$T>: (16 as $T).checked_next_multiple_of(8), Some(16));
assert_eq_const_safe!(Option<$T>: (23 as $T).checked_next_multiple_of(8), Some(24));
assert_eq_const_safe!(Option<$T>: (16 as $T).checked_next_multiple_of(-8), Some(16));
assert_eq_const_safe!(Option<$T>: (23 as $T).checked_next_multiple_of(-8), Some(16));
assert_eq_const_safe!(Option<$T>: (-16 as $T).checked_next_multiple_of(8), Some(-16));
assert_eq_const_safe!(Option<$T>: (-23 as $T).checked_next_multiple_of(8), Some(-16));
assert_eq_const_safe!(Option<$T>: (-16 as $T).checked_next_multiple_of(-8), Some(-16));
assert_eq_const_safe!(Option<$T>: (-23 as $T).checked_next_multiple_of(-8), Some(-24));
assert_eq_const_safe!(Option<$T>: (1 as $T).checked_next_multiple_of(0), None);
assert_eq_const_safe!(Option<$T>: MAX.checked_next_multiple_of(2), None);
assert_eq_const_safe!(Option<$T>: MIN.checked_next_multiple_of(-3), None);
assert_eq_const_safe!(Option<$T>: MIN.checked_next_multiple_of(-1), Some(MIN));
}
fn test_carrying_add() {
assert_eq_const_safe!(MAX.carrying_add(1, false), (MIN, true));
assert_eq_const_safe!(MAX.carrying_add(0, true), (MIN, true));
assert_eq_const_safe!(MAX.carrying_add(1, true), (MIN + 1, true));
assert_eq_const_safe!(MAX.carrying_add(-1, false), (MAX - 1, false));
assert_eq_const_safe!(MAX.carrying_add(-1, true), (MAX, false)); // no intermediate overflow
assert_eq_const_safe!(MIN.carrying_add(-1, false), (MAX, true));
assert_eq_const_safe!(MIN.carrying_add(-1, true), (MIN, false)); // no intermediate overflow
assert_eq_const_safe!((0 as $T).carrying_add(MAX, true), (MIN, true));
assert_eq_const_safe!((0 as $T).carrying_add(MIN, true), (MIN + 1, false));
assert_eq_const_safe!(($T, bool): MAX.carrying_add(1, false), (MIN, true));
assert_eq_const_safe!(($T, bool): MAX.carrying_add(0, true), (MIN, true));
assert_eq_const_safe!(($T, bool): MAX.carrying_add(1, true), (MIN + 1, true));
assert_eq_const_safe!(($T, bool): MAX.carrying_add(-1, false), (MAX - 1, false));
assert_eq_const_safe!(($T, bool): MAX.carrying_add(-1, true), (MAX, false)); // no intermediate overflow
assert_eq_const_safe!(($T, bool): MIN.carrying_add(-1, false), (MAX, true));
assert_eq_const_safe!(($T, bool): MIN.carrying_add(-1, true), (MIN, false)); // no intermediate overflow
assert_eq_const_safe!(($T, bool): (0 as $T).carrying_add(MAX, true), (MIN, true));
assert_eq_const_safe!(($T, bool): (0 as $T).carrying_add(MIN, true), (MIN + 1, false));
}
fn test_borrowing_sub() {
assert_eq_const_safe!(MIN.borrowing_sub(1, false), (MAX, true));
assert_eq_const_safe!(MIN.borrowing_sub(0, true), (MAX, true));
assert_eq_const_safe!(MIN.borrowing_sub(1, true), (MAX - 1, true));
assert_eq_const_safe!(MIN.borrowing_sub(-1, false), (MIN + 1, false));
assert_eq_const_safe!(MIN.borrowing_sub(-1, true), (MIN, false)); // no intermediate overflow
assert_eq_const_safe!(MAX.borrowing_sub(-1, false), (MIN, true));
assert_eq_const_safe!(MAX.borrowing_sub(-1, true), (MAX, false)); // no intermediate overflow
assert_eq_const_safe!((0 as $T).borrowing_sub(MIN, false), (MIN, true));
assert_eq_const_safe!((0 as $T).borrowing_sub(MIN, true), (MAX, false));
assert_eq_const_safe!(($T, bool): MIN.borrowing_sub(1, false), (MAX, true));
assert_eq_const_safe!(($T, bool): MIN.borrowing_sub(0, true), (MAX, true));
assert_eq_const_safe!(($T, bool): MIN.borrowing_sub(1, true), (MAX - 1, true));
assert_eq_const_safe!(($T, bool): MIN.borrowing_sub(-1, false), (MIN + 1, false));
assert_eq_const_safe!(($T, bool): MIN.borrowing_sub(-1, true), (MIN, false)); // no intermediate overflow
assert_eq_const_safe!(($T, bool): MAX.borrowing_sub(-1, false), (MIN, true));
assert_eq_const_safe!(($T, bool): MAX.borrowing_sub(-1, true), (MAX, false)); // no intermediate overflow
assert_eq_const_safe!(($T, bool): (0 as $T).borrowing_sub(MIN, false), (MIN, true));
assert_eq_const_safe!(($T, bool): (0 as $T).borrowing_sub(MIN, true), (MAX, false));
}
fn test_widening_mul() {
assert_eq_const_safe!(MAX.widening_mul(MAX), (1, MAX / 2));
assert_eq_const_safe!(MIN.widening_mul(MAX), (MIN as $U, MIN / 2));
assert_eq_const_safe!(MIN.widening_mul(MIN), (0, MAX / 2 + 1));
assert_eq_const_safe!(($U, $T): MAX.widening_mul(MAX), (1, MAX / 2));
assert_eq_const_safe!(($U, $T): MIN.widening_mul(MAX), (MIN as $U, MIN / 2));
assert_eq_const_safe!(($U, $T): MIN.widening_mul(MIN), (0, MAX / 2 + 1));
}
fn test_carrying_mul() {
assert_eq_const_safe!(MAX.carrying_mul(MAX, 0), (1, MAX / 2));
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T): MAX.carrying_mul(MAX, 0), (1, MAX / 2));
assert_eq_const_safe!(($U, $T):
MAX.carrying_mul(MAX, MAX),
(UMAX / 2 + 1, MAX / 2)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MAX.carrying_mul(MAX, MIN),
(UMAX / 2 + 2, MAX / 2 - 1)
);
assert_eq_const_safe!(MIN.carrying_mul(MAX, 0), (MIN as $U, MIN / 2));
assert_eq_const_safe!(MIN.carrying_mul(MAX, MAX), (UMAX, MIN / 2));
assert_eq_const_safe!(MIN.carrying_mul(MAX, MIN), (0, MIN / 2));
assert_eq_const_safe!(MIN.carrying_mul(MIN, 0), (0, MAX / 2 + 1));
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T): MIN.carrying_mul(MAX, 0), (MIN as $U, MIN / 2));
assert_eq_const_safe!(($U, $T): MIN.carrying_mul(MAX, MAX), (UMAX, MIN / 2));
assert_eq_const_safe!(($U, $T): MIN.carrying_mul(MAX, MIN), (0, MIN / 2));
assert_eq_const_safe!(($U, $T): MIN.carrying_mul(MIN, 0), (0, MAX / 2 + 1));
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul(MIN, MAX),
(UMAX / 2, MAX / 2 + 1)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul(MIN, MIN),
(UMAX / 2 + 1, MAX / 2)
);
}
fn test_carrying_mul_add() {
assert_eq_const_safe!(MAX.carrying_mul_add(MAX, 0, 0), (1, MAX / 2));
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T): MAX.carrying_mul_add(MAX, 0, 0), (1, MAX / 2));
assert_eq_const_safe!(($U, $T):
MAX.carrying_mul_add(MAX, MAX, 0),
(UMAX / 2 + 1, MAX / 2)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MAX.carrying_mul_add(MAX, MIN, 0),
(UMAX / 2 + 2, MAX / 2 - 1)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MAX.carrying_mul_add(MAX, MAX, MAX),
(UMAX, MAX / 2)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MAX.carrying_mul_add(MAX, MAX, MIN),
(0, MAX / 2)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MAX.carrying_mul_add(MAX, MIN, MIN),
(1, MAX / 2 - 1)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MAX, 0, 0),
(MIN as $U, MIN / 2)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MAX, MAX, 0),
(UMAX, MIN / 2)
);
assert_eq_const_safe!(MIN.carrying_mul_add(MAX, MIN, 0), (0, MIN / 2));
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MAX, MIN, 0),
(0, MIN / 2)
);
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MAX, MAX, MAX),
(UMAX / 2 - 1, MIN / 2 + 1)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MAX, MAX, MIN),
(UMAX / 2, MIN / 2)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MAX, MIN, MIN),
(UMAX / 2 + 1, MIN / 2 - 1)
);
assert_eq_const_safe!(MIN.carrying_mul_add(MIN, 0, 0), (0, MAX / 2 + 1));
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MIN, 0, 0),
(0, MAX / 2 + 1)
);
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MIN, MAX, 0),
(UMAX / 2, MAX / 2 + 1)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MIN, MIN, 0),
(UMAX / 2 + 1, MAX / 2)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MIN, MAX, MAX),
(UMAX - 1, MAX / 2 + 1)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MIN, MAX, MIN),
(UMAX, MAX / 2)
);
assert_eq_const_safe!(
assert_eq_const_safe!(($U, $T):
MIN.carrying_mul_add(MIN, MIN, MIN),
(0, MAX / 2)
);
}
fn test_midpoint() {
assert_eq_const_safe!(<$T>::midpoint(1, 3), 2);
assert_eq_const_safe!(<$T>::midpoint(3, 1), 2);
assert_eq_const_safe!($T: <$T>::midpoint(1, 3), 2);
assert_eq_const_safe!($T: <$T>::midpoint(3, 1), 2);
assert_eq_const_safe!(<$T>::midpoint(0, 0), 0);
assert_eq_const_safe!(<$T>::midpoint(0, 2), 1);
assert_eq_const_safe!(<$T>::midpoint(2, 0), 1);
assert_eq_const_safe!(<$T>::midpoint(2, 2), 2);
assert_eq_const_safe!($T: <$T>::midpoint(0, 0), 0);
assert_eq_const_safe!($T: <$T>::midpoint(0, 2), 1);
assert_eq_const_safe!($T: <$T>::midpoint(2, 0), 1);
assert_eq_const_safe!($T: <$T>::midpoint(2, 2), 2);
assert_eq_const_safe!(<$T>::midpoint(1, 4), 2);
assert_eq_const_safe!(<$T>::midpoint(4, 1), 2);
assert_eq_const_safe!(<$T>::midpoint(3, 4), 3);
assert_eq_const_safe!(<$T>::midpoint(4, 3), 3);
assert_eq_const_safe!($T: <$T>::midpoint(1, 4), 2);
assert_eq_const_safe!($T: <$T>::midpoint(4, 1), 2);
assert_eq_const_safe!($T: <$T>::midpoint(3, 4), 3);
assert_eq_const_safe!($T: <$T>::midpoint(4, 3), 3);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), 0);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), 0);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, <$T>::MAX), 0);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, <$T>::MIN), 0);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
assert_eq_const_safe!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, 6), <$T>::MAX / 2 + 3);
assert_eq_const_safe!(<$T>::midpoint(6, <$T>::MAX), <$T>::MAX / 2 + 3);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
assert_eq_const_safe!($T: <$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, 6), <$T>::MAX / 2 + 3);
assert_eq_const_safe!($T: <$T>::midpoint(6, <$T>::MAX), <$T>::MAX / 2 + 3);
}
}
@ -526,154 +533,154 @@ macro_rules! int_module {
test_runtime_and_compiletime! {
fn test_unbounded_shl() {
// <$T>::MIN
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 1), (<$T>::MIN << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 3), (<$T>::MIN << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 5), (<$T>::MIN << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 1), (<$T>::MIN << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 3), (<$T>::MIN << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 5), (<$T>::MIN << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
// <$T>::MAX
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 1), (<$T>::MAX << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 3), (<$T>::MAX << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 5), (<$T>::MAX << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 1), (<$T>::MAX << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 3), (<$T>::MAX << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 5), (<$T>::MAX << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
// 1
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_ONE), (1 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_TWO), (1 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_THREE), (1 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_FOUR), (1 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(1, 1), (1 << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(1, 3), (1 << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(1, 5), (1 << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_ONE), (1 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_TWO), (1 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_THREE), (1 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_FOUR), (1 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 1), (1 << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 3), (1 << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 5), (1 << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW3), 0);
// -1
assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_ONE), (-1 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_TWO), (-1 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_THREE), (-1 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_FOUR), (-1 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(-1, 1), (-1 << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(-1, 3), (-1 << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(-1, 5), (-1 << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_ONE), (-1 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_TWO), (-1 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_THREE), (-1 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_TEST_FOUR), (-1 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, 1), (-1 << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, 3), (-1 << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, 5), (-1 << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(-1, SHIFT_AMOUNT_OVERFLOW3), 0);
// 8
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_ONE), (8 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_TWO), (8 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_THREE), (8 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_FOUR), (8 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(8, 1), (8 << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(8, 3), (8 << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(8, 5), (8 << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_ONE), (8 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_TWO), (8 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_THREE), (8 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_FOUR), (8 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 1), (8 << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 3), (8 << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 5), (8 << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW3), 0);
// 17
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_ONE), (17 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_TWO), (17 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_THREE), (17 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_FOUR), (17 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(17, 1), (17 << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(17, 3), (17 << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(17, 5), (17 << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_ONE), (17 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_TWO), (17 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_THREE), (17 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_FOUR), (17 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 1), (17 << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 3), (17 << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 5), (17 << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW3), 0);
}
fn test_unbounded_shr() {
// <$T>::MIN
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 1), (<$T>::MIN >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 3), (<$T>::MIN >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 5), (<$T>::MIN >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), -1);
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), -1);
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), -1);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 1), (<$T>::MIN >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 3), (<$T>::MIN >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 5), (<$T>::MIN >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), -1);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), -1);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), -1);
// <$T>::MAX
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 1), (<$T>::MAX >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 3), (<$T>::MAX >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 5), (<$T>::MAX >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 1), (<$T>::MAX >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 3), (<$T>::MAX >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 5), (<$T>::MAX >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
// 1
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_ONE), (1 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_TWO), (1 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_THREE), (1 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_FOUR), (1 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(1, 1), (1 >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(1, 3), (1 >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(1, 5), (1 >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_ONE), (1 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_TWO), (1 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_THREE), (1 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_FOUR), (1 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 1), (1 >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 3), (1 >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 5), (1 >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW3), 0);
// -1
assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_ONE), (-1 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_TWO), (-1 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_THREE), (-1 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_FOUR), (-1 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(-1, 1), (-1 >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(-1, 3), (-1 >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(-1, 5), (-1 >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW), -1);
assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW), -1);
assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW2), -1);
assert_eq_const_safe!(<$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW3), -1);
assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_ONE), (-1 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_TWO), (-1 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_THREE), (-1 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_TEST_FOUR), (-1 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, 1), (-1 >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, 3), (-1 >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, 5), (-1 >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW), -1);
assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW), -1);
assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW2), -1);
assert_eq_const_safe!($T: <$T>::unbounded_shr(-1, SHIFT_AMOUNT_OVERFLOW3), -1);
// 8
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_ONE), (8 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_TWO), (8 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_THREE), (8 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_FOUR), (8 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(8, 1), (8 >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(8, 3), (8 >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(8, 5), (8 >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_ONE), (8 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_TWO), (8 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_THREE), (8 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_FOUR), (8 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 1), (8 >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 3), (8 >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 5), (8 >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW3), 0);
// 17
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_ONE), (17 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_TWO), (17 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_THREE), (17 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_FOUR), (17 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(17, 1), (17 >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(17, 3), (17 >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(17, 5), (17 >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_ONE), (17 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_TWO), (17 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_THREE), (17 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_FOUR), (17 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 1), (17 >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 3), (17 >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 5), (17 >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW3), 0);
}
}
};

View file

@ -1,5 +1,6 @@
macro_rules! uint_module {
($T:ident) => {
use core::num::ParseIntError;
use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
use core::$T::*;
@ -49,95 +50,95 @@ macro_rules! uint_module {
fn test_leading_trailing_ones() {
const A: $T = 0b0101_1111;
assert_eq_const_safe!(A.trailing_ones(), 5);
assert_eq_const_safe!((!A).leading_ones(), $T::BITS - 7);
assert_eq_const_safe!(u32: A.trailing_ones(), 5);
assert_eq_const_safe!(u32: (!A).leading_ones(), $T::BITS - 7);
assert_eq_const_safe!(A.reverse_bits().leading_ones(), 5);
assert_eq_const_safe!(u32: A.reverse_bits().leading_ones(), 5);
assert_eq_const_safe!(_1.leading_ones(), $T::BITS);
assert_eq_const_safe!(_1.trailing_ones(), $T::BITS);
assert_eq_const_safe!(u32: _1.leading_ones(), $T::BITS);
assert_eq_const_safe!(u32: _1.trailing_ones(), $T::BITS);
assert_eq_const_safe!((_1 << 1).trailing_ones(), 0);
assert_eq_const_safe!((_1 >> 1).leading_ones(), 0);
assert_eq_const_safe!(u32: (_1 << 1).trailing_ones(), 0);
assert_eq_const_safe!(u32: (_1 >> 1).leading_ones(), 0);
assert_eq_const_safe!((_1 << 1).leading_ones(), $T::BITS - 1);
assert_eq_const_safe!((_1 >> 1).trailing_ones(), $T::BITS - 1);
assert_eq_const_safe!(u32: (_1 << 1).leading_ones(), $T::BITS - 1);
assert_eq_const_safe!(u32: (_1 >> 1).trailing_ones(), $T::BITS - 1);
assert_eq_const_safe!(_0.leading_ones(), 0);
assert_eq_const_safe!(_0.trailing_ones(), 0);
assert_eq_const_safe!(u32: _0.leading_ones(), 0);
assert_eq_const_safe!(u32: _0.trailing_ones(), 0);
const X: $T = 0b0010_1100;
assert_eq_const_safe!(X.leading_ones(), 0);
assert_eq_const_safe!(X.trailing_ones(), 0);
assert_eq_const_safe!(u32: X.leading_ones(), 0);
assert_eq_const_safe!(u32: X.trailing_ones(), 0);
}
fn test_rotate() {
assert_eq_const_safe!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
assert_eq_const_safe!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
assert_eq_const_safe!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
assert_eq_const_safe!($T: A.rotate_left(6).rotate_right(2).rotate_right(4), A);
assert_eq_const_safe!($T: B.rotate_left(3).rotate_left(2).rotate_right(5), B);
assert_eq_const_safe!($T: C.rotate_left(6).rotate_right(2).rotate_right(4), C);
// Rotating these should make no difference
//
// We test using 124 bits because to ensure that overlong bit shifts do
// not cause undefined behavior. See #10183.
assert_eq_const_safe!(_0.rotate_left(124), _0);
assert_eq_const_safe!(_1.rotate_left(124), _1);
assert_eq_const_safe!(_0.rotate_right(124), _0);
assert_eq_const_safe!(_1.rotate_right(124), _1);
assert_eq_const_safe!($T: _0.rotate_left(124), _0);
assert_eq_const_safe!($T: _1.rotate_left(124), _1);
assert_eq_const_safe!($T: _0.rotate_right(124), _0);
assert_eq_const_safe!($T: _1.rotate_right(124), _1);
// Rotating by 0 should have no effect
assert_eq_const_safe!(A.rotate_left(0), A);
assert_eq_const_safe!(B.rotate_left(0), B);
assert_eq_const_safe!(C.rotate_left(0), C);
assert_eq_const_safe!($T: A.rotate_left(0), A);
assert_eq_const_safe!($T: B.rotate_left(0), B);
assert_eq_const_safe!($T: C.rotate_left(0), C);
// Rotating by a multiple of word size should also have no effect
assert_eq_const_safe!(A.rotate_left(128), A);
assert_eq_const_safe!(B.rotate_left(128), B);
assert_eq_const_safe!(C.rotate_left(128), C);
assert_eq_const_safe!($T: A.rotate_left(128), A);
assert_eq_const_safe!($T: B.rotate_left(128), B);
assert_eq_const_safe!($T: C.rotate_left(128), C);
}
fn test_swap_bytes() {
assert_eq_const_safe!(A.swap_bytes().swap_bytes(), A);
assert_eq_const_safe!(B.swap_bytes().swap_bytes(), B);
assert_eq_const_safe!(C.swap_bytes().swap_bytes(), C);
assert_eq_const_safe!($T: A.swap_bytes().swap_bytes(), A);
assert_eq_const_safe!($T: B.swap_bytes().swap_bytes(), B);
assert_eq_const_safe!($T: C.swap_bytes().swap_bytes(), C);
// Swapping these should make no difference
assert_eq_const_safe!(_0.swap_bytes(), _0);
assert_eq_const_safe!(_1.swap_bytes(), _1);
assert_eq_const_safe!($T: _0.swap_bytes(), _0);
assert_eq_const_safe!($T: _1.swap_bytes(), _1);
}
fn test_reverse_bits() {
assert_eq_const_safe!(A.reverse_bits().reverse_bits(), A);
assert_eq_const_safe!(B.reverse_bits().reverse_bits(), B);
assert_eq_const_safe!(C.reverse_bits().reverse_bits(), C);
assert_eq_const_safe!($T: A.reverse_bits().reverse_bits(), A);
assert_eq_const_safe!($T: B.reverse_bits().reverse_bits(), B);
assert_eq_const_safe!($T: C.reverse_bits().reverse_bits(), C);
// Swapping these should make no difference
assert_eq_const_safe!(_0.reverse_bits(), _0);
assert_eq_const_safe!(_1.reverse_bits(), _1);
assert_eq_const_safe!($T: _0.reverse_bits(), _0);
assert_eq_const_safe!($T: _1.reverse_bits(), _1);
}
fn test_le() {
assert_eq_const_safe!($T::from_le(A.to_le()), A);
assert_eq_const_safe!($T::from_le(B.to_le()), B);
assert_eq_const_safe!($T::from_le(C.to_le()), C);
assert_eq_const_safe!($T::from_le(_0), _0);
assert_eq_const_safe!($T::from_le(_1), _1);
assert_eq_const_safe!(_0.to_le(), _0);
assert_eq_const_safe!(_1.to_le(), _1);
assert_eq_const_safe!($T: $T::from_le(A.to_le()), A);
assert_eq_const_safe!($T: $T::from_le(B.to_le()), B);
assert_eq_const_safe!($T: $T::from_le(C.to_le()), C);
assert_eq_const_safe!($T: $T::from_le(_0), _0);
assert_eq_const_safe!($T: $T::from_le(_1), _1);
assert_eq_const_safe!($T: _0.to_le(), _0);
assert_eq_const_safe!($T: _1.to_le(), _1);
}
fn test_be() {
assert_eq_const_safe!($T::from_be(A.to_be()), A);
assert_eq_const_safe!($T::from_be(B.to_be()), B);
assert_eq_const_safe!($T::from_be(C.to_be()), C);
assert_eq_const_safe!($T::from_be(_0), _0);
assert_eq_const_safe!($T::from_be(_1), _1);
assert_eq_const_safe!(_0.to_be(), _0);
assert_eq_const_safe!(_1.to_be(), _1);
assert_eq_const_safe!($T: $T::from_be(A.to_be()), A);
assert_eq_const_safe!($T: $T::from_be(B.to_be()), B);
assert_eq_const_safe!($T: $T::from_be(C.to_be()), C);
assert_eq_const_safe!($T: $T::from_be(_0), _0);
assert_eq_const_safe!($T: $T::from_be(_1), _1);
assert_eq_const_safe!($T: _0.to_be(), _0);
assert_eq_const_safe!($T: _1.to_be(), _1);
}
fn test_unsigned_checked_div() {
assert_eq_const_safe!((10 as $T).checked_div(2), Some(5));
assert_eq_const_safe!((5 as $T).checked_div(0), None);
assert_eq_const_safe!(Option<$T>: (10 as $T).checked_div(2), Some(5));
assert_eq_const_safe!(Option<$T>: (5 as $T).checked_div(0), None);
}
}
@ -194,12 +195,12 @@ macro_rules! uint_module {
test_runtime_and_compiletime! {
fn test_parse_bytes() {
assert_eq_const_safe!($T::from_str_radix("123", 10), Ok(123 as $T));
assert_eq_const_safe!($T::from_str_radix("1001", 2), Ok(9 as $T));
assert_eq_const_safe!($T::from_str_radix("123", 8), Ok(83 as $T));
assert_eq_const_safe!(u16::from_str_radix("123", 16), Ok(291 as u16));
assert_eq_const_safe!(u16::from_str_radix("ffff", 16), Ok(65535 as u16));
assert_eq_const_safe!($T::from_str_radix("z", 36), Ok(35 as $T));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("123", 10), Ok(123 as $T));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("1001", 2), Ok(9 as $T));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("123", 8), Ok(83 as $T));
assert_eq_const_safe!(Result<u16, ParseIntError>: u16::from_str_radix("123", 16), Ok(291 as u16));
assert_eq_const_safe!(Result<u16, ParseIntError>: u16::from_str_radix("ffff", 16), Ok(65535 as u16));
assert_eq_const_safe!(Result<$T, ParseIntError>: $T::from_str_radix("z", 36), Ok(35 as $T));
assert!($T::from_str_radix("Z", 10).is_err());
assert!($T::from_str_radix("_", 2).is_err());
@ -208,16 +209,16 @@ macro_rules! uint_module {
fn test_pow() {
{
const R: $T = 2;
assert_eq_const_safe!(R.pow(2), 4 as $T);
assert_eq_const_safe!(R.pow(0), 1 as $T);
assert_eq_const_safe!(R.wrapping_pow(2), 4 as $T);
assert_eq_const_safe!(R.wrapping_pow(0), 1 as $T);
assert_eq_const_safe!(R.checked_pow(2), Some(4 as $T));
assert_eq_const_safe!(R.checked_pow(0), Some(1 as $T));
assert_eq_const_safe!(R.overflowing_pow(2), (4 as $T, false));
assert_eq_const_safe!(R.overflowing_pow(0), (1 as $T, false));
assert_eq_const_safe!(R.saturating_pow(2), 4 as $T);
assert_eq_const_safe!(R.saturating_pow(0), 1 as $T);
assert_eq_const_safe!($T: R.pow(2), 4 as $T);
assert_eq_const_safe!($T: R.pow(0), 1 as $T);
assert_eq_const_safe!($T: R.wrapping_pow(2), 4 as $T);
assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(4 as $T));
assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (4 as $T, false));
assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
assert_eq_const_safe!($T: R.saturating_pow(2), 4 as $T);
assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
}
{
@ -226,20 +227,20 @@ macro_rules! uint_module {
// if itest::MAX == 2^j-1, then itest is a `j` bit int,
// so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
// thussaturating_pow the overflowing result is exactly 1.
assert_eq_const_safe!(R.wrapping_pow(2), 1 as $T);
assert_eq_const_safe!(R.checked_pow(2), None);
assert_eq_const_safe!(R.overflowing_pow(2), (1 as $T, true));
assert_eq_const_safe!(R.saturating_pow(2), MAX);
assert_eq_const_safe!($T: R.wrapping_pow(2), 1 as $T);
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), None);
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (1 as $T, true));
assert_eq_const_safe!($T: R.saturating_pow(2), MAX);
}
}
fn test_isqrt() {
assert_eq_const_safe!((0 as $T).isqrt(), 0 as $T);
assert_eq_const_safe!((1 as $T).isqrt(), 1 as $T);
assert_eq_const_safe!((2 as $T).isqrt(), 1 as $T);
assert_eq_const_safe!((99 as $T).isqrt(), 9 as $T);
assert_eq_const_safe!((100 as $T).isqrt(), 10 as $T);
assert_eq_const_safe!($T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1);
assert_eq_const_safe!($T: (0 as $T).isqrt(), 0 as $T);
assert_eq_const_safe!($T: (1 as $T).isqrt(), 1 as $T);
assert_eq_const_safe!($T: (2 as $T).isqrt(), 1 as $T);
assert_eq_const_safe!($T: (99 as $T).isqrt(), 9 as $T);
assert_eq_const_safe!($T: (100 as $T).isqrt(), 10 as $T);
assert_eq_const_safe!($T: $T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1);
}
}
@ -264,24 +265,24 @@ macro_rules! uint_module {
test_runtime_and_compiletime! {
fn test_div_floor() {
assert_eq_const_safe!((8 as $T).div_floor(3), 2);
assert_eq_const_safe!($T: (8 as $T).div_floor(3), 2);
}
fn test_div_ceil() {
assert_eq_const_safe!((8 as $T).div_ceil(3), 3);
assert_eq_const_safe!($T: (8 as $T).div_ceil(3), 3);
}
fn test_next_multiple_of() {
assert_eq_const_safe!((16 as $T).next_multiple_of(8), 16);
assert_eq_const_safe!((23 as $T).next_multiple_of(8), 24);
assert_eq_const_safe!(MAX.next_multiple_of(1), MAX);
assert_eq_const_safe!($T: (16 as $T).next_multiple_of(8), 16);
assert_eq_const_safe!($T: (23 as $T).next_multiple_of(8), 24);
assert_eq_const_safe!($T: MAX.next_multiple_of(1), MAX);
}
fn test_checked_next_multiple_of() {
assert_eq_const_safe!((16 as $T).checked_next_multiple_of(8), Some(16));
assert_eq_const_safe!((23 as $T).checked_next_multiple_of(8), Some(24));
assert_eq_const_safe!((1 as $T).checked_next_multiple_of(0), None);
assert_eq_const_safe!(MAX.checked_next_multiple_of(2), None);
assert_eq_const_safe!(Option<$T>: (16 as $T).checked_next_multiple_of(8), Some(16));
assert_eq_const_safe!(Option<$T>: (23 as $T).checked_next_multiple_of(8), Some(24));
assert_eq_const_safe!(Option<$T>: (1 as $T).checked_next_multiple_of(0), None);
assert_eq_const_safe!(Option<$T>: MAX.checked_next_multiple_of(2), None);
}
fn test_is_next_multiple_of() {
@ -292,63 +293,63 @@ macro_rules! uint_module {
}
fn test_carrying_add() {
assert_eq_const_safe!($T::MAX.carrying_add(1, false), (0, true));
assert_eq_const_safe!($T::MAX.carrying_add(0, true), (0, true));
assert_eq_const_safe!($T::MAX.carrying_add(1, true), (1, true));
assert_eq_const_safe!(($T, bool): $T::MAX.carrying_add(1, false), (0, true));
assert_eq_const_safe!(($T, bool): $T::MAX.carrying_add(0, true), (0, true));
assert_eq_const_safe!(($T, bool): $T::MAX.carrying_add(1, true), (1, true));
assert_eq_const_safe!($T::MIN.carrying_add($T::MAX, false), ($T::MAX, false));
assert_eq_const_safe!($T::MIN.carrying_add(0, true), (1, false));
assert_eq_const_safe!($T::MIN.carrying_add($T::MAX, true), (0, true));
assert_eq_const_safe!(($T, bool): $T::MIN.carrying_add($T::MAX, false), ($T::MAX, false));
assert_eq_const_safe!(($T, bool): $T::MIN.carrying_add(0, true), (1, false));
assert_eq_const_safe!(($T, bool): $T::MIN.carrying_add($T::MAX, true), (0, true));
}
fn test_borrowing_sub() {
assert_eq_const_safe!($T::MIN.borrowing_sub(1, false), ($T::MAX, true));
assert_eq_const_safe!($T::MIN.borrowing_sub(0, true), ($T::MAX, true));
assert_eq_const_safe!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true));
assert_eq_const_safe!(($T, bool): $T::MIN.borrowing_sub(1, false), ($T::MAX, true));
assert_eq_const_safe!(($T, bool): $T::MIN.borrowing_sub(0, true), ($T::MAX, true));
assert_eq_const_safe!(($T, bool): $T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true));
assert_eq_const_safe!($T::MAX.borrowing_sub($T::MAX, false), (0, false));
assert_eq_const_safe!($T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false));
assert_eq_const_safe!($T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true));
assert_eq_const_safe!(($T, bool): $T::MAX.borrowing_sub($T::MAX, false), (0, false));
assert_eq_const_safe!(($T, bool): $T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false));
assert_eq_const_safe!(($T, bool): $T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true));
}
fn test_widening_mul() {
assert_eq_const_safe!($T::MAX.widening_mul($T::MAX), (1, $T::MAX - 1));
assert_eq_const_safe!(($T, $T): $T::MAX.widening_mul($T::MAX), (1, $T::MAX - 1));
}
fn test_carrying_mul() {
assert_eq_const_safe!($T::MAX.carrying_mul($T::MAX, 0), (1, $T::MAX - 1));
assert_eq_const_safe!($T::MAX.carrying_mul($T::MAX, $T::MAX), (0, $T::MAX));
assert_eq_const_safe!(($T, $T): $T::MAX.carrying_mul($T::MAX, 0), (1, $T::MAX - 1));
assert_eq_const_safe!(($T, $T): $T::MAX.carrying_mul($T::MAX, $T::MAX), (0, $T::MAX));
}
fn test_carrying_mul_add() {
assert_eq_const_safe!($T::MAX.carrying_mul_add($T::MAX, 0, 0), (1, $T::MAX - 1));
assert_eq_const_safe!($T::MAX.carrying_mul_add($T::MAX, $T::MAX, 0), (0, $T::MAX));
assert_eq_const_safe!($T::MAX.carrying_mul_add($T::MAX, $T::MAX, $T::MAX), ($T::MAX, $T::MAX));
assert_eq_const_safe!(($T, $T): $T::MAX.carrying_mul_add($T::MAX, 0, 0), (1, $T::MAX - 1));
assert_eq_const_safe!(($T, $T): $T::MAX.carrying_mul_add($T::MAX, $T::MAX, 0), (0, $T::MAX));
assert_eq_const_safe!(($T, $T): $T::MAX.carrying_mul_add($T::MAX, $T::MAX, $T::MAX), ($T::MAX, $T::MAX));
}
fn test_midpoint() {
assert_eq_const_safe!(<$T>::midpoint(1, 3), 2);
assert_eq_const_safe!(<$T>::midpoint(3, 1), 2);
assert_eq_const_safe!($T: <$T>::midpoint(1, 3), 2);
assert_eq_const_safe!($T: <$T>::midpoint(3, 1), 2);
assert_eq_const_safe!(<$T>::midpoint(0, 0), 0);
assert_eq_const_safe!(<$T>::midpoint(0, 2), 1);
assert_eq_const_safe!(<$T>::midpoint(2, 0), 1);
assert_eq_const_safe!(<$T>::midpoint(2, 2), 2);
assert_eq_const_safe!($T: <$T>::midpoint(0, 0), 0);
assert_eq_const_safe!($T: <$T>::midpoint(0, 2), 1);
assert_eq_const_safe!($T: <$T>::midpoint(2, 0), 1);
assert_eq_const_safe!($T: <$T>::midpoint(2, 2), 2);
assert_eq_const_safe!(<$T>::midpoint(1, 4), 2);
assert_eq_const_safe!(<$T>::midpoint(4, 1), 2);
assert_eq_const_safe!(<$T>::midpoint(3, 4), 3);
assert_eq_const_safe!(<$T>::midpoint(4, 3), 3);
assert_eq_const_safe!($T: <$T>::midpoint(1, 4), 2);
assert_eq_const_safe!($T: <$T>::midpoint(4, 1), 2);
assert_eq_const_safe!($T: <$T>::midpoint(3, 4), 3);
assert_eq_const_safe!($T: <$T>::midpoint(4, 3), 3);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), (<$T>::MAX - <$T>::MIN) / 2);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, <$T>::MIN), (<$T>::MAX - <$T>::MIN) / 2);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
assert_eq_const_safe!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
assert_eq_const_safe!(<$T>::midpoint(<$T>::MAX, 6), (<$T>::MAX - <$T>::MIN) / 2 + 3);
assert_eq_const_safe!(<$T>::midpoint(6, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2 + 3);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
assert_eq_const_safe!($T: <$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
assert_eq_const_safe!($T: <$T>::midpoint(<$T>::MAX, 6), (<$T>::MAX - <$T>::MIN) / 2 + 3);
assert_eq_const_safe!($T: <$T>::midpoint(6, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2 + 3);
}
}
@ -365,154 +366,154 @@ macro_rules! uint_module {
test_runtime_and_compiletime! {
fn test_unbounded_shl() {
// <$T>::MIN
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 1), (<$T>::MIN << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 3), (<$T>::MIN << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, 5), (<$T>::MIN << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 1), (<$T>::MIN << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 3), (<$T>::MIN << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, 5), (<$T>::MIN << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
// <$T>::MAX
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 1), (<$T>::MAX << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 3), (<$T>::MAX << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, 5), (<$T>::MAX << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 1), (<$T>::MAX << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 3), (<$T>::MAX << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, 5), (<$T>::MAX << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
// 1
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_ONE), (1 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_TWO), (1 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_THREE), (1 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_FOUR), (1 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(1, 1), (1 << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(1, 3), (1 << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(1, 5), (1 << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_ONE), (1 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_TWO), (1 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_THREE), (1 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_TEST_FOUR), (1 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 1), (1 << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 3), (1 << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, 5), (1 << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(1, SHIFT_AMOUNT_OVERFLOW3), 0);
// !0
assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_ONE), (!0 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_TWO), (!0 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_THREE), (!0 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_FOUR), (!0 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(!0, 1), (!0 << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(!0, 3), (!0 << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(!0, 5), (!0 << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_ONE), (!0 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_TWO), (!0 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_THREE), (!0 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_TEST_FOUR), (!0 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, 1), (!0 << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, 3), (!0 << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, 5), (!0 << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(!0, SHIFT_AMOUNT_OVERFLOW3), 0);
// 8
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_ONE), (8 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_TWO), (8 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_THREE), (8 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_FOUR), (8 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(8, 1), (8 << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(8, 3), (8 << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(8, 5), (8 << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_ONE), (8 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_TWO), (8 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_THREE), (8 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_TEST_FOUR), (8 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 1), (8 << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 3), (8 << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, 5), (8 << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(8, SHIFT_AMOUNT_OVERFLOW3), 0);
// 17
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_ONE), (17 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_TWO), (17 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_THREE), (17 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_FOUR), (17 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shl(17, 1), (17 << 1));
assert_eq_const_safe!(<$T>::unbounded_shl(17, 3), (17 << 3));
assert_eq_const_safe!(<$T>::unbounded_shl(17, 5), (17 << 5));
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_ONE), (17 << SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_TWO), (17 << SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_THREE), (17 << SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_TEST_FOUR), (17 << SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 1), (17 << 1));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 3), (17 << 3));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, 5), (17 << 5));
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shl(17, SHIFT_AMOUNT_OVERFLOW3), 0);
}
fn test_unbounded_shr() {
// <$T>::MIN
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 1), (<$T>::MIN >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 3), (<$T>::MIN >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, 5), (<$T>::MIN >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_ONE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_TWO), (<$T>::MIN >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_THREE), (<$T>::MIN >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MIN >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 1), (<$T>::MIN >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 3), (<$T>::MIN >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, 5), (<$T>::MIN >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MIN, SHIFT_AMOUNT_OVERFLOW3), 0);
// <$T>::MAX
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 1), (<$T>::MAX >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 3), (<$T>::MAX >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, 5), (<$T>::MAX >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_ONE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_TWO), (<$T>::MAX >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_THREE), (<$T>::MAX >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_TEST_FOUR), (<$T>::MAX >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 1), (<$T>::MAX >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 3), (<$T>::MAX >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, 5), (<$T>::MAX >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(<$T>::MAX, SHIFT_AMOUNT_OVERFLOW3), 0);
// 1
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_ONE), (1 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_TWO), (1 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_THREE), (1 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_FOUR), (1 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(1, 1), (1 >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(1, 3), (1 >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(1, 5), (1 >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_ONE), (1 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_TWO), (1 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_THREE), (1 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_TEST_FOUR), (1 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 1), (1 >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 3), (1 >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, 5), (1 >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(1, SHIFT_AMOUNT_OVERFLOW3), 0);
// !0
assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_ONE), (!0 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_TWO), (!0 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_THREE), (!0 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_FOUR), (!0 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(!0, 1), (!0 >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(!0, 3), (!0 >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(!0, 5), (!0 >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_ONE), (!0 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_TWO), (!0 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_THREE), (!0 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_TEST_FOUR), (!0 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, 1), (!0 >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, 3), (!0 >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, 5), (!0 >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(!0, SHIFT_AMOUNT_OVERFLOW3), 0);
// 8
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_ONE), (8 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_TWO), (8 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_THREE), (8 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_FOUR), (8 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(8, 1), (8 >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(8, 3), (8 >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(8, 5), (8 >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_ONE), (8 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_TWO), (8 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_THREE), (8 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_TEST_FOUR), (8 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 1), (8 >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 3), (8 >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, 5), (8 >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(8, SHIFT_AMOUNT_OVERFLOW3), 0);
// 17
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_ONE), (17 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_TWO), (17 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_THREE), (17 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_FOUR), (17 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!(<$T>::unbounded_shr(17, 1), (17 >> 1));
assert_eq_const_safe!(<$T>::unbounded_shr(17, 3), (17 >> 3));
assert_eq_const_safe!(<$T>::unbounded_shr(17, 5), (17 >> 5));
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!(<$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW3), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_ONE), (17 >> SHIFT_AMOUNT_TEST_ONE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_TWO), (17 >> SHIFT_AMOUNT_TEST_TWO));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_THREE), (17 >> SHIFT_AMOUNT_TEST_THREE));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_TEST_FOUR), (17 >> SHIFT_AMOUNT_TEST_FOUR));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 1), (17 >> 1));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 3), (17 >> 3));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, 5), (17 >> 5));
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW2), 0);
assert_eq_const_safe!($T: <$T>::unbounded_shr(17, SHIFT_AMOUNT_OVERFLOW3), 0);
}
}
};

View file

@ -1,22 +0,0 @@
# `inline_const_pat`
The tracking issue for this feature is: [#76001]
------
This feature allows you to use inline constant expressions in pattern position:
```rust
#![feature(inline_const_pat)]
const fn one() -> i32 { 1 }
let some_int = 3;
match some_int {
const { 1 + 2 } => println!("Matched 1 + 2"),
const { one() } => println!("Matched const fn returning 1"),
_ => println!("Didn't match anything :("),
}
```
[#76001]: https://github.com/rust-lang/rust/issues/76001

View file

@ -246,7 +246,6 @@ fn emit_redundant_guards<'tcx>(
fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
for_each_expr_without_closures(expr, |expr| {
if match expr.kind {
ExprKind::ConstBlock(..) => cx.tcx.features().inline_const_pat(),
ExprKind::Call(c, ..) if let ExprKind::Path(qpath) = c.kind => {
// Allow ctors
matches!(cx.qpath_res(&qpath, c.hir_id), Res::Def(DefKind::Ctor(..), ..))

View file

@ -91,7 +91,7 @@ fn issue3728() {
fn literals() {
match 42 {
const { 1 + 2 } | 4
1 | 2 | 4
| 6 => {}
10 | 11 | 12
| 13 | 14 => {}

View file

@ -99,7 +99,7 @@ fn issue3728() {
fn literals() {
match 42 {
const { 1 + 2 } | 4 | 6 => {}
1 | 2 | 4 | 6 => {}
10 | 11 | 12 | 13 | 14 => {}
_ => {}
}

View file

@ -2873,7 +2873,6 @@ ui/macros/rfc-3086-metavar-expr/issue-111904.rs
ui/malformed/issue-107423-unused-delim-only-one-no-pair.rs
ui/malformed/issue-69341-malformed-derive-inert.rs
ui/marker_trait_attr/issue-61651-type-mismatch.rs
ui/match/issue-112438.rs
ui/match/issue-113012.rs
ui/match/issue-11319.rs
ui/match/issue-114691.rs

View file

@ -1,6 +1,5 @@
//@ pp-exact
#![feature(inline_const_pat)]
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
@ -206,9 +205,7 @@ fn _11() {
let _ = ();
()
};
let const {
#![rustc_dummy]
} =
let _ =
#[rustc_dummy] const {
#![rustc_dummy]
};

View file

@ -1,9 +0,0 @@
#![feature(inline_const_pat)]
fn main() {
match () {
const { (|| {})() } => {}
//~^ ERROR cannot call non-const closure in constants
//~| ERROR could not evaluate constant pattern
}
}

View file

@ -1,18 +0,0 @@
error[E0015]: cannot call non-const closure in constants
--> $DIR/invalid-inline-const-in-match-arm.rs:5:17
|
LL | const { (|| {})() } => {}
| ^^^^^^^^^
|
= note: closures need an RFC before allowed to be called in constants
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
error: could not evaluate constant pattern
--> $DIR/invalid-inline-const-in-match-arm.rs:5:9
|
LL | const { (|| {})() } => {}
| ^^^^^^^^^^^^^^^^^^^ could not evaluate constant
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0015`.

View file

@ -1,4 +0,0 @@
fn main() {
let const { () } = ();
//~^ ERROR inline-const in pattern position is experimental [E0658]
}

View file

@ -1,13 +0,0 @@
error[E0658]: inline-const in pattern position is experimental
--> $DIR/feature-gate-inline_const_pat.rs:2:9
|
LL | let const { () } = ();
| ^^^^^
|
= note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
= help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,7 +1,5 @@
//@ run-pass
#![allow(non_contiguous_range_endpoints)]
#![feature(inline_const_pat)]
fn main() {
let mut if_lettable = vec![];
let mut first_or = vec![];
@ -16,7 +14,6 @@ fn main() {
match x {
1 | -3..0 => first_or.push(x),
y @ (0..5 | 6) => or_two.push(y),
y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
y @ -5.. => range_from.push(y),
y @ ..-7 => assert_eq!(y, -8),
y => bottom.push(y),
@ -25,6 +22,6 @@ fn main() {
assert_eq!(if_lettable, [-1, 0, 2, 4]);
assert_eq!(first_or, [-3, -2, -1, 1]);
assert_eq!(or_two, [0, 2, 3, 4, 6]);
assert_eq!(range_from, [-5, -4, 7]);
assert_eq!(range_from, [-5, -4, 5, 7]);
assert_eq!(bottom, [-7, -6]);
}

View file

@ -18,8 +18,6 @@ fn main() {
//~^ error: expected a pattern range bound, found an expression
1 | -3..0 => first_or.push(x),
y @ (0..5 | 6) => or_two.push(y),
y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
//~^ error: inline-const in pattern position is experimental [E0658]
y @ -5.. => range_from.push(y),
y @ ..-7 => assert_eq!(y, -8),
y => bottom.push(y),

View file

@ -11,10 +11,6 @@ LL + const VAL: /* Type */ = 5+1;
LL ~ match x as i32 {
LL ~ 0..VAL => errors_only.push(x),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | 0..const { 5+1 } => errors_only.push(x),
| +++++++ +
error[E0408]: variable `n` is not bound in all patterns
--> $DIR/range_pat_interactions1.rs:10:25
@ -24,17 +20,6 @@ LL | if let n @ 2..3|4 = x {
| |
| variable not in all patterns
error[E0658]: inline-const in pattern position is experimental
--> $DIR/range_pat_interactions1.rs:21:20
|
LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
| ^^^^^
|
= note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
= help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0408, E0658.
For more information about an error, try `rustc --explain E0408`.
For more information about this error, try `rustc --explain E0408`.

View file

@ -1,22 +0,0 @@
fn main() {
let mut first_or = Vec::<i32>::new();
let mut or_two = Vec::<i32>::new();
let mut range_from = Vec::<i32>::new();
let mut bottom = Vec::<i32>::new();
let mut errors_only = Vec::<i32>::new();
for x in -9 + 1..=(9 - 2) {
match x as i32 {
0..=(5+1) => errors_only.push(x),
//~^ error: expected a pattern range bound, found an expression
//~| error: range pattern bounds cannot have parentheses
1 | -3..0 => first_or.push(x),
y @ (0..5 | 6) => or_two.push(y),
y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
//~^ error: inline-const in pattern position is experimental
y @ -5.. => range_from.push(y),
y @ ..-7 => assert_eq!(y, -8),
y => bottom.push(y),
}
}
}

View file

@ -1,43 +0,0 @@
error: range pattern bounds cannot have parentheses
--> $DIR/range_pat_interactions2.rs:10:17
|
LL | 0..=(5+1) => errors_only.push(x),
| ^ ^
|
help: remove these parentheses
|
LL - 0..=(5+1) => errors_only.push(x),
LL + 0..=5+1 => errors_only.push(x),
|
error: expected a pattern range bound, found an expression
--> $DIR/range_pat_interactions2.rs:10:18
|
LL | 0..=(5+1) => errors_only.push(x),
| ^^^ not a pattern
|
= note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
help: consider extracting the expression into a `const`
|
LL + const VAL: /* Type */ = 5+1;
LL ~ match x as i32 {
LL ~ 0..=(VAL) => errors_only.push(x),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | 0..=(const { 5+1 }) => errors_only.push(x),
| +++++++ +
error[E0658]: inline-const in pattern position is experimental
--> $DIR/range_pat_interactions2.rs:15:20
|
LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
| ^^^^^
|
= note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
= help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,19 +0,0 @@
fn main() {
let mut first_or = Vec::<i32>::new();
let mut or_two = Vec::<i32>::new();
let mut range_from = Vec::<i32>::new();
let mut bottom = Vec::<i32>::new();
for x in -9 + 1..=(9 - 2) {
match x as i32 {
8.. => bottom.push(x),
1 | -3..0 => first_or.push(x),
y @ (0..5 | 6) => or_two.push(y),
y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
//~^ inline-const in pattern position is experimental
y @ -5.. => range_from.push(y),
y @ ..-7 => assert_eq!(y, -8),
y => bottom.push(y),
}
}
}

View file

@ -1,13 +0,0 @@
error[E0658]: inline-const in pattern position is experimental
--> $DIR/range_pat_interactions3.rs:12:20
|
LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
| ^^^^^
|
= note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
= help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,16 +0,0 @@
//@ compile-flags: -Zlint-mir
//@ check-pass
#![feature(inline_const_pat)]
fn main() {
match 1 {
const {
|| match 0 {
x => 0,
};
0
} => (),
_ => (),
}
}

View file

@ -1,18 +0,0 @@
//! This test used to ICE because const blocks didn't have a body
//! anymore, making a lot of logic very fragile around handling the
//! HIR of a const block.
//! https://github.com/rust-lang/rust/issues/125846
//@ check-pass
#![feature(inline_const_pat)]
fn main() {
match 0 {
const {
let a = 10_usize;
*&a
}
| _ => {}
}
}

View file

@ -1,28 +0,0 @@
#![feature(inline_const_pat)]
// rust-lang/rust#82518: ICE with inline-const in match referencing const-generic parameter
fn foo<const V: usize>() {
match 0 {
const { V } => {},
//~^ ERROR constant pattern cannot depend on generic parameters
_ => {},
}
}
const fn f(x: usize) -> usize {
x + 1
}
fn bar<const V: usize>() {
match 0 {
const { f(V) } => {},
//~^ ERROR constant pattern cannot depend on generic parameters
_ => {},
}
}
fn main() {
foo::<1>();
bar::<1>();
}

View file

@ -1,15 +0,0 @@
error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/const-match-pat-generic.rs:7:9
|
LL | const { V } => {},
| ^^^^^^^^^^^ `const` depends on a generic parameter
error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/const-match-pat-generic.rs:19:9
|
LL | const { f(V) } => {},
| ^^^^^^^^^^^^^^ `const` depends on a generic parameter
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0158`.

View file

@ -1,11 +0,0 @@
//@ check-pass
#![feature(inline_const_pat)]
fn main() {
match 1u64 {
0 => (),
const { 0 + 1 } => (),
const { 2 - 1 } ..= const { u64::MAX } => (),
}
}

View file

@ -1,47 +0,0 @@
#![feature(inline_const_pat)]
use std::marker::PhantomData;
#[derive(PartialEq, Eq)]
pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>);
#[derive(PartialEq, Eq)]
pub struct CovariantRef<'a, T: ?Sized>(&'a T);
impl<'a, T: ?Sized> InvariantRef<'a, T> {
pub const fn new(r: &'a T) -> Self {
InvariantRef(r, PhantomData)
}
}
impl<'a> InvariantRef<'a, ()> {
pub const NEW: Self = InvariantRef::new(&());
}
impl<'a> CovariantRef<'a, ()> {
pub const NEW: Self = CovariantRef(&());
}
fn match_invariant_ref<'a>() {
let y = ();
match InvariantRef::new(&y) {
//~^ ERROR `y` does not live long enough [E0597]
const { InvariantRef::<'a>::NEW } => (),
}
}
fn match_covariant_ref<'a>() {
// Unclear if we should error here (should we be able to subtype the type of
// `y.0`), but using the associated const directly in the pattern also
// errors.
let y: (CovariantRef<'static, _>,) = (CovariantRef(&()),);
//~^ ERROR lifetime may not live long enough
match y.0 {
const { CovariantRef::<'a>::NEW } => (),
}
}
fn main() {
match_invariant_ref();
match_covariant_ref();
}

View file

@ -1,28 +0,0 @@
error[E0597]: `y` does not live long enough
--> $DIR/const-match-pat-lifetime-err.rs:27:29
|
LL | fn match_invariant_ref<'a>() {
| -- lifetime `'a` defined here
LL | let y = ();
| - binding `y` declared here
LL | match InvariantRef::new(&y) {
| ^^ borrowed value does not live long enough
LL |
LL | const { InvariantRef::<'a>::NEW } => (),
| ----------------------- using this value as a constant requires that `y` is borrowed for `'a`
LL | }
LL | }
| - `y` dropped here while still borrowed
error: lifetime may not live long enough
--> $DIR/const-match-pat-lifetime-err.rs:37:12
|
LL | fn match_covariant_ref<'a>() {
| -- lifetime `'a` defined here
...
LL | let y: (CovariantRef<'static, _>,) = (CovariantRef(&()),);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0597`.

View file

@ -1,34 +0,0 @@
//@ run-pass
#![feature(inline_const_pat)]
use std::marker::PhantomData;
// rust-lang/rust#78174: ICE: "cannot convert ReErased to a region vid"
fn issue_78174() {
match "foo" {
const { concat!("fo", "o") } => (),
_ => unreachable!(),
}
}
#[derive(PartialEq, Eq)]
pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>);
impl<'a, T: ?Sized> InvariantRef<'a, T> {
pub const fn new(r: &'a T) -> Self {
InvariantRef(r, PhantomData)
}
}
fn match_invariant_ref<'a>() {
match const { InvariantRef::<'a, _>::new(&()) } {
const { InvariantRef::<'a, ()>::new(&()) } => {
}
}
}
fn main() {
issue_78174();
match_invariant_ref();
}

View file

@ -1,38 +0,0 @@
//@ build-pass
#![feature(inline_const_pat)]
fn main() {
const N: u32 = 10;
let x: u32 = 3;
match x {
1 ..= const { N + 1 } => {},
_ => {},
}
match x {
const { N - 1 } ..= 10 => {},
_ => {},
}
match x {
const { N - 1 } ..= const { N + 1 } => {},
_ => {},
}
match x {
.. const { N + 1 } => {},
_ => {},
}
match x {
const { N - 1 } .. => {},
_ => {},
}
match x {
..= const { N + 1 } => {},
_ => {}
}
}

View file

@ -1,20 +0,0 @@
//@ run-pass
#![feature(inline_const_pat)]
const MMIO_BIT1: u8 = 4;
const MMIO_BIT2: u8 = 5;
fn main() {
let s = match read_mmio() {
0 => "FOO",
const { 1 << MMIO_BIT1 } => "BAR",
const { 1 << MMIO_BIT2 } => "BAZ",
_ => unreachable!(),
};
assert_eq!("BAZ", s);
}
fn read_mmio() -> i32 {
1 << 5
}

View file

@ -0,0 +1,11 @@
// While `feature(inline_const_pat)` has been removed from the
// compiler, we should still make sure that the resulting error
// message is acceptable.
fn main() {
match 1 {
const { 1 + 7 } => {}
//~^ `inline_const_pat` has been removed
2 => {}
_ => {}
}
}

View file

@ -0,0 +1,10 @@
error: `inline_const_pat` has been removed
--> $DIR/in-pat-recovery.rs:6:15
|
LL | const { 1 + 7 } => {}
| ^^^^^^^^^
|
= help: use a named `const`-item or an `if`-guard instead
error: aborting due to 1 previous error

View file

@ -1,12 +0,0 @@
#![feature(inline_const_pat)]
fn uwu() {}
fn main() {
let x = [];
match x[123] {
const { uwu } => {}
//~^ ERROR `fn() {uwu}` cannot be used in patterns
_ => {}
}
}

View file

@ -1,8 +0,0 @@
error: fn item `fn() {uwu}` cannot be used in patterns
--> $DIR/pat-match-fndef.rs:8:9
|
LL | const { uwu } => {}
| ^^^^^^^^^^^^^ fn item can't be used in patterns
error: aborting due to 1 previous error

View file

@ -1,22 +0,0 @@
#![feature(inline_const_pat)]
const unsafe fn require_unsafe() -> usize {
1
}
fn main() {
match () {
const {
require_unsafe();
//~^ ERROR [E0133]
} => (),
}
match 1 {
const {
require_unsafe()
//~^ ERROR [E0133]
}..=4 => (),
_ => (),
}
}

View file

@ -1,19 +0,0 @@
error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
--> $DIR/pat-unsafe-err.rs:10:13
|
LL | require_unsafe();
| ^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
--> $DIR/pat-unsafe-err.rs:17:13
|
LL | require_unsafe()
| ^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0133`.

View file

@ -1,29 +0,0 @@
//@ check-pass
#![warn(unused_unsafe)]
#![feature(inline_const_pat)]
const unsafe fn require_unsafe() -> usize {
1
}
fn main() {
unsafe {
match () {
const {
require_unsafe();
unsafe {}
//~^ WARNING unnecessary `unsafe` block
} => (),
}
match 1 {
const {
unsafe {}
//~^ WARNING unnecessary `unsafe` block
require_unsafe()
}..=4 => (),
_ => (),
}
}
}

View file

@ -1,20 +0,0 @@
warning: unnecessary `unsafe` block
--> $DIR/pat-unsafe.rs:15:17
|
LL | unsafe {}
| ^^^^^^ unnecessary `unsafe` block
|
note: the lint level is defined here
--> $DIR/pat-unsafe.rs:3:9
|
LL | #![warn(unused_unsafe)]
| ^^^^^^^^^^^^^
warning: unnecessary `unsafe` block
--> $DIR/pat-unsafe.rs:22:17
|
LL | unsafe {}
| ^^^^^^ unnecessary `unsafe` block
warning: 2 warnings emitted

View file

@ -1,44 +0,0 @@
//@ check-pass
#![feature(inline_const_pat)]
#![deny(dead_code)]
const fn one() -> i32 {
1
}
const fn two() -> i32 {
2
}
const fn three() -> i32 {
3
}
fn inline_const() {
// rust-lang/rust#78171: dead_code lint triggers even though function is used in const pattern
match 1 {
const { one() } => {}
_ => {}
}
}
fn inline_const_range() {
match 1 {
1 ..= const { two() } => {}
_ => {}
}
}
struct S<const C: i32>;
fn const_generic_arg() {
match S::<3> {
S::<{three()}> => {}
}
}
fn main() {
inline_const();
inline_const_range();
const_generic_arg();
}

View file

@ -1,10 +0,0 @@
//@ run-pass
#![feature(inline_const_pat)]
#![allow(dead_code)]
fn foo<const V: usize>() {
match 0 {
const { 1 << 5 } | _ => {}
}
}
fn main() {}

View file

@ -1,4 +1,3 @@
#![feature(inline_const_pat)]
#![allow(overlapping_range_endpoints)]
fn main() {
@ -17,8 +16,6 @@ fn main() {
// There isn't really a way to detect these
1..=TOO_BIG => {}
//~^ ERROR lower range bound must be less than or equal to upper
1..=const { 256 } => {}
//~^ ERROR lower range bound must be less than or equal to upper
_ => {}
}

View file

@ -1,59 +1,53 @@
error: literal out of range for `u8`
--> $DIR/validate-range-endpoints.rs:7:12
--> $DIR/validate-range-endpoints.rs:6:12
|
LL | 1..257 => {}
| ^^^ this value does not fit into the type `u8` whose range is `0..=255`
error: literal out of range for `u8`
--> $DIR/validate-range-endpoints.rs:9:13
--> $DIR/validate-range-endpoints.rs:8:13
|
LL | 1..=256 => {}
| ^^^ this value does not fit into the type `u8` whose range is `0..=255`
error[E0030]: lower range bound must be less than or equal to upper
--> $DIR/validate-range-endpoints.rs:18:9
--> $DIR/validate-range-endpoints.rs:17:9
|
LL | 1..=TOO_BIG => {}
| ^^^^^^^^^^^ lower bound larger than upper bound
error[E0030]: lower range bound must be less than or equal to upper
--> $DIR/validate-range-endpoints.rs:20:9
|
LL | 1..=const { 256 } => {}
| ^^^^^^^^^^^^^^^^^ lower bound larger than upper bound
error: literal out of range for `u64`
--> $DIR/validate-range-endpoints.rs:26:32
--> $DIR/validate-range-endpoints.rs:23:32
|
LL | 10000000000000000000..=99999999999999999999 => {}
| ^^^^^^^^^^^^^^^^^^^^ this value does not fit into the type `u64` whose range is `0..=18446744073709551615`
error: literal out of range for `i8`
--> $DIR/validate-range-endpoints.rs:32:12
--> $DIR/validate-range-endpoints.rs:29:12
|
LL | 0..129 => {}
| ^^^ this value does not fit into the type `i8` whose range is `-128..=127`
error: literal out of range for `i8`
--> $DIR/validate-range-endpoints.rs:34:13
--> $DIR/validate-range-endpoints.rs:31:13
|
LL | 0..=128 => {}
| ^^^ this value does not fit into the type `i8` whose range is `-128..=127`
error: literal out of range for `i8`
--> $DIR/validate-range-endpoints.rs:36:9
--> $DIR/validate-range-endpoints.rs:33:9
|
LL | -129..0 => {}
| ^^^^ this value does not fit into the type `i8` whose range is `-128..=127`
error: literal out of range for `i8`
--> $DIR/validate-range-endpoints.rs:38:9
--> $DIR/validate-range-endpoints.rs:35:9
|
LL | -10000..=-20 => {}
| ^^^^^^ this value does not fit into the type `i8` whose range is `-128..=127`
error[E0004]: non-exhaustive patterns: `i8::MIN..=-17_i8` and `1_i8..=i8::MAX` not covered
--> $DIR/validate-range-endpoints.rs:49:11
--> $DIR/validate-range-endpoints.rs:46:11
|
LL | match 0i8 {
| ^^^ patterns `i8::MIN..=-17_i8` and `1_i8..=i8::MAX` not covered
@ -66,7 +60,7 @@ LL + i8::MIN..=-17_i8 | 1_i8..=i8::MAX => todo!()
|
error[E0004]: non-exhaustive patterns: `i8::MIN..=-17_i8` not covered
--> $DIR/validate-range-endpoints.rs:53:11
--> $DIR/validate-range-endpoints.rs:50:11
|
LL | match 0i8 {
| ^^^ pattern `i8::MIN..=-17_i8` not covered
@ -78,7 +72,7 @@ LL ~ -10000.. => {},
LL + i8::MIN..=-17_i8 => todo!()
|
error: aborting due to 11 previous errors
error: aborting due to 10 previous errors
Some errors have detailed explanations: E0004, E0030.
For more information about an error, try `rustc --explain E0004`.

View file

@ -16,10 +16,6 @@ LL + const VAL: /* Type */ = tmp[0];
LL ~ match z {
LL ~ VAL => {}
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { tmp[0] } => {}
| +++++++ +
error: aborting due to 1 previous error

View file

@ -17,10 +17,6 @@ LL ~ match 0 {
LL | x => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x.y } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:6:9
@ -42,10 +38,6 @@ LL | x => (),
LL | x.y => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x.0 } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:7:9
@ -68,10 +60,6 @@ LL | x.y => (),
LL | x.0 => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x._0 } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:8:9
@ -94,10 +82,6 @@ LL | x => (),
LL | x._0 => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x.0.1 } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:9:9
@ -120,10 +104,6 @@ LL | x => (),
LL | x.0.1 => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x.4.y.17.__z } => (),
| +++++++ +
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
--> $DIR/recover-pat-exprs.rs:12:12
@ -173,10 +153,6 @@ LL + const VAL: /* Type */ = x[0];
LL ~ match 0 {
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x[0] } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:24:9
@ -197,10 +173,6 @@ LL ~ match 0 {
LL | x[0] => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x[..] } => (),
| +++++++ +
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
--> $DIR/recover-pat-exprs.rs:27:12
@ -247,10 +219,6 @@ LL + const VAL: /* Type */ = x.f();
LL ~ match 0 {
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x.f() } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:38:9
@ -271,10 +239,6 @@ LL ~ match 0 {
LL | x.f() => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x._f() } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:39:9
@ -296,10 +260,6 @@ LL | x.f() => (),
LL | x._f() => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x? } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:40:9
@ -322,10 +282,6 @@ LL | x._f() => (),
LL | x? => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { ().f() } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:41:9
@ -348,10 +304,6 @@ LL | x.f() => (),
LL | ().f() => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { (0, x)?.f() } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:42:9
@ -374,10 +326,6 @@ LL | x.f() => (),
LL | (0, x)?.f() => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x.f().g() } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:43:9
@ -400,10 +348,6 @@ LL | x.f() => (),
LL | x.f().g() => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { 0.f()?.g()?? } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:50:9
@ -423,10 +367,6 @@ LL + const VAL: /* Type */ = x as usize;
LL ~ match 0 {
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x as usize } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:51:9
@ -447,10 +387,6 @@ LL ~ match 0 {
LL | x as usize => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { 0 as usize } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:52:9
@ -472,10 +408,6 @@ LL | x as usize => (),
LL | 0 as usize => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x.f().0.4 as f32 } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:59:9
@ -495,10 +427,6 @@ LL + const VAL: /* Type */ = 1 + 1;
LL ~ match 0 {
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { 1 + 1 } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:60:9
@ -519,10 +447,6 @@ LL ~ match 0 {
LL | 1 + 1 => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { (1 + 2) * 3 } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:63:9
@ -545,10 +469,6 @@ LL | 1 + 1 => (),
LL |
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x.0 > 2 } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:64:9
@ -571,10 +491,6 @@ LL | 1 + 1 => (),
LL | x.0 > 2 => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { x.0 == 2 } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:69:13
@ -594,10 +510,6 @@ LL + const VAL: /* Type */ = y.0 > 2;
LL ~ match (0, 0) {
LL ~ (x, VAL) if x != 0 => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | (x, const { y.0 > 2 }) if x != 0 => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:70:13
@ -618,10 +530,6 @@ LL ~ match (0, 0) {
LL | (x, y.0 > 2) if x != 0 => (),
LL ~ (x, VAL) if x != 0 || x != 1 => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | (x, const { y.0 > 2 }) if x != 0 || x != 1 => (),
| +++++++ +
error: left-hand side of `@` must be a binding
--> $DIR/recover-pat-exprs.rs:83:9
@ -658,10 +566,6 @@ LL + const VAL: /* Type */ = u8::MAX.abs();
LL ~ match u8::MAX {
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { u8::MAX.abs() } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:86:17
@ -684,10 +588,6 @@ LL | u8::MAX.abs() => (),
LL |
LL ~ z @ w @ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | z @ w @ const { v.u() } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:88:9
@ -710,10 +610,6 @@ LL | u8::MAX.abs() => (),
LL |
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { y.ilog(3) } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:90:9
@ -736,10 +632,6 @@ LL | u8::MAX.abs() => (),
LL |
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { n + 1 } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:92:10
@ -762,10 +654,6 @@ LL | u8::MAX.abs() => (),
LL |
LL ~ (VAL) => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | (const { "".f() + 14 * 8 }) => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:95:9
@ -788,10 +676,6 @@ LL | u8::MAX.abs() => (),
LL | 0 | ((1) | 2) | 3 => (),
LL ~ VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { f?() } => (),
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:101:9

View file

@ -16,10 +16,6 @@ LL + const VAL: /* Type */ = "hi".to_owned();
LL ~ match foo {
LL ~ Foo(VAL) => true,
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | Foo(const { "hi".to_owned() }) => true,
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-issues.rs:14:20
@ -39,10 +35,6 @@ LL + const BAZ: /* Type */ = "hi".to_owned();
LL ~ match bar {
LL ~ Bar { baz: BAZ } => true,
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | Bar { baz: const { "hi".to_owned() } } => true,
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-issues.rs:25:11
@ -62,10 +54,6 @@ LL + const VAL: /* Type */ = "foo".to_string();
LL ~ match foo.as_slice() {
LL ~ &[VAL] => {}
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | &[const { "foo".to_string() }] => {}
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-issues.rs:36:17
@ -79,10 +67,6 @@ help: consider extracting the expression into a `const`
LL + const VAL: /* Type */ = MAGIC.0 as usize;
LL ~ if let Some(VAL) = None::<usize> {}
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | if let Some(const { MAGIC.0 as usize }) = None::<usize> {}
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-issues.rs:41:13
@ -96,10 +80,6 @@ help: consider extracting the expression into a `const`
LL + const VAL: /* Type */ = -1.some(4);
LL ~ if let (VAL) = (0, Some(4)) {}
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | if let (const { -1.some(4) }) = (0, Some(4)) {}
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-issues.rs:44:13
@ -113,10 +93,6 @@ help: consider extracting the expression into a `const`
LL + const VAL: /* Type */ = -1.Some(4);
LL ~ if let (VAL) = (0, Some(4)) {}
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | if let (const { -1.Some(4) }) = (0, Some(4)) {}
| +++++++ +
error: aborting due to 6 previous errors

View file

@ -34,10 +34,6 @@ help: consider extracting the expression into a `const`
LL + const VAL: /* Type */ = 1 + 1;
LL ~ let Some(VAL) = x else {
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | let Some(const { 1 + 1 }) = x else {
| +++++++ +
error: expected a pattern, found an expression
--> $DIR/recover-pat-lets.rs:17:17
@ -51,10 +47,6 @@ help: consider extracting the expression into a `const`
LL + const VAL: /* Type */ = 1 + 1;
LL ~ if let Some(VAL) = x {
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | if let Some(const { 1 + 1 }) = x {
| +++++++ +
error: aborting due to 5 previous errors

View file

@ -98,10 +98,6 @@ LL | 0..=1 => (),
LL |
LL ~ ..=VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | ..=const { 1 + 2 } => (),
| +++++++ +
error: expected a pattern range bound, found an expression
--> $DIR/recover-pat-ranges.rs:15:10
@ -119,10 +115,6 @@ LL | 0..=1 => (),
LL |
LL ~ (VAL).. => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | (const { -4 + 0 }).. => (),
| +++++++ +
error: expected a pattern range bound, found an expression
--> $DIR/recover-pat-ranges.rs:18:10
@ -140,10 +132,6 @@ LL | 0..=1 => (),
LL |
LL ~ (VAL)...1 * 2 => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | (const { 1 + 4 })...1 * 2 => (),
| +++++++ +
error: expected a pattern range bound, found an expression
--> $DIR/recover-pat-ranges.rs:18:19
@ -161,10 +149,6 @@ LL | 0..=1 => (),
LL |
LL ~ (1 + 4)...VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | (1 + 4)...const { 1 * 2 } => (),
| +++++++ +
error: expected a pattern range bound, found an expression
--> $DIR/recover-pat-ranges.rs:24:9
@ -182,10 +166,6 @@ LL | 0..=1 => (),
LL |
LL ~ VAL..="y".z() => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | const { 0.x() }..="y".z() => (),
| +++++++ +
error: expected a pattern range bound, found an expression
--> $DIR/recover-pat-ranges.rs:24:17
@ -203,10 +183,6 @@ LL | 0..=1 => (),
LL |
LL ~ 0.x()..=VAL => (),
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | 0.x()..=const { "y".z() } => (),
| +++++++ +
warning: `...` range patterns are deprecated
--> $DIR/recover-pat-ranges.rs:18:16

View file

@ -84,10 +84,6 @@ LL + const VAL: /* Type */ = 2 + _;
LL ~ match 9 {
LL ~ 4..=(VAL) => ()
|
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
LL | 4..=(const { 2 + _ }) => ()
| +++++++ +
error: aborting due to 11 previous errors

View file

@ -1,14 +1,29 @@
//@ edition:2021
#![allow(unreachable_code)]
#![feature(const_async_blocks)]
#![feature(inline_const_pat)]
fn main() {
match loop {} {
const { || {} } => {} //~ ERROR cannot be used in patterns
struct AnyOption<T>(T);
impl<T> AnyOption<T> {
const NONE: Option<T> = None;
}
fn uwu() {}
fn defines() {
match Some(uwu) {
AnyOption::<_>::NONE => {}
//~^ ERROR constant of non-structural type
_ => {}
}
match loop {} {
const { async {} } => {} //~ ERROR cannot be used in patterns
match Some(|| {}) {
AnyOption::<_>::NONE => {}
//~^ ERROR constant of non-structural type
_ => {}
}
match Some(async {}) {
AnyOption::<_>::NONE => {}
//~^ ERROR constant of non-structural type
_ => {}
}
}
fn main() {}

View file

@ -1,14 +1,42 @@
error: closure `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns
--> $DIR/non-structural-match-types.rs:9:9
|
LL | const { || {} } => {}
| ^^^^^^^^^^^^^^^ closure can't be used in patterns
error: `async` block `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns
error: constant of non-structural type `Option<fn() {uwu}>` in a pattern
--> $DIR/non-structural-match-types.rs:12:9
|
LL | const { async {} } => {}
| ^^^^^^^^^^^^^^^^^^ `async` block can't be used in patterns
LL | impl<T> AnyOption<T> {
| --------------------
LL | const NONE: Option<T> = None;
| --------------------- constant defined here
...
LL | AnyOption::<_>::NONE => {}
| ^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: aborting due to 2 previous errors
error: constant of non-structural type `Option<{closure@$DIR/non-structural-match-types.rs:17:16: 17:18}>` in a pattern
--> $DIR/non-structural-match-types.rs:18:9
|
LL | impl<T> AnyOption<T> {
| --------------------
LL | const NONE: Option<T> = None;
| --------------------- constant defined here
...
LL | AnyOption::<_>::NONE => {}
| ^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: constant of non-structural type `Option<{async block@$DIR/non-structural-match-types.rs:23:16: 23:21}>` in a pattern
--> $DIR/non-structural-match-types.rs:24:9
|
LL | impl<T> AnyOption<T> {
| --------------------
LL | const NONE: Option<T> = None;
| --------------------- constant defined here
...
LL | AnyOption::<_>::NONE => {}
| ^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
= note: `ResumeTy` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
error: aborting due to 3 previous errors

View file

@ -1,10 +0,0 @@
#![feature(pattern_types)]
#![feature(pattern_type_macro)]
#![feature(inline_const_pat)]
//@ check-pass
use std::pat::pattern_type;
fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
fn main() {}

View file

@ -1,23 +0,0 @@
// Check that ref mut patterns within a const pattern don't get considered
// unsafe because they're within a pattern for a layout constrained stuct.
//@ check-pass
#![feature(rustc_attrs)]
#![feature(inline_const_pat)]
#[rustc_layout_scalar_valid_range_start(3)]
struct Gt2(i32);
fn main() {
match unsafe { Gt2(5) } {
Gt2(
const {
|| match () {
ref mut y => (),
};
4
},
) => (),
_ => (),
}
}