Rollup merge of #139035 - nnethercote:PatKind-Missing, r=oli-obk
Add new `PatKind::Missing` variants To avoid some ugly uses of `kw::Empty` when handling "missing" patterns, e.g. in bare fn tys. Helps with #137978. Details in the individual commits. r? ``@oli-obk``
This commit is contained in:
commit
82df6229b6
42 changed files with 92 additions and 66 deletions
|
@ -563,6 +563,7 @@ impl Pat {
|
|||
/// This is intended for use by diagnostics.
|
||||
pub fn to_ty(&self) -> Option<P<Ty>> {
|
||||
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<String> {
|
||||
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,
|
||||
|
||||
|
|
|
@ -1587,7 +1587,7 @@ pub fn walk_pat<T: MutVisitor>(vis: &mut T, pat: &mut P<Pat>) {
|
|||
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));
|
||||
|
|
|
@ -750,7 +750,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);
|
||||
|
|
|
@ -1496,18 +1496,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
|
||||
self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
|
||||
PatKind::Ident(_, ident, _) => {
|
||||
if ident.name != kw::Empty {
|
||||
Some(self.lower_ident(ident))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
PatKind::Missing => None,
|
||||
PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
|
||||
PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
|
||||
_ => {
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -244,7 +244,7 @@ impl<'a> AstValidator<'a> {
|
|||
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, 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)
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -1555,6 +1555,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)),
|
||||
|
@ -1582,7 +1583,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)),
|
||||
|
@ -1720,6 +1721,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,
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -623,6 +623,7 @@ fn resolve_local<'tcx>(
|
|||
|
||||
PatKind::Ref(_, _)
|
||||
| PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..)
|
||||
| PatKind::Missing
|
||||
| PatKind::Wild
|
||||
| PatKind::Never
|
||||
| PatKind::Expr(_)
|
||||
|
|
|
@ -1868,6 +1868,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) => {
|
||||
|
|
|
@ -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(_, _)
|
||||
|
|
|
@ -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.
|
||||
|
@ -1832,6 +1833,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
|
||||
|
|
|
@ -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,
|
||||
|
@ -1032,7 +1034,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
| PatKind::Tuple(..)
|
||||
| PatKind::Slice(..) => "binding",
|
||||
|
||||
PatKind::Wild
|
||||
PatKind::Missing
|
||||
| PatKind::Wild
|
||||
| PatKind::Never
|
||||
| PatKind::Binding(..)
|
||||
| PatKind::Box(..)
|
||||
|
|
|
@ -779,21 +779,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 {
|
||||
("<type>", 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 {
|
||||
("<type>", Applicability::HasPlaceholders)
|
||||
};
|
||||
cx.emit_span_lint(
|
||||
ANONYMOUS_PARAMETERS,
|
||||
arg.pat.span,
|
||||
BuiltinAnonymousParams { suggestion: (arg.pat.span, appl), ty_snip },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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(_)
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -920,6 +920,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
|
||||
PatKind::Constant { .. }
|
||||
| PatKind::Range { .. }
|
||||
| PatKind::Missing
|
||||
| PatKind::Wild
|
||||
| PatKind::Never
|
||||
| PatKind::Error(_) => {}
|
||||
|
|
|
@ -315,6 +315,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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -2987,9 +2987,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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -96,7 +96,7 @@ use rustc_middle::query::Providers;
|
|||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::{BytePos, Span, Symbol, kw, sym};
|
||||
use rustc_span::{BytePos, Span, Symbol, sym};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use self::LiveNodeKind::*;
|
||||
|
@ -1481,9 +1481,6 @@ impl<'tcx> Liveness<'_, 'tcx> {
|
|||
|
||||
fn should_warn(&self, var: Variable) -> Option<String> {
|
||||
let name = self.ir.variable_name(var);
|
||||
if name == kw::Empty {
|
||||
return None;
|
||||
}
|
||||
let name = name.as_str();
|
||||
if name.as_bytes()[0] == b'_' {
|
||||
return None;
|
||||
|
|
|
@ -460,7 +460,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;
|
||||
|
|
|
@ -4009,22 +4009,17 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
self.report_error(ident.span, error(ident));
|
||||
}
|
||||
|
||||
// Record as bound if it's valid:
|
||||
let ident_valid = ident.name != kw::Empty;
|
||||
if ident_valid {
|
||||
bindings.last_mut().unwrap().1.insert(ident);
|
||||
}
|
||||
// Record as bound.
|
||||
bindings.last_mut().unwrap().1.insert(ident);
|
||||
|
||||
if already_bound_or {
|
||||
// `Variant1(a) | Variant2(a)`, ok
|
||||
// Reuse definition from the first `a`.
|
||||
self.innermost_rib_bindings(ValueNS)[&ident]
|
||||
} else {
|
||||
// A completely fresh binding is added to the set.
|
||||
let res = Res::Local(pat_id);
|
||||
if ident_valid {
|
||||
// A completely fresh binding add to the set if it's valid.
|
||||
self.innermost_rib_bindings(ValueNS).insert(ident, res);
|
||||
}
|
||||
self.innermost_rib_bindings(ValueNS).insert(ident, res);
|
||||
res
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(..)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -406,6 +406,7 @@ impl<'a> PatState<'a> {
|
|||
pats.iter().map(|p| p.pat),
|
||||
),
|
||||
|
||||
PatKind::Missing => unreachable!(),
|
||||
PatKind::Wild
|
||||
| PatKind::Binding(_, _, _, None)
|
||||
| PatKind::Expr(_)
|
||||
|
|
|
@ -224,6 +224,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, 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,
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1858,6 +1858,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),
|
||||
|
|
|
@ -2442,11 +2442,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)]
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -515,6 +515,8 @@ fn test_meta() {
|
|||
|
||||
#[test]
|
||||
fn test_pat() {
|
||||
// PatKind::Missing: untestable in isolation.
|
||||
|
||||
// PatKind::Wild
|
||||
c1!(pat, [ _ ], "_");
|
||||
|
||||
|
|
|
@ -574,6 +574,11 @@ mod items {
|
|||
}
|
||||
|
||||
mod patterns {
|
||||
/// PatKind::Missing
|
||||
fn pat_missing() {
|
||||
let _: fn(u32, T, &str);
|
||||
}
|
||||
|
||||
/// PatKind::Wild
|
||||
fn pat_wild() {
|
||||
let _;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue