core/
pat.rs

1//! Helper module for exporting the `pattern_type` macro
2
3/// Creates a pattern type.
4/// ```ignore (cannot test this from within core yet)
5/// type Positive = std::pat::pattern_type!(i32 is 1..);
6/// ```
7#[macro_export]
8#[rustc_builtin_macro(pattern_type)]
9#[unstable(feature = "pattern_type_macro", issue = "123646")]
10macro_rules! pattern_type {
11    ($($arg:tt)*) => {
12        /* compiler built-in */
13    };
14}
15
16/// A trait implemented for integer types and `char`.
17/// Useful in the future for generic pattern types, but
18/// used right now to simplify ast lowering of pattern type ranges.
19#[unstable(feature = "pattern_type_range_trait", issue = "123646")]
20#[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
21#[diagnostic::on_unimplemented(
22    message = "`{Self}` is not a valid base type for range patterns",
23    label = "only integer types and `char` are supported"
24)]
25pub const trait RangePattern {
26    /// Trait version of the inherent `MIN` assoc const.
27    #[lang = "RangeMin"]
28    const MIN: Self;
29
30    /// Trait version of the inherent `MIN` assoc const.
31    #[lang = "RangeMax"]
32    const MAX: Self;
33
34    /// A compile-time helper to subtract 1 for exclusive ranges.
35    #[lang = "RangeSub"]
36    #[track_caller]
37    fn sub_one(self) -> Self;
38}
39
40macro_rules! impl_range_pat {
41    ($($ty:ty,)*) => {
42        $(
43            #[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
44            impl const RangePattern for $ty {
45                const MIN: $ty = <$ty>::MIN;
46                const MAX: $ty = <$ty>::MAX;
47                fn sub_one(self) -> Self {
48                    match self.checked_sub(1) {
49                        Some(val) => val,
50                        None => panic!("exclusive range end at minimum value of type")
51                    }
52                }
53            }
54        )*
55    }
56}
57
58impl_range_pat! {
59    i8, i16, i32, i64, i128, isize,
60    u8, u16, u32, u64, u128, usize,
61}
62
63#[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
64impl const RangePattern for char {
65    const MIN: Self = char::MIN;
66
67    const MAX: Self = char::MAX;
68
69    fn sub_one(self) -> Self {
70        match char::from_u32(self as u32 - 1) {
71            None => panic!("exclusive range to start of valid chars"),
72            Some(val) => val,
73        }
74    }
75}