Skip to content

Commit

Permalink
Rollup merge of rust-lang#119967 - ShE3py:patkind-err, r=WaffleLapkin
Browse files Browse the repository at this point in the history
Add `PatKind::Err` to AST/HIR

rust-lang#116715 added `thir::PatKind::Error`; this PR adds `hir::PatKind::Err` and `ast::PatKind::Err` (see rust-lang#118625 (comment).)

---

`@rustbot` label +A-patterns
r? WaffleLapkin
  • Loading branch information
compiler-errors committed Jan 17, 2024
2 parents b37d526 + 7889e99 commit c2e0719
Show file tree
Hide file tree
Showing 23 changed files with 66 additions and 24 deletions.
6 changes: 5 additions & 1 deletion compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,8 @@ impl Pat {
| PatKind::Range(..)
| PatKind::Ident(..)
| PatKind::Path(..)
| PatKind::MacCall(_) => {}
| PatKind::MacCall(_)
| PatKind::Err(_) => {}
}
}

Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
};

Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand All @@ -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)),
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,8 @@ fn resolve_local<'tcx>(
| PatKind::Never
| PatKind::Path(_)
| PatKind::Lit(_)
| PatKind::Range(_, _, _) => false,
| PatKind::Range(_, _, _)
| PatKind::Err(_) => false,
}
}

Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
})?
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
| PatKind::Lit(..)
| PatKind::Range(..)
| PatKind::Never
| PatKind::Wild => {
| PatKind::Wild
| PatKind::Err(_) => {
// always ok
}
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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`.
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_passes/src/hir_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion src/librustdoc/clean/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
3 changes: 2 additions & 1 deletion src/tools/clippy/clippy_lints/src/equatable_if_let.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
5 changes: 4 additions & 1 deletion src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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),
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions src/tools/clippy/clippy_lints/src/utils/author.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_utils/src/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(_) => {},
}
}

Expand Down
1 change: 1 addition & 0 deletions src/tools/clippy/clippy_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1733,6 +1733,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
},
}
},
PatKind::Err(_) => true,
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/tools/rustfmt/src/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(..)
Expand Down Expand Up @@ -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,
}
}
}
Expand Down

0 comments on commit c2e0719

Please sign in to comment.