Skip to content

Commit 75b3a4c

Browse files
Rollup merge of rust-lang#136922 - oli-obk:pattern-types-option-ends, r=BoxyUwU
Pattern types: Avoid having to handle an Option for range ends in the type system or the HIR Instead, 1. during hir_ty_lowering, we now generate constants for the min/max when the range doesn't have a start/end specified. 2. in a later commit we generate those constants during ast lowering, simplifying everything further by not having to handle the range end inclusivity anymore in the type system (and thus avoiding any issues of `0..5` being different from `0..=4` I think it makes all the type system code simpler, and the cost of the extra `ConstKind::Value` processing seems negligible. r? `@BoxyUwU` cc `@joshtriplett` `@scottmcm`
2 parents f0cd1b9 + 65914ce commit 75b3a4c

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

core/src/pat.rs

+62
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,65 @@ macro_rules! pattern_type {
1212
/* compiler built-in */
1313
};
1414
}
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+
)]
26+
pub 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+
41+
macro_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+
59+
impl_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")]
65+
impl 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+
}

0 commit comments

Comments
 (0)