Skip to content

Commit 472b9c7

Browse files
committed
Add never_patterns feature gate
1 parent f81d6f0 commit 472b9c7

File tree

33 files changed

+289
-16
lines changed

33 files changed

+289
-16
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@ impl Pat {
646646
// These patterns do not contain subpatterns, skip.
647647
PatKind::Wild
648648
| PatKind::Rest
649+
| PatKind::Never
649650
| PatKind::Lit(_)
650651
| PatKind::Range(..)
651652
| PatKind::Ident(..)
@@ -796,6 +797,9 @@ pub enum PatKind {
796797
/// only one rest pattern may occur in the pattern sequences.
797798
Rest,
798799

800+
// A never pattern `!`
801+
Never,
802+
799803
/// Parentheses in patterns used for grouping (i.e., `(PAT)`).
800804
Paren(P<Pat>),
801805

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1242,7 +1242,7 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
12421242
let Pat { id, kind, span, tokens } = pat.deref_mut();
12431243
vis.visit_id(id);
12441244
match kind {
1245-
PatKind::Wild | PatKind::Rest => {}
1245+
PatKind::Wild | PatKind::Rest | PatKind::Never => {}
12461246
PatKind::Ident(_binding_mode, ident, sub) => {
12471247
vis.visit_ident(ident);
12481248
visit_opt(sub, |sub| vis.visit_pat(sub));

compiler/rustc_ast/src/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
556556
walk_list!(visitor, visit_expr, lower_bound);
557557
walk_list!(visitor, visit_expr, upper_bound);
558558
}
559-
PatKind::Wild | PatKind::Rest => {}
559+
PatKind::Wild | PatKind::Rest | PatKind::Never => {}
560560
PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
561561
walk_list!(visitor, visit_pat, elems);
562562
}

compiler/rustc_ast_lowering/src/pat.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2424
let node = loop {
2525
match &pattern.kind {
2626
PatKind::Wild => break hir::PatKind::Wild,
27+
PatKind::Never => break hir::PatKind::Never,
2728
PatKind::Ident(binding_mode, ident, sub) => {
2829
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(s));
2930
break self.lower_pat_ident(pattern, *binding_mode, *ident, lower_sub);

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
555555
gate_all!(explicit_tail_calls, "`become` expression is experimental");
556556
gate_all!(generic_const_items, "generic const items are experimental");
557557
gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
558+
gate_all!(never_patterns, "`!` patterns are experimental");
558559

559560
if !visitor.features.negative_bounds {
560561
for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() {

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,7 @@ impl<'a> State<'a> {
14341434
is that it doesn't matter */
14351435
match &pat.kind {
14361436
PatKind::Wild => self.word("_"),
1437+
PatKind::Never => self.word("!"),
14371438
PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, sub) => {
14381439
if *by_ref == ByRef::Yes {
14391440
self.word_nbsp("ref");

compiler/rustc_feature/src/unstable.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ macro_rules! declare_features {
147147
// was set.
148148
//
149149
// Note that the features are grouped into internal/user-facing and then
150-
// sorted by version inside those groups. This is enforced with tidy.
150+
// sorted alphabetically inside those groups. This is enforced with tidy.
151151
//
152152
// N.B., `tools/tidy/src/features.rs` parses this information directly out of the
153153
// source, so take care when modifying it.
@@ -510,6 +510,8 @@ declare_features! (
510510
(unstable, native_link_modifiers_as_needed, "1.53.0", Some(81490), None),
511511
/// Allow negative trait implementations.
512512
(unstable, negative_impls, "1.44.0", Some(68318), None),
513+
/// Allows the `!` pattern.
514+
(incomplete, never_patterns, "CURRENT_RUSTC_VERSION", Some(118155), None),
513515
/// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
514516
(unstable, never_type, "1.13.0", Some(35121), None),
515517
/// Allows diverging expressions to fall back to `!` rather than `()`.

compiler/rustc_hir/src/hir.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,7 @@ impl<'hir> Pat<'hir> {
10321032

10331033
use PatKind::*;
10341034
match self.kind {
1035-
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
1035+
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
10361036
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it),
10371037
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
10381038
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
@@ -1059,7 +1059,7 @@ impl<'hir> Pat<'hir> {
10591059

10601060
use PatKind::*;
10611061
match self.kind {
1062-
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
1062+
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
10631063
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it),
10641064
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
10651065
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
@@ -1172,6 +1172,9 @@ pub enum PatKind<'hir> {
11721172
/// Invariant: `pats.len() >= 2`.
11731173
Or(&'hir [Pat<'hir>]),
11741174

1175+
/// A never pattern `!`.
1176+
Never,
1177+
11751178
/// A path pattern for a unit struct/variant or a (maybe-associated) constant.
11761179
Path(QPath<'hir>),
11771180

compiler/rustc_hir/src/intravisit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
660660
walk_list!(visitor, visit_expr, lower_bound);
661661
walk_list!(visitor, visit_expr, upper_bound);
662662
}
663-
PatKind::Wild => (),
663+
PatKind::Never | PatKind::Wild => (),
664664
PatKind::Slice(prepatterns, ref slice_pattern, postpatterns) => {
665665
walk_list!(visitor, visit_pat, prepatterns);
666666
walk_list!(visitor, visit_pat, slice_pattern);

compiler/rustc_hir_analysis/src/check/region.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ fn resolve_local<'tcx>(
664664
PatKind::Ref(_, _)
665665
| PatKind::Binding(hir::BindingAnnotation(hir::ByRef::No, _), ..)
666666
| PatKind::Wild
667+
| PatKind::Never
667668
| PatKind::Path(_)
668669
| PatKind::Lit(_)
669670
| PatKind::Range(_, _, _) => false,

0 commit comments

Comments
 (0)