Rollup merge of #118157 - Nadrieril:never_pat-feature-gate, r=compiler-errors
Add `never_patterns` feature gate This PR adds the feature gate and most basic parsing for the experimental `never_patterns` feature. See the tracking issue (https://github.com/rust-lang/rust/issues/118155) for details on the experiment. `@scottmcm` has agreed to be my lang-team liaison for this experiment.
This commit is contained in:
commit
071f8f610d
@ -46,7 +46,7 @@ fn array_rec(pats: &[Pat<'_>]) -> bool {
|
||||
pats.iter().all(unary_pattern)
|
||||
}
|
||||
match &pat.kind {
|
||||
PatKind::Slice(_, _, _) | PatKind::Range(_, _, _) | PatKind::Binding(..) | PatKind::Wild | PatKind::Or(_) => {
|
||||
PatKind::Slice(_, _, _) | PatKind::Range(_, _, _) | PatKind::Binding(..) | PatKind::Wild | PatKind::Never | PatKind::Or(_) => {
|
||||
false
|
||||
},
|
||||
PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)),
|
||||
|
@ -150,6 +150,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
|
||||
#[derive(Clone, Copy)]
|
||||
enum NormalizedPat<'a> {
|
||||
Wild,
|
||||
Never,
|
||||
Struct(Option<DefId>, &'a [(Symbol, Self)]),
|
||||
Tuple(Option<DefId>, &'a [Self]),
|
||||
Or(&'a [Self]),
|
||||
@ -229,6 +230,7 @@ fn from_pat(cx: &LateContext<'_>, arena: &'a DroplessArena, pat: &'a Pat<'_>) ->
|
||||
PatKind::Binding(.., Some(pat)) | PatKind::Box(pat) | PatKind::Ref(pat, _) => {
|
||||
Self::from_pat(cx, arena, pat)
|
||||
},
|
||||
PatKind::Never => Self::Never,
|
||||
PatKind::Struct(ref path, fields, _) => {
|
||||
let fields =
|
||||
arena.alloc_from_iter(fields.iter().map(|f| (f.ident.name, Self::from_pat(cx, arena, f.pat))));
|
||||
@ -333,6 +335,7 @@ fn from_pat(cx: &LateContext<'_>, arena: &'a DroplessArena, pat: &'a Pat<'_>) ->
|
||||
fn has_overlapping_values(&self, other: &Self) -> bool {
|
||||
match (*self, *other) {
|
||||
(Self::Wild, _) | (_, Self::Wild) => true,
|
||||
(Self::Never, Self::Never) => true,
|
||||
(Self::Or(pats), ref other) | (ref other, Self::Or(pats)) => {
|
||||
pats.iter().any(|pat| pat.has_overlapping_values(other))
|
||||
},
|
||||
|
@ -226,7 +226,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
|
||||
// Therefore they are not some form of constructor `C`,
|
||||
// with which a pattern `C(p_0)` may be formed,
|
||||
// which we would want to join with other `C(p_j)`s.
|
||||
Ident(.., None) | Lit(_) | Wild | Path(..) | Range(..) | Rest | MacCall(_)
|
||||
Ident(.., None) | Lit(_) | Wild | Never | Path(..) | Range(..) | Rest | MacCall(_)
|
||||
// Skip immutable refs, as grouping them saves few characters,
|
||||
// and almost always requires adding parens (increasing noisiness).
|
||||
// In the case of only two patterns, replacement adds net characters.
|
||||
|
@ -629,6 +629,7 @@ macro_rules! kind {
|
||||
|
||||
match pat.value.kind {
|
||||
PatKind::Wild => kind!("Wild"),
|
||||
PatKind::Never => kind!("Never"),
|
||||
PatKind::Binding(ann, _, name, sub) => {
|
||||
bind!(self, name);
|
||||
opt_bind!(self, sub);
|
||||
|
@ -1017,6 +1017,7 @@ pub fn hash_pat(&mut self, pat: &Pat<'_>) {
|
||||
}
|
||||
e.hash(&mut self.s);
|
||||
},
|
||||
PatKind::Never => {},
|
||||
PatKind::Wild => {},
|
||||
}
|
||||
}
|
||||
|
@ -1707,6 +1707,7 @@ fn are_refutable<'a, I: IntoIterator<Item = &'a Pat<'a>>>(cx: &LateContext<'_>,
|
||||
|
||||
match pat.kind {
|
||||
PatKind::Wild => false,
|
||||
PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable.
|
||||
PatKind::Binding(_, _, _, pat) => pat.map_or(false, |pat| is_refutable(cx, pat)),
|
||||
PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat),
|
||||
PatKind::Lit(..) | PatKind::Range(..) => true,
|
||||
|
Loading…
Reference in New Issue
Block a user