Skip to content

Commit

Permalink
Rollup merge of rust-lang#118157 - Nadrieril:never_pat-feature-gate, …
Browse files Browse the repository at this point in the history
…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 (rust-lang#118155) for details on the experiment.

`@scottmcm` has agreed to be my lang-team liaison for this experiment.
  • Loading branch information
matthiaskrgr authored Nov 29, 2023
2 parents 684c4bf + 02e50f0 commit 071f8f6
Show file tree
Hide file tree
Showing 6 changed files with 8 additions and 2 deletions.
2 changes: 1 addition & 1 deletion clippy_lints/src/equatable_if_let.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn unary_pattern(pat: &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)),
Expand Down
3 changes: 3 additions & 0 deletions clippy_lints/src/matches/match_same_arms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]),
Expand Down Expand Up @@ -229,6 +230,7 @@ impl<'a> NormalizedPat<'a> {
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))));
Expand Down Expand Up @@ -333,6 +335,7 @@ impl<'a> NormalizedPat<'a> {
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))
},
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/unnested_or_patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/utils/author.rs
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {

match pat.value.kind {
PatKind::Wild => kind!("Wild"),
PatKind::Never => kind!("Never"),
PatKind::Binding(ann, _, name, sub) => {
bind!(self, name);
opt_bind!(self, sub);
Expand Down
1 change: 1 addition & 0 deletions clippy_utils/src/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
}
e.hash(&mut self.s);
},
PatKind::Never => {},
PatKind::Wild => {},
}
}
Expand Down
1 change: 1 addition & 0 deletions clippy_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1707,6 +1707,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {

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,
Expand Down

0 comments on commit 071f8f6

Please sign in to comment.