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#[const_trait]
22#[diagnostic::on_unimplemented(
23    message = "`{Self}` is not a valid base type for range patterns",
24    label = "only integer types and `char` are supported"
25)]
26pub trait RangePattern {
27    /// Trait version of the inherent `MIN` assoc const.
28    #[cfg_attr(not(bootstrap), lang = "RangeMin")]
29    const MIN: Self;
30
31    /// Trait version of the inherent `MIN` assoc const.
32    #[cfg_attr(not(bootstrap), lang = "RangeMax")]
33    const MAX: Self;
34
35    /// A compile-time helper to subtract 1 for exclusive ranges.
36    #[cfg_attr(not(bootstrap), lang = "RangeSub")]
37    #[track_caller]
38    fn sub_one(self) -> Self;
39}
40
41macro_rules! impl_range_pat {
42    ($($ty:ty,)*) => {
43        $(
44            #[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
45            impl const RangePattern for $ty {
46                const MIN: $ty = <$ty>::MIN;
47                const MAX: $ty = <$ty>::MAX;
48                fn sub_one(self) -> Self {
49                    match self.checked_sub(1) {
50                        Some(val) => val,
51                        None => panic!("exclusive range end at minimum value of type")
52                    }
53                }
54            }
55        )*
56    }
57}
58
59impl_range_pat! {
60    i8, i16, i32, i64, i128, isize,
61    u8, u16, u32, u64, u128, usize,
62}
63
64#[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
65impl const RangePattern for char {
66    const MIN: Self = char::MIN;
67
68    const MAX: Self = char::MAX;
69
70    fn sub_one(self) -> Self {
71        match char::from_u32(self as u32 - 1) {
72            None => panic!("exclusive range to start of valid chars"),
73            Some(val) => val,
74        }
75    }
76}