pat.rs - source
Description: Source of the Rust file `library/core/src/pat.rs`.

#
core/
pat.rs

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