1
Fork 0

add guard pattern AST node

This commit is contained in:
Max Niederman 2024-08-22 16:49:45 -07:00 committed by Nadrieril
parent 35bbc45f16
commit 9b8bfed73b
7 changed files with 26 additions and 4 deletions

View file

@ -632,9 +632,11 @@ impl Pat {
| PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)), | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
// Trivial wrappers over inner patterns. // Trivial wrappers over inner patterns.
PatKind::Box(s) | PatKind::Deref(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => { PatKind::Box(s)
s.walk(it) | PatKind::Deref(s)
} | PatKind::Ref(s, _)
| PatKind::Paren(s)
| PatKind::Guard(s, _) => s.walk(it),
// These patterns do not contain subpatterns, skip. // These patterns do not contain subpatterns, skip.
PatKind::Wild PatKind::Wild
@ -844,6 +846,9 @@ pub enum PatKind {
// A never pattern `!`. // A never pattern `!`.
Never, Never,
/// A guard pattern (e.g., `x if guard(x)`).
Guard(P<Pat>, P<Expr>),
/// Parentheses in patterns used for grouping (i.e., `(PAT)`). /// Parentheses in patterns used for grouping (i.e., `(PAT)`).
Paren(P<Pat>), Paren(P<Pat>),

View file

@ -1520,6 +1520,10 @@ pub fn walk_pat<T: MutVisitor>(vis: &mut T, pat: &mut P<Pat>) {
visit_opt(e2, |e| vis.visit_expr(e)); visit_opt(e2, |e| vis.visit_expr(e));
vis.visit_span(span); vis.visit_span(span);
} }
PatKind::Guard(p, e) => {
vis.visit_pat(p);
vis.visit_expr(e);
}
PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
visit_thin_vec(elems, |elem| vis.visit_pat(elem)) visit_thin_vec(elems, |elem| vis.visit_pat(elem))
} }

View file

@ -679,6 +679,10 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Res
visit_opt!(visitor, visit_expr, lower_bound); visit_opt!(visitor, visit_expr, lower_bound);
visit_opt!(visitor, visit_expr, upper_bound); visit_opt!(visitor, visit_expr, upper_bound);
} }
PatKind::Guard(subpattern, guard_condition) => {
try_visit!(visitor.visit_pat(subpattern));
try_visit!(visitor.visit_expr(guard_condition));
}
PatKind::Wild | PatKind::Rest | PatKind::Never => {} PatKind::Wild | PatKind::Rest | PatKind::Never => {}
PatKind::Err(_guar) => {} PatKind::Err(_guar) => {}
PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {

View file

@ -114,6 +114,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.lower_range_end(end, e2.is_some()), self.lower_range_end(end, e2.is_some()),
); );
} }
// FIXME(guard_patterns): lower pattern guards to HIR
PatKind::Guard(inner, _) => pattern = inner,
PatKind::Slice(pats) => break self.lower_pat_slice(pats), PatKind::Slice(pats) => break self.lower_pat_slice(pats),
PatKind::Rest => { PatKind::Rest => {
// If we reach here the `..` pattern is not semantically allowed. // If we reach here the `..` pattern is not semantically allowed.

View file

@ -1709,6 +1709,12 @@ impl<'a> State<'a> {
self.print_expr(e, FixupContext::default()); self.print_expr(e, FixupContext::default());
} }
} }
PatKind::Guard(subpat, condition) => {
self.print_pat(subpat);
self.space();
self.word_space("if");
self.print_expr(condition, FixupContext::default());
}
PatKind::Slice(elts) => { PatKind::Slice(elts) => {
self.word("["); self.word("[");
self.commasep(Inconsistent, elts, |s, p| s.print_pat(p)); self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));

View file

@ -1235,7 +1235,7 @@ impl EarlyLintPass for UnusedParens {
self.check_unused_parens_pat(cx, &f.pat, false, false, keep_space); self.check_unused_parens_pat(cx, &f.pat, false, false, keep_space);
}, },
// Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106. // Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
Ident(.., Some(p)) | Box(p) | Deref(p) => self.check_unused_parens_pat(cx, p, true, false, keep_space), Ident(.., Some(p)) | Box(p) | Deref(p) | Guard(p, _) => self.check_unused_parens_pat(cx, p, true, false, keep_space),
// Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342. // Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
// Also avoid linting on `& mut? (p0 | .. | pn)`, #64106. // Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not, keep_space), Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not, keep_space),

View file

@ -556,6 +556,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
Slice, Slice,
Rest, Rest,
Never, Never,
Guard,
Paren, Paren,
MacCall, MacCall,
Err Err