Skip to content

Commit 3448f0e

Browse files
committed
Add never_patterns feature gate
1 parent fec80b4 commit 3448f0e

File tree

40 files changed

+297
-18
lines changed

40 files changed

+297
-18
lines changed

Diff for: compiler/rustc_ast/src/ast.rs

+4
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

Diff for: compiler/rustc_ast/src/mut_visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,7 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
12491249
let Pat { id, kind, span, tokens } = pat.deref_mut();
12501250
vis.visit_id(id);
12511251
match kind {
1252-
PatKind::Wild | PatKind::Rest => {}
1252+
PatKind::Wild | PatKind::Rest | PatKind::Never => {}
12531253
PatKind::Ident(_binding_mode, ident, sub) => {
12541254
vis.visit_ident(ident);
12551255
visit_opt(sub, |sub| vis.visit_pat(sub));

Diff for: compiler/rustc_ast/src/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
559559
walk_list!(visitor, visit_expr, lower_bound);
560560
walk_list!(visitor, visit_expr, upper_bound);
561561
}
562-
PatKind::Wild | PatKind::Rest => {}
562+
PatKind::Wild | PatKind::Rest | PatKind::Never => {}
563563
PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
564564
walk_list!(visitor, visit_pat, elems);
565565
}

Diff for: compiler/rustc_ast_lowering/src/pat.rs

+1
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);

Diff for: compiler/rustc_ast_passes/src/feature_gate.rs

