diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 064f05ef1f3..944ae65ffc6 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -563,6 +563,7 @@ impl Pat { /// This is intended for use by diagnostics. pub fn to_ty(&self) -> Option> { let kind = match &self.kind { + PatKind::Missing => unreachable!(), // In a type expression `_` is an inference variable. PatKind::Wild => TyKind::Infer, // An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`. @@ -625,7 +626,8 @@ impl Pat { | PatKind::Guard(s, _) => s.walk(it), // These patterns do not contain subpatterns, skip. - PatKind::Wild + PatKind::Missing + | PatKind::Wild | PatKind::Rest | PatKind::Never | PatKind::Expr(_) @@ -676,6 +678,7 @@ impl Pat { /// Return a name suitable for diagnostics. pub fn descr(&self) -> Option { match &self.kind { + PatKind::Missing => unreachable!(), PatKind::Wild => Some("_".to_string()), PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")), PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())), @@ -769,6 +772,9 @@ pub enum RangeSyntax { // Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`. #[derive(Clone, Encodable, Decodable, Debug)] pub enum PatKind { + /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`. + Missing, + /// Represents a wildcard pattern (`_`). Wild, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 274fe312f7f..8c6ddf2a69c 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1572,7 +1572,7 @@ pub fn walk_pat(vis: &mut T, pat: &mut P) { vis.visit_id(id); match kind { PatKind::Err(_guar) => {} - PatKind::Wild | PatKind::Rest | PatKind::Never => {} + PatKind::Missing | PatKind::Wild | PatKind::Rest | PatKind::Never => {} PatKind::Ident(_binding_mode, ident, sub) => { vis.visit_ident(ident); visit_opt(sub, |sub| vis.visit_pat(sub)); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 2716601ca4f..3d78f65f634 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -727,7 +727,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Res try_visit!(visitor.visit_pat(subpattern)); try_visit!(visitor.visit_expr(guard_condition)); } - PatKind::Wild | PatKind::Rest | PatKind::Never => {} + PatKind::Missing | PatKind::Wild | PatKind::Rest | PatKind::Never => {} PatKind::Err(_guar) => {} PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { walk_list!(visitor, visit_pat, elems); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ced9064fd9f..4041e5d092a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1495,6 +1495,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Option] { self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind { + PatKind::Missing => None, PatKind::Ident(_, ident, _) => { if ident.name != kw::Empty { Some(self.lower_ident(ident)) @@ -1506,7 +1507,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { _ => { self.dcx().span_delayed_bug( param.pat.span, - "non-ident/wild param pat must trigger an error", + "non-missing/ident/wild param pat must trigger an error", ); None } diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 07cc64a1358..f94d788a9b0 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -26,6 +26,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let pat_hir_id = self.lower_node_id(pattern.id); let node = loop { match &pattern.kind { + PatKind::Missing => break hir::PatKind::Missing, PatKind::Wild => break hir::PatKind::Wild, PatKind::Never => break hir::PatKind::Never, PatKind::Ident(binding_mode, ident, sub) => { diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index a1487ca74be..ab6d4644f7e 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -239,7 +239,7 @@ impl<'a> AstValidator<'a> { fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option, bool)) { for Param { pat, .. } in &decl.inputs { match pat.kind { - PatKind::Ident(BindingMode::NONE, _, None) | PatKind::Wild => {} + PatKind::Missing | PatKind::Ident(BindingMode::NONE, _, None) | PatKind::Wild => {} PatKind::Ident(BindingMode::MUT, ident, None) => { report_err(pat.span, Some(ident), true) } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index cdb18179449..f9e17fb0539 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1622,9 +1622,9 @@ impl<'a> State<'a> { fn print_pat(&mut self, pat: &ast::Pat) { self.maybe_print_comment(pat.span.lo()); self.ann.pre(self, AnnNode::Pat(pat)); - /* Pat isn't normalized, but the beauty of it - is that it doesn't matter */ + /* Pat isn't normalized, but the beauty of it is that it doesn't matter */ match &pat.kind { + PatKind::Missing => unreachable!(), PatKind::Wild => self.word("_"), PatKind::Never => self.word("!"), PatKind::Ident(BindingMode(by_ref, mutbl), ident, sub) => { @@ -1946,12 +1946,7 @@ impl<'a> State<'a> { if let Some(eself) = input.to_self() { self.print_explicit_self(&eself); } else { - let invalid = if let PatKind::Ident(_, ident, _) = input.pat.kind { - ident.name == kw::Empty - } else { - false - }; - if !invalid { + if !matches!(input.pat.kind, PatKind::Missing) { self.print_pat(&input.pat); self.word(":"); self.space(); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 751c379b21a..08e37accb8a 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1516,6 +1516,7 @@ impl<'hir> Pat<'hir> { use PatKind::*; match self.kind { + Missing => unreachable!(), Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true, Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it), Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)), @@ -1543,7 +1544,7 @@ impl<'hir> Pat<'hir> { use PatKind::*; match self.kind { - Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {} + Missing | Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {} Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it), Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)), TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)), @@ -1681,6 +1682,9 @@ pub enum TyPatKind<'hir> { #[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum PatKind<'hir> { + /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`. + Missing, + /// Represents a wildcard pattern (i.e., `_`). Wild, diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 506358341b5..ea3f396761b 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -744,7 +744,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V: visit_opt!(visitor, visit_pat_expr, lower_bound); visit_opt!(visitor, visit_pat_expr, upper_bound); } - PatKind::Never | PatKind::Wild | PatKind::Err(_) => (), + PatKind::Missing | PatKind::Never | PatKind::Wild | PatKind::Err(_) => (), PatKind::Slice(prepatterns, ref slice_pattern, postpatterns) => { walk_list!(visitor, visit_pat, prepatterns); visit_opt!(visitor, visit_pat, slice_pattern); diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 255f5fee52a..d63fef8c0ef 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -701,6 +701,7 @@ fn resolve_local<'tcx>( PatKind::Ref(_, _) | PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..) + | PatKind::Missing | PatKind::Wild | PatKind::Never | PatKind::Expr(_) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index ddaca89ccf8..a4961fc2c85 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1875,6 +1875,7 @@ impl<'a> State<'a> { // Pat isn't normalized, but the beauty of it // is that it doesn't matter match pat.kind { + PatKind::Missing => unreachable!(), PatKind::Wild => self.word("_"), PatKind::Never => self.word("!"), PatKind::Binding(BindingMode(by_ref, mutbl), _, ident, sub) => { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index a75f6f4caac..0ed03a03c1b 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -482,7 +482,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // All of these constitute a read, or match on something that isn't `!`, // which would require a `NeverToAny` coercion. - hir::PatKind::Binding(_, _, _, _) + hir::PatKind::Missing + | hir::PatKind::Binding(_, _, _, _) | hir::PatKind::Struct(_, _, _) | hir::PatKind::TupleStruct(_, _, _) | hir::PatKind::Tuple(_, _) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index c71a5ea8b97..d50f235ad4d 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -611,6 +611,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx for pat in pats { self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| { match &pat.kind { + PatKind::Missing => unreachable!(), PatKind::Binding(.., opt_sub_pat) => { // If the opt_sub_pat is None, then the binding does not count as // a wildcard for the purpose of borrowing discr. @@ -1884,6 +1885,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx | PatKind::Expr(..) | PatKind::Range(..) | PatKind::Never + | PatKind::Missing | PatKind::Wild | PatKind::Err(_) => { // always ok diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index f1f956779c9..0d4ecbc867b 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -341,7 +341,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let ty = match pat.kind { - PatKind::Wild | PatKind::Err(_) => expected, + PatKind::Missing | PatKind::Wild | PatKind::Err(_) => expected, // We allow any type here; we ensure that the type is uninhabited during match checking. PatKind::Never => expected, PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => { @@ -505,9 +505,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, // Ref patterns are complicated, we handle them in `check_pat_ref`. - PatKind::Ref(..) => AdjustMode::Pass, + PatKind::Ref(..) + // No need to do anything on a missing pattern. + | PatKind::Missing // A `_` pattern works with any expected type, so there's no need to do anything. - PatKind::Wild + | PatKind::Wild // A malformed pattern doesn't have an expected type, so let's just accept any type. | PatKind::Err(_) // Bindings also work with whatever the expected type is, @@ -1037,7 +1039,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | PatKind::Tuple(..) | PatKind::Slice(..) => "binding", - PatKind::Wild + PatKind::Missing + | PatKind::Wild | PatKind::Never | PatKind::Binding(..) | PatKind::Box(..) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 9dccd4a0552..0b5cdf99de5 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -778,21 +778,19 @@ impl EarlyLintPass for AnonymousParameters { } if let ast::AssocItemKind::Fn(box Fn { ref sig, .. }) = it.kind { for arg in sig.decl.inputs.iter() { - if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind { - if ident.name == kw::Empty { - let ty_snip = cx.sess().source_map().span_to_snippet(arg.ty.span); + if let ast::PatKind::Missing = arg.pat.kind { + let ty_snip = cx.sess().source_map().span_to_snippet(arg.ty.span); - let (ty_snip, appl) = if let Ok(ref snip) = ty_snip { - (snip.as_str(), Applicability::MachineApplicable) - } else { - ("", Applicability::HasPlaceholders) - }; - cx.emit_span_lint( - ANONYMOUS_PARAMETERS, - arg.pat.span, - BuiltinAnonymousParams { suggestion: (arg.pat.span, appl), ty_snip }, - ); - } + let (ty_snip, appl) = if let Ok(ref snip) = ty_snip { + (snip.as_str(), Applicability::MachineApplicable) + } else { + ("", Applicability::HasPlaceholders) + }; + cx.emit_span_lint( + ANONYMOUS_PARAMETERS, + arg.pat.span, + BuiltinAnonymousParams { suggestion: (arg.pat.span, appl), ty_snip }, + ); } } } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 7b43aac90c7..806bca78f78 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1201,7 +1201,8 @@ impl EarlyLintPass for UnusedParens { // Do not lint on `(..)` as that will result in the other arms being useless. Paren(_) // The other cases do not contain sub-patterns. - | Wild | Never | Rest | Expr(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) | Err(_) => {}, + | Missing | Wild | Never | Rest | Expr(..) | MacCall(..) | Range(..) | Ident(.., None) + | Path(..) | Err(_) => {}, // These are list-like patterns; parens can always be removed. TupleStruct(_, _, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps { self.check_unused_parens_pat(cx, p, false, false, keep_space); diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 6783bbf8bf4..413717e45eb 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -747,6 +747,9 @@ pub struct Ascription<'tcx> { #[derive(Clone, Debug, HashStable, TypeVisitable)] pub enum PatKind<'tcx> { + /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`. + Missing, + /// A wildcard pattern: `_`. Wild, diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index 7d62ab7970d..f3da2a5cc8e 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -250,7 +250,8 @@ pub(crate) fn for_each_immediate_subpat<'a, 'tcx>( mut callback: impl FnMut(&'a Pat<'tcx>), ) { match &pat.kind { - PatKind::Wild + PatKind::Missing + | PatKind::Wild | PatKind::Binding { subpattern: None, .. } | PatKind::Constant { value: _ } | PatKind::Range(_) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 29d400a957b..11672163b65 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -118,7 +118,7 @@ impl<'tcx> MatchPairTree<'tcx> { let place = place_builder.try_to_place(cx); let mut subpairs = Vec::new(); let test_case = match pattern.kind { - PatKind::Wild | PatKind::Error(_) => None, + PatKind::Missing | PatKind::Wild | PatKind::Error(_) => None, PatKind::Or { ref pats } => Some(TestCase::Or { pats: pats.iter().map(|pat| FlatPat::new(place_builder.clone(), pat, cx)).collect(), diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 3acf2a6a2a6..977d4f3e931 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -920,6 +920,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { PatKind::Constant { .. } | PatKind::Range { .. } + | PatKind::Missing | PatKind::Wild | PatKind::Never | PatKind::Error(_) => {} diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 7f2e7d5ca83..9572dfc52da 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -313,6 +313,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { fn visit_pat(&mut self, pat: &'a Pat<'tcx>) { if self.in_union_destructure { match pat.kind { + PatKind::Missing => unreachable!(), // binding to a variable allows getting stuff out of variable PatKind::Binding { .. } // match is conditional on having this value diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 4bfeab44bf4..f36a895849a 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -290,6 +290,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let mut span = pat.span; let kind = match pat.kind { + hir::PatKind::Missing => PatKind::Missing, + hir::PatKind::Wild => PatKind::Wild, hir::PatKind::Never => PatKind::Never, diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 16cef0ec3ac..ac71bb845a8 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -664,6 +664,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, "kind: PatKind {", depth_lvl); match pat_kind { + PatKind::Missing => unreachable!(), PatKind::Wild => { print_indented!(self, "Wild", depth_lvl + 1); } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index aad18578375..0f5d8d9fbed 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2941,9 +2941,7 @@ impl<'a> Parser<'a> { } match ty { Ok(ty) => { - let ident = Ident::new(kw::Empty, this.prev_token.span); - let bm = BindingMode::NONE; - let pat = this.mk_pat_ident(ty.span, bm, ident); + let pat = this.mk_pat(ty.span, PatKind::Missing); (pat, ty) } // If this is a C-variadic argument and we hit an error, return the error. diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index 1278e98afcf..71815448172 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -295,6 +295,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { record_variants!( (self, p, p.kind, Some(p.hir_id), hir, Pat, PatKind), [ + Missing, Wild, Binding, Struct, @@ -597,6 +598,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { record_variants!( (self, p, p.kind, None, ast, Pat, PatKind), [ + Missing, Wild, Ident, Struct, diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index a25a80cd45f..e8152734052 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -457,7 +457,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { PatKind::AscribeUserType { subpattern, .. } | PatKind::ExpandedConstant { subpattern, .. } => return self.lower_pat(subpattern), PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat), - PatKind::Binding { subpattern: None, .. } | PatKind::Wild => { + PatKind::Missing | PatKind::Binding { subpattern: None, .. } | PatKind::Wild => { ctor = Wildcard; fields = vec![]; arity = 0; diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index f81db58950c..afcca81a485 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -304,6 +304,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { Symbol::intern(&match &p.kind { // FIXME(never_patterns): does this make sense? + PatKind::Missing => unreachable!(), PatKind::Wild | PatKind::Err(_) | PatKind::Never diff --git a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs index cd9ab2764ac..3afb687040f 100644 --- a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs +++ b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs @@ -45,6 +45,7 @@ fn unary_pattern(pat: &Pat<'_>) -> bool { pats.iter().all(unary_pattern) } match &pat.kind { + PatKind::Missing => unreachable!(), PatKind::Slice(_, _, _) | PatKind::Range(_, _, _) | PatKind::Binding(..) diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index 250f17fa902..a21597ffb93 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -253,6 +253,7 @@ fn iter_matching_struct_fields<'a>( impl<'a> NormalizedPat<'a> { fn from_pat(cx: &LateContext<'_>, arena: &'a DroplessArena, pat: &'a Pat<'_>) -> Self { match pat.kind { + PatKind::Missing => unreachable!(), PatKind::Wild | PatKind::Binding(.., None) => Self::Wild, PatKind::Binding(.., Some(pat)) | PatKind::Box(pat) diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs index 56fbd626eef..836c46240ce 100644 --- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs @@ -406,6 +406,7 @@ impl<'a> PatState<'a> { pats.iter().map(|p| p.pat), ), + PatKind::Missing => unreachable!(), PatKind::Wild | PatKind::Binding(_, _, _, None) | PatKind::Expr(_) diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs index f43715d6752..8966e6851ac 100644 --- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs @@ -224,6 +224,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec>, focus_idx: us // We're trying to find whatever kind (~"constructor") we found in `alternatives[start..]`. let changed = match &mut focus_kind { + Missing => unreachable!(), // These pattern forms are "leafs" and do not have sub-patterns. // Therefore they are not some form of constructor `C`, // with which a pattern `C(p_0)` may be formed, diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 4309cd2c9ab..b7dcd2ffb0e 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -676,6 +676,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { } match pat.value.kind { + PatKind::Missing => unreachable!(), PatKind::Wild => kind!("Wild"), PatKind::Never => kind!("Never"), PatKind::Binding(ann, _, name, sub) => { diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 6023ae9cc7b..ed99f966d2b 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -33,6 +33,7 @@ pub fn eq_id(l: Ident, r: Ident) -> bool { pub fn eq_pat(l: &Pat, r: &Pat) -> bool { use PatKind::*; match (&l.kind, &r.kind) { + (Missing, _) | (_, Missing) => unreachable!(), (Paren(l), _) => eq_pat(l, r), (_, Paren(r)) => eq_pat(l, r), (Wild, Wild) | (Rest, Rest) => true, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 9938e64d242..b813cd361ed 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -1124,6 +1124,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { pub fn hash_pat(&mut self, pat: &Pat<'_>) { std::mem::discriminant(&pat.kind).hash(&mut self.s); match pat.kind { + PatKind::Missing => unreachable!(), PatKind::Binding(BindingMode(by_ref, mutability), _, _, pat) => { std::mem::discriminant(&by_ref).hash(&mut self.s); std::mem::discriminant(&mutability).hash(&mut self.s); diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 1307ff79bc5..bdcbe1437d0 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1857,6 +1857,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { } match pat.kind { + PatKind::Missing => unreachable!(), PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable. PatKind::Binding(_, _, _, pat) => pat.is_some_and(|pat| is_refutable(cx, pat)), PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat), diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index 3fb3284e3d7..81ff6327a4f 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -2433,11 +2433,7 @@ pub(crate) fn span_hi_for_param(context: &RewriteContext<'_>, param: &ast::Param } pub(crate) fn is_named_param(param: &ast::Param) -> bool { - if let ast::PatKind::Ident(_, ident, _) = param.pat.kind { - ident.name != symbol::kw::Empty - } else { - true - } + !matches!(param.pat.kind, ast::PatKind::Missing) } #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs index bafed41e39f..8ec3de286dc 100644 --- a/src/tools/rustfmt/src/patterns.rs +++ b/src/tools/rustfmt/src/patterns.rs @@ -42,6 +42,7 @@ pub(crate) fn is_short_pattern( fn is_short_pattern_inner(context: &RewriteContext<'_>, pat: &ast::Pat) -> bool { match &pat.kind { + ast::PatKind::Missing => unreachable!(), ast::PatKind::Rest | ast::PatKind::Never | ast::PatKind::Wild | ast::PatKind::Err(_) => { true } @@ -100,6 +101,7 @@ impl Rewrite for Pat { fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { match self.kind { + PatKind::Missing => unreachable!(), PatKind::Or(ref pats) => { let pat_strs = pats .iter() diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 40033f546d3..3490d3efc59 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -515,6 +515,8 @@ fn test_meta() { #[test] fn test_pat() { + // PatKind::Missing: untestable in isolation. + // PatKind::Wild c1!(pat, [ _ ], "_"); diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs index 31af323ecda..4d1f12e3490 100644 --- a/tests/ui/unpretty/expanded-exhaustive.rs +++ b/tests/ui/unpretty/expanded-exhaustive.rs @@ -574,6 +574,11 @@ mod items { } mod patterns { + /// PatKind::Missing + fn pat_missing() { + let _: fn(u32, T, &str); + } + /// PatKind::Wild fn pat_wild() { let _; diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout index 19ae66f7a07..d8da941a340 100644 --- a/tests/ui/unpretty/expanded-exhaustive.stdout +++ b/tests/ui/unpretty/expanded-exhaustive.stdout @@ -361,6 +361,7 @@ mod expressions { + { builtin # offset_of(T, field) }; @@ -517,6 +518,8 @@ mod items { } } mod patterns { + /// PatKind::Missing + fn pat_missing() { let _: fn(u32, T, &str); } /// PatKind::Wild fn pat_wild() { let _; } /// PatKind::Ident