| //! Helper module for exporting the `pattern_type` macro | |
| use crate::marker::{Freeze, PointeeSized, Unsize}; | |
| use crate::ops::{CoerceUnsized, DispatchFromDyn}; | |
| /// Creates a pattern type. | |
| /// ```ignore (cannot test this from within core yet) | |
| /// type Positive = std::pat::pattern_type!(i32 is 1..); | |
| /// ``` | |
| #[macro_export] | |
| #[rustc_builtin_macro(pattern_type)] | |
| #[unstable(feature = "pattern_type_macro", issue = "123646")] | |
| macro_rules! pattern_type { | |
| ($($arg:tt)*) => { | |
| /* compiler built-in */ | |
| }; | |
| } | |
| /// A trait implemented for integer types and `char`. | |
| /// Useful in the future for generic pattern types, but | |
| /// used right now to simplify ast lowering of pattern type ranges. | |
| #[unstable(feature = "pattern_type_range_trait", issue = "123646")] | |
| #[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")] | |
| #[diagnostic::on_unimplemented( | |
| message = "`{Self}` is not a valid base type for range patterns", | |
| label = "only integer types and `char` are supported" | |
| )] | |
| pub const trait RangePattern { | |
| /// Trait version of the inherent `MIN` assoc const. | |
| #[lang = "RangeMin"] | |
| const MIN: Self; | |
| /// Trait version of the inherent `MIN` assoc const. | |
| #[lang = "RangeMax"] | |
| const MAX: Self; | |
| /// A compile-time helper to subtract 1 for exclusive ranges. | |
| #[lang = "RangeSub"] | |
| #[track_caller] | |
| fn sub_one(self) -> Self; | |
| } | |
| macro_rules! impl_range_pat { | |
| ($($ty:ty,)*) => { | |
| $( | |
| #[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")] | |
| const impl RangePattern for $ty { | |
| const MIN: $ty = <$ty>::MIN; | |
| const MAX: $ty = <$ty>::MAX; | |
| fn sub_one(self) -> Self { | |
| match self.checked_sub(1) { | |
| Some(val) => val, | |
| None => panic!("exclusive range end at minimum value of type") | |
| } | |
| } | |
| } | |
| )* | |
| } | |
| } | |
| impl_range_pat! { | |
| i8, i16, i32, i64, i128, isize, | |
| u8, u16, u32, u64, u128, usize, | |
| } | |
| #[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")] | |
| const impl RangePattern for char { | |
| const MIN: Self = char::MIN; | |
| const MAX: Self = char::MAX; | |
| fn sub_one(self) -> Self { | |
| match char::from_u32(self as u32 - 1) { | |
| None => panic!("exclusive range to start of valid chars"), | |
| Some(val) => val, | |
| } | |
| } | |
| } | |
| impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<pattern_type!(*const U is !null)> for pattern_type!(*const T is !null) where | |
| T: Unsize<U> | |
| { | |
| } | |
| impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<pattern_type!(U is !null)> for pattern_type!(T is !null) {} | |
| impl<T: PointeeSized> Unpin for pattern_type!(*const T is !null) {} | |
| unsafe impl<T: PointeeSized> Freeze for pattern_type!(*const T is !null) {} | |
| unsafe impl<T: PointeeSized> Freeze for pattern_type!(*mut T is !null) {} |