+1
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() {

Diff for: compiler/rustc_ast_pretty/src/pprust/state.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,7 @@ impl<'a> State<'a> {
14461446
is that it doesn't matter */
14471447
match &pat.kind {
14481448
PatKind::Wild => self.word("_"),
1449+
PatKind::Never => self.word("!"),
14491450
PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, sub) => {
14501451
if *by_ref == ByRef::Yes {
14511452
self.word_nbsp("ref");

Diff for: compiler/rustc_feature/src/unstable.rs

+3-1
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 `()`.

Diff for: compiler/rustc_hir/src/hir.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,7 @@ impl<'hir> Pat<'hir> {
10021002

10031003
use PatKind::*;
10041004
match self.kind {
1005-
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
1005+
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
10061006
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it),
10071007
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
10081008
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
@@ -1029,7 +1029,7 @@ impl<'hir> Pat<'hir> {
10291029

10301030
use PatKind::*;
10311031
match self.kind {
1032-
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
1032+
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
10331033
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it),
10341034
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
10351035
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
@@ -1142,6 +1142,9 @@ pub enum PatKind<'hir> {
11421142
/// Invariant: `pats.len() >= 2`.
11431143
Or(&'hir [Pat<'hir>]),
11441144

1145+
/// A never pattern `!`.
1146+
Never,
1147+
11451148
/// A path pattern for a unit struct/variant or a (maybe-associated) constant.
11461149
Path(QPath<'hir>),
11471150

Diff for: compiler/rustc_hir/src/intravisit.rs

+1-1
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);

Diff for: compiler/rustc_hir_analysis/src/check/region.rs

+1
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,7 @@ fn resolve_local<'tcx>(
662662
PatKind::Ref(_, _)
663663
| PatKind::Binding(hir::BindingAnnotation(hir::ByRef::No, _), ..)
664664
| PatKind::Wild
665+
| PatKind::Never
665666
| PatKind::Path(_)
666667
| PatKind::Lit(_)
667668
| PatKind::Range(_, _, _) => false,

Diff for: compiler/rustc_hir_pretty/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1722,6 +1722,7 @@ impl<'a> State<'a> {
17221722
// is that it doesn't matter
17231723
match pat.kind {
17241724
PatKind::Wild => self.word("_"),
1725+
PatKind::Never => self.word("!"),
17251726
PatKind::Binding(BindingAnnotation(by_ref, mutbl), _, ident, sub) => {
17261727
if by_ref == ByRef::Yes {
17271728
self.word_nbsp("ref");

Diff for: compiler/rustc_hir_typeck/src/expr_use_visitor.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -401,12 +401,17 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
401401
mc.cat_pattern(discr_place.clone(), pat, |place, pat| {
402402
match &pat.kind {
403403
PatKind::Binding(.., opt_sub_pat) => {
404-
// If the opt_sub_pat is None, than the binding does not count as
404+
// If the opt_sub_pat is None, then the binding does not count as
405405
// a wildcard for the purpose of borrowing discr.
406406
if opt_sub_pat.is_none() {
407407
needs_to_be_read = true;
408408
}
409409
}
410+
PatKind::Never => {
411+
// A never pattern reads the value.
412+
// FIXME(never_patterns): does this do what I expect?
413+
needs_to_be_read = true;
414+
}
410415
PatKind::Path(qpath) => {
411416
// A `Path` pattern is just a name like `Foo`. This is either a
412417
// named constant or else it refers to an ADT variant

Diff for: compiler/rustc_hir_typeck/src/mem_categorization.rs

+1
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
773773
| PatKind::Binding(.., None)
774774
| PatKind::Lit(..)
775775
| PatKind::Range(..)
776+
| PatKind::Never
776777
| PatKind::Wild => {
777778
// always ok
778779
}

Diff for: compiler/rustc_hir_typeck/src/pat.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
178178

179179
let ty = match pat.kind {
180180
PatKind::Wild => expected,
181+
PatKind::Never => expected, // FIXME(never_patterns): check the type is uninhabited
181182
PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti),
182183
PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti),
183184
PatKind::Binding(ba, var_id, _, sub) => {
@@ -289,7 +290,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
289290
| PatKind::Slice(..) => AdjustMode::Peel,
290291
// String and byte-string literals result in types `&str` and `&[u8]` respectively.
291292
// All other literals result in non-reference types.
292-
// As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo {}`.
293+
// As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo" {}`.
293294
//
294295
// Call `resolve_vars_if_possible` here for inline const blocks.
295296
PatKind::Lit(lt) => match self.resolve_vars_if_possible(self.check_expr(lt)).kind() {
@@ -307,6 +308,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
307308
// a reference type wherefore peeling doesn't give up any expressiveness.
308309
_ => AdjustMode::Peel,
309310
},
311+
// A never pattern behaves somewhat like a literal or unit variant.
312+
PatKind::Never => AdjustMode::Peel,
310313
// When encountering a `& mut? pat` pattern, reset to "by value".
311314
// This is so that `x` and `y` here are by value, as they appear to be:
312315
//
@@ -743,6 +746,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
743746
| PatKind::Slice(..) => "binding",
744747

745748
PatKind::Wild
749+
| PatKind::Never
746750
| PatKind::Binding(..)
747751
| PatKind::Path(..)
748752
| PatKind::Box(..)

Diff for: compiler/rustc_lint/src/unused.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1154,7 +1154,7 @@ impl EarlyLintPass for UnusedParens {
11541154
// Do not lint on `(..)` as that will result in the other arms being useless.
11551155
Paren(_)
11561156
// The other cases do not contain sub-patterns.
1157-
| Wild | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
1157+
| Wild | Never | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
11581158
// These are list-like patterns; parens can always be removed.
11591159
TupleStruct(_, _, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
11601160
self.check_unused_parens_pat(cx, p, false, false, keep_space);

Diff for: compiler/rustc_middle/src/thir.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,12 @@ impl<'tcx> Pat<'tcx> {
635635

636636
use PatKind::*;
637637
match &self.kind {
638-
Wild | Range(..) | Binding { subpattern: None, .. } | Constant { .. } | Error(_) => {}
638+
Wild
639+
| Never
640+
| Range(..)
641+
| Binding { subpattern: None, .. }
642+
| Constant { .. }
643+
| Error(_) => {}
639644
AscribeUserType { subpattern, .. }
640645
| Binding { subpattern: Some(subpattern), .. }
641646
| Deref { subpattern }
@@ -809,6 +814,9 @@ pub enum PatKind<'tcx> {
809814
pats: Box<[Box<Pat<'tcx>>]>,
810815
},
811816

817+
/// A never pattern `!`.
818+
Never,
819+
812820
/// An error has been encountered during lowering. We probably shouldn't report more lints
813821
/// related to this pattern.
814822
Error(ErrorGuaranteed),
@@ -1069,6 +1077,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
10691077

10701078
match self.kind {
10711079
PatKind::Wild => write!(f, "_"),
1080+
PatKind::Never => write!(f, "!"),
10721081
PatKind::AscribeUserType { ref subpattern, .. } => write!(f, "{subpattern}: _"),
10731082
PatKind::Binding { mutability, name, mode, ref subpattern, .. } => {
10741083
let is_mut = match mode {

Diff for: compiler/rustc_middle/src/thir/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
227227
is_primary: _,
228228
name: _,
229229
} => visitor.visit_pat(subpattern),
230-
Binding { .. } | Wild | Error(_) => {}
230+
Binding { .. } | Wild | Never | Error(_) => {}
231231
Variant { subpatterns, adt_def: _, args: _, variant_index: _ } | Leaf { subpatterns } => {
232232
for subpattern in subpatterns {
233233
visitor.visit_pat(&subpattern.pattern);

Diff for: compiler/rustc_mir_build/src/build/matches/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
827827
PatKind::Constant { .. }
828828
| PatKind::Range { .. }
829829
| PatKind::Wild
830+
| PatKind::Never
830831
| PatKind::Error(_) => {}
831832

832833
PatKind::Deref { ref subpattern } => {

Diff for: compiler/rustc_mir_build/src/build/matches/simplify.rs

+6
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
194194
Ok(())
195195
}
196196

197+
PatKind::Never => {
198+
// A never pattern acts like a load from the place.
199+
// FIXME(never_patterns): load from the place
200+
Ok(())
201+
}
202+
197203
PatKind::Constant { .. } => {
198204
// FIXME normalize patterns when possible
199205
Err(match_pair)

Diff for: compiler/rustc_mir_build/src/build/matches/test.rs

+2
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7575
| PatKind::Array { .. }
7676
| PatKind::Wild
7777
| PatKind::Binding { .. }
78+
| PatKind::Never
7879
| PatKind::Leaf { .. }
7980
| PatKind::Deref { .. }
8081
| PatKind::Error(_) => self.error_simplifiable(match_pair),
@@ -107,6 +108,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
107108
PatKind::Slice { .. }
108109
| PatKind::Array { .. }
109110
| PatKind::Wild
111+
| PatKind::Never
110112
| PatKind::Or { .. }
111113
| PatKind::Binding { .. }
112114
| PatKind::AscribeUserType { .. }

Diff for: compiler/rustc_mir_build/src/check_unsafety.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
247247
self.requires_unsafe(pat.span, AccessToUnionField);
248248
return; // we can return here since this already requires unsafe
249249
}
250-
// wildcard doesn't take anything
250+
// wildcard/never don't take anything
251251
PatKind::Wild |
252+
PatKind::Never |
252253
// these just wrap other patterns
253254
PatKind::Or { .. } |
254255
PatKind::InlineConstant { .. } |

Diff for: compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,10 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
15801580
let pats = expand_or_pat(pat);
15811581
fields = Fields::from_iter(cx, pats.into_iter().map(mkpat));
15821582
}
1583+
PatKind::Never => {
1584+
ctor = Wildcard; // FIXME(never_patterns)
1585+
fields = Fields::empty();
1586+
}
15831587
PatKind::Error(_) => {
15841588
ctor = Opaque;
15851589
fields = Fields::empty();

Diff for: compiler/rustc_mir_build/src/thir/pattern/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
254254
let kind = match pat.kind {
255255
hir::PatKind::Wild => PatKind::Wild,
256256

257+
hir::PatKind::Never => PatKind::Never,
258+
257259
hir::PatKind::Lit(value) => self.lower_lit(value),
258260

259261
hir::PatKind::Range(ref lo_expr, ref hi_expr, end) => {
@@ -792,6 +794,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> {
792794
fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
793795
match *self {
794796
PatKind::Wild => PatKind::Wild,
797+
PatKind::Never => PatKind::Never,
795798
PatKind::Error(e) => PatKind::Error(e),
796799
PatKind::AscribeUserType {
797800
ref subpattern,

Diff for: compiler/rustc_mir_build/src/thir/print.rs

+3
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,9 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
636636
PatKind::Wild => {
637637
print_indented!(self, "Wild", depth_lvl + 1);
638638
}
639+
PatKind::Never => {
640+
print_indented!(self, "Never", depth_lvl + 1);
641+
}
639642
PatKind::AscribeUserType { ascription, subpattern } => {
640643
print_indented!(self, "AscribeUserType: {", depth_lvl + 1);
641644
print_indented!(self, format!("ascription: {:?}", ascription), depth_lvl + 2);

Diff for: compiler/rustc_parse/src/parser/pat.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,12 @@ impl<'a> Parser<'a> {
368368
self.recover_dotdotdot_rest_pat(lo)
369369
} else if let Some(form) = self.parse_range_end() {
370370
self.parse_pat_range_to(form)? // `..=X`, `...X`, or `..X`.
371+
} else if self.eat(&token::Not) {
372+
// Parse `!`
373+
self.sess.gated_spans.gate(sym::never_patterns, self.prev_token.span);
374+
PatKind::Never
371375
} else if self.eat_keyword(kw::Underscore) {
372-
// Parse _
376+
// Parse `_`
373377
PatKind::Wild
374378
} else if self.eat_keyword(kw::Mut) {
375379
self.parse_pat_ident_mut(syntax_loc)?

Diff for: compiler/rustc_passes/src/hir_stats.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,21 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
286286
fn visit_pat(&mut self, p: &'v hir::Pat<'v>) {
287287
record_variants!(
288288
(self, p, p.kind, Id::Node(p.hir_id), hir, Pat, PatKind),
289-
[Wild, Binding, Struct, TupleStruct, Or, Path, Tuple, Box, Ref, Lit, Range, Slice]
289+
[
290+
Wild,
291+
Binding,
292+
Struct,
293+
TupleStruct,
294+
Or,
295+
Never,
296+
Path,
297+
Tuple,
298+
Box,
299+
Ref,
300+
Lit,
301+
Range,
302+
Slice
303+
]
290304
);
291305
hir_visit::walk_pat(self, p)
292306
}
@@ -554,6 +568,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
554568
Range,
555569
Slice,
556570
Rest,
571+
Never,
557572
Paren,
558573
MacCall
559574
]

Diff for: compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,7 @@ symbols! {
10961096
negative_impls,
10971097
neon,
10981098
never,
1099+
never_patterns,
10991100
never_type,
11001101
never_type_fallback,
11011102
new,

Diff for: src/librustdoc/clean/utils.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
303303
debug!("trying to get a name from pattern: {p:?}");
304304

305305
Symbol::intern(&match p.kind {
306-
PatKind::Wild | PatKind::Struct(..) => return kw::Underscore,
306+
// FIXME(never_patterns): does this make sense?
307+
PatKind::Wild | PatKind::Never | PatKind::Struct(..) => return kw::Underscore,
307308
PatKind::Binding(_, _, ident, _) => return ident.name,
308309
PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p),
309310
PatKind::Or(pats) => {

Diff for: src/tools/clippy/clippy_lints/src/equatable_if_let.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
4646
pats.iter().all(unary_pattern)
4747
}
4848
match &pat.kind {
49-
PatKind::Slice(_, _, _) | PatKind::Range(_, _, _) | PatKind::Binding(..) | PatKind::Wild | PatKind::Or(_) => {
49+
PatKind::Slice(_, _, _) | PatKind::Range(_, _, _) | PatKind::Binding(..) | PatKind::Wild | PatKind::Never | PatKind::Or(_) => {
5050
false
5151
},
5252
PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)),

0 commit comments

Comments
 (0)