Add PatKind::Err
This commit is contained in:
parent
6ed31aba1a
commit
7889e99b55
23 changed files with 66 additions and 24 deletions
|
@ -625,7 +625,8 @@ impl Pat {
|
|||
| PatKind::Range(..)
|
||||
| PatKind::Ident(..)
|
||||
| PatKind::Path(..)
|
||||
| PatKind::MacCall(_) => {}
|
||||
| PatKind::MacCall(_)
|
||||
| PatKind::Err(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -809,6 +810,9 @@ pub enum PatKind {
|
|||
|
||||
/// A macro pattern; pre-expansion.
|
||||
MacCall(P<MacCall>),
|
||||
|
||||
/// Placeholder for a pattern that wasn't syntactically well formed in some way.
|
||||
Err(ErrorGuaranteed),
|
||||
}
|
||||
|
||||
/// Whether the `..` is present in a struct fields pattern.
|
||||
|
|
|
@ -1267,7 +1267,7 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
|
|||
let Pat { id, kind, span, tokens } = pat.deref_mut();
|
||||
vis.visit_id(id);
|
||||
match kind {
|
||||
PatKind::Wild | PatKind::Rest | PatKind::Never => {}
|
||||
PatKind::Wild | PatKind::Rest | PatKind::Never | PatKind::Err(_) => {}
|
||||
PatKind::Ident(_binding_mode, ident, sub) => {
|
||||
vis.visit_ident(ident);
|
||||
visit_opt(sub, |sub| vis.visit_pat(sub));
|
||||
|
|
|
@ -568,7 +568,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
|
|||
walk_list!(visitor, visit_expr, lower_bound);
|
||||
walk_list!(visitor, visit_expr, upper_bound);
|
||||
}
|
||||
PatKind::Wild | PatKind::Rest | PatKind::Never => {}
|
||||
PatKind::Wild | PatKind::Rest | PatKind::Never | PatKind::Err(_) => {}
|
||||
PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
|
||||
walk_list!(visitor, visit_pat, elems);
|
||||
}
|
||||
|
|
|
@ -109,6 +109,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// return inner to be processed in next loop
|
||||
PatKind::Paren(inner) => pattern = inner,
|
||||
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
|
||||
PatKind::Err(guar) => break hir::PatKind::Err(*guar),
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1519,6 +1519,11 @@ impl<'a> State<'a> {
|
|||
self.pclose();
|
||||
}
|
||||
PatKind::MacCall(m) => self.print_mac(m),
|
||||
PatKind::Err(_) => {
|
||||
self.popen();
|
||||
self.word("/*ERROR*/");
|
||||
self.pclose();
|
||||
}
|
||||
}
|
||||
self.ann.post(self, AnnNode::Pat(pat))
|
||||
}
|
||||
|
|
|
@ -1015,7 +1015,7 @@ impl<'hir> Pat<'hir> {
|
|||
|
||||
use PatKind::*;
|
||||
match self.kind {
|
||||
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
|
||||
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => true,
|
||||
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it),
|
||||
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
|
||||
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
|
||||
|
@ -1042,7 +1042,7 @@ impl<'hir> Pat<'hir> {
|
|||
|
||||
use PatKind::*;
|
||||
match self.kind {
|
||||
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
|
||||
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => {}
|
||||
Box(s) | Ref(s, _) | Binding(.., Some(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)),
|
||||
|
@ -1205,6 +1205,9 @@ pub enum PatKind<'hir> {
|
|||
/// PatKind::Slice([Binding(a), Binding(b)], Some(Wild), [Binding(c), Binding(d)])
|
||||
/// ```
|
||||
Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
|
||||
|
||||
/// A placeholder for a pattern that wasn't well formed in some way.
|
||||
Err(ErrorGuaranteed),
|
||||
}
|
||||
|
||||
/// A statement.
|
||||
|
|
|
@ -655,7 +655,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
|
|||
walk_list!(visitor, visit_expr, lower_bound);
|
||||
walk_list!(visitor, visit_expr, upper_bound);
|
||||
}
|
||||
PatKind::Never | PatKind::Wild => (),
|
||||
PatKind::Never | PatKind::Wild | PatKind::Err(_) => (),
|
||||
PatKind::Slice(prepatterns, ref slice_pattern, postpatterns) => {
|
||||
walk_list!(visitor, visit_pat, prepatterns);
|
||||
walk_list!(visitor, visit_pat, slice_pattern);
|
||||
|
|
|
@ -681,7 +681,8 @@ fn resolve_local<'tcx>(
|
|||
| PatKind::Never
|
||||
| PatKind::Path(_)
|
||||
| PatKind::Lit(_)
|
||||
| PatKind::Range(_, _, _) => false,
|
||||
| PatKind::Range(_, _, _)
|
||||
| PatKind::Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1838,6 +1838,11 @@ impl<'a> State<'a> {
|
|||
self.commasep(Inconsistent, after, |s, p| s.print_pat(p));
|
||||
self.word("]");
|
||||
}
|
||||
PatKind::Err(_) => {
|
||||
self.popen();
|
||||
self.word("/*ERROR*/");
|
||||
self.pclose();
|
||||
}
|
||||
}
|
||||
self.ann.post(self, AnnNode::Pat(pat))
|
||||
}
|
||||
|
|
|
@ -458,11 +458,15 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|||
needs_to_be_read = true;
|
||||
}
|
||||
}
|
||||
PatKind::Or(_) | PatKind::Box(_) | PatKind::Ref(..) | PatKind::Wild => {
|
||||
PatKind::Or(_)
|
||||
| PatKind::Box(_)
|
||||
| PatKind::Ref(..)
|
||||
| PatKind::Wild
|
||||
| PatKind::Err(_) => {
|
||||
// If the PatKind is Or, Box, or Ref, the decision is made later
|
||||
// as these patterns contains subpatterns
|
||||
// If the PatKind is Wild, the decision is made based on the other patterns being
|
||||
// examined
|
||||
// If the PatKind is Wild or Err, the decision is made based on the other patterns
|
||||
// being examined
|
||||
}
|
||||
}
|
||||
})?
|
||||
|
|
|
@ -767,7 +767,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
|||
| PatKind::Lit(..)
|
||||
| PatKind::Range(..)
|
||||
| PatKind::Never
|
||||
| PatKind::Wild => {
|
||||
| PatKind::Wild
|
||||
| PatKind::Err(_) => {
|
||||
// always ok
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin: pat_info.decl_origin };
|
||||
|
||||
let ty = match pat.kind {
|
||||
PatKind::Wild => expected,
|
||||
PatKind::Wild | PatKind::Err(_) => expected,
|
||||
// FIXME(never_patterns): check the type is uninhabited. If that is not possible within
|
||||
// typeck, do that in a later phase.
|
||||
PatKind::Never => expected,
|
||||
|
@ -325,6 +325,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
PatKind::Ref(..) => AdjustMode::Reset,
|
||||
// A `_` pattern works with any expected type, so there's no need to do anything.
|
||||
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,
|
||||
// and moreover if we peel references off, that will give us the wrong binding type.
|
||||
// Also, we can have a subpattern `binding @ pat`.
|
||||
|
@ -754,7 +756,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
| PatKind::Box(..)
|
||||
| PatKind::Ref(..)
|
||||
| PatKind::Lit(..)
|
||||
| PatKind::Range(..) => break 'block None,
|
||||
| PatKind::Range(..)
|
||||
| PatKind::Err(_) => break 'block None,
|
||||
},
|
||||
|
||||
// Don't provide suggestions in other cases
|
||||
|
|
|
@ -1166,7 +1166,7 @@ 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 | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
|
||||
| Wild | Never | Rest | Lit(..) | 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);
|
||||
|
|
|
@ -345,6 +345,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
hir::PatKind::Or(pats) => PatKind::Or { pats: self.lower_patterns(pats) },
|
||||
|
||||
hir::PatKind::Err(guar) => PatKind::Error(guar),
|
||||
};
|
||||
|
||||
Box::new(Pat { span, ty, kind })
|
||||
|
|
|
@ -303,7 +303,8 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
|||
Ref,
|
||||
Lit,
|
||||
Range,
|
||||
Slice
|
||||
Slice,
|
||||
Err
|
||||
]
|
||||
);
|
||||
hir_visit::walk_pat(self, p)
|
||||
|
@ -576,7 +577,8 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
|
|||
Rest,
|
||||
Never,
|
||||
Paren,
|
||||
MacCall
|
||||
MacCall,
|
||||
Err
|
||||
]
|
||||
);
|
||||
ast_visit::walk_pat(self, p)
|
||||
|
|
|
@ -312,7 +312,9 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
|
|||
|
||||
Symbol::intern(&match p.kind {
|
||||
// FIXME(never_patterns): does this make sense?
|
||||
PatKind::Wild | PatKind::Never | PatKind::Struct(..) => return kw::Underscore,
|
||||
PatKind::Wild | PatKind::Err(_) | PatKind::Never | PatKind::Struct(..) => {
|
||||
return kw::Underscore;
|
||||
}
|
||||
PatKind::Binding(_, _, ident, _) => return ident.name,
|
||||
PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p),
|
||||
PatKind::Or(pats) => {
|
||||
|
|
|
@ -51,7 +51,8 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
|
|||
| PatKind::Binding(..)
|
||||
| PatKind::Wild
|
||||
| PatKind::Never
|
||||
| PatKind::Or(_) => false,
|
||||
| PatKind::Or(_)
|
||||
| PatKind::Err(_) => false,
|
||||
PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)),
|
||||
PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a),
|
||||
PatKind::Ref(x, _) | PatKind::Box(x) => unary_pattern(x),
|
||||
|
|
|
@ -11,7 +11,7 @@ use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdMapEntry, HirIdSet, P
|
|||
use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_span::{ErrorGuaranteed, Symbol};
|
||||
|
||||
use super::MATCH_SAME_ARMS;
|
||||
|
||||
|
@ -167,6 +167,8 @@ enum NormalizedPat<'a> {
|
|||
/// contains everything afterwards. Note that either side, or both sides, may contain zero
|
||||
/// patterns.
|
||||
Slice(&'a [Self], Option<&'a [Self]>),
|
||||
/// A placeholder for a pattern that wasn't well formed in some way.
|
||||
Err(ErrorGuaranteed),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
@ -329,6 +331,7 @@ impl<'a> NormalizedPat<'a> {
|
|||
arena.alloc_from_iter(front.iter().map(|pat| Self::from_pat(cx, arena, pat))),
|
||||
wild_pat.map(|_| &*arena.alloc_from_iter(back.iter().map(|pat| Self::from_pat(cx, arena, pat)))),
|
||||
),
|
||||
PatKind::Err(guar) => Self::Err(guar),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 | Never | Path(..) | Range(..) | Rest | MacCall(_)
|
||||
Ident(.., None) | Lit(_) | Wild | Err(_) | 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.
|
||||
|
|
|
@ -710,6 +710,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
self.slice(start, |pat| self.pat(pat));
|
||||
self.slice(end, |pat| self.pat(pat));
|
||||
},
|
||||
PatKind::Err(_) => kind!("Err"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1007,7 +1007,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
}
|
||||
e.hash(&mut self.s);
|
||||
},
|
||||
PatKind::Never | PatKind::Wild => {},
|
||||
PatKind::Never | PatKind::Wild | PatKind::Err(_) => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1733,6 +1733,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
|
|||
},
|
||||
}
|
||||
},
|
||||
PatKind::Err(_) => true,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,9 +40,11 @@ pub(crate) fn is_short_pattern(pat: &ast::Pat, pat_str: &str) -> bool {
|
|||
|
||||
fn is_short_pattern_inner(pat: &ast::Pat) -> bool {
|
||||
match pat.kind {
|
||||
ast::PatKind::Rest | ast::PatKind::Never | ast::PatKind::Wild | ast::PatKind::Lit(_) => {
|
||||
true
|
||||
}
|
||||
ast::PatKind::Rest
|
||||
| ast::PatKind::Never
|
||||
| ast::PatKind::Wild
|
||||
| ast::PatKind::Err(_)
|
||||
| ast::PatKind::Lit(_) => true,
|
||||
ast::PatKind::Ident(_, _, ref pat) => pat.is_none(),
|
||||
ast::PatKind::Struct(..)
|
||||
| ast::PatKind::MacCall(..)
|
||||
|
@ -274,6 +276,7 @@ impl Rewrite for Pat {
|
|||
PatKind::Paren(ref pat) => pat
|
||||
.rewrite(context, shape.offset_left(1)?.sub_width(1)?)
|
||||
.map(|inner_pat| format!("({})", inner_pat)),
|
||||
PatKind::Err(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue