Skip to content

Commit 9b8bfed

Browse files
max-niedermanNadrieril
authored andcommitted
add guard pattern AST node
1 parent 35bbc45 commit 9b8bfed

File tree

7 files changed

+26
-4
lines changed

7 files changed

+26
-4
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -632,9 +632,11 @@ impl Pat {
632632
| PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
633633

634634
// Trivial wrappers over inner patterns.
635-
PatKind::Box(s) | PatKind::Deref(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => {
636-
s.walk(it)
637-
}
635+
PatKind::Box(s)
636+
| PatKind::Deref(s)
637+
| PatKind::Ref(s, _)
638+
| PatKind::Paren(s)
639+
| PatKind::Guard(s, _) => s.walk(it),
638640

639641
// These patterns do not contain subpatterns, skip.
640642
PatKind::Wild
@@ -844,6 +846,9 @@ pub enum PatKind {
844846
// A never pattern `!`.
845847
Never,
846848

849+
/// A guard pattern (e.g., `x if guard(x)`).
850+
Guard(P<Pat>, P<Expr>),
851+
847852
/// Parentheses in patterns used for grouping (i.e., `(PAT)`).
848853
Paren(P<Pat>),
849854

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,10 @@ pub fn walk_pat<T: MutVisitor>(vis: &mut T, pat: &mut P<Pat>) {
15201520
visit_opt(e2, |e| vis.visit_expr(e));
15211521
vis.visit_span(span);
15221522
}
1523+
PatKind::Guard(p, e) => {
1524+
vis.visit_pat(p);
1525+
vis.visit_expr(e);
1526+
}
15231527
PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
15241528
visit_thin_vec(elems, |elem| vis.visit_pat(elem))
15251529
}

compiler/rustc_ast/src/visit.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,10 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Res
679679
visit_opt!(visitor, visit_expr, lower_bound);
680680
visit_opt!(visitor, visit_expr, upper_bound);
681681
}
682+
PatKind::Guard(subpattern, guard_condition) => {
683+
try_visit!(visitor.visit_pat(subpattern));
684+
try_visit!(visitor.visit_expr(guard_condition));
685+
}
682686
PatKind::Wild | PatKind::Rest | PatKind::Never => {}
683687
PatKind::Err(_guar) => {}
684688
PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {

compiler/rustc_ast_lowering/src/pat.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
114114
self.lower_range_end(end, e2.is_some()),
115115
);
116116
}
117+
// FIXME(guard_patterns): lower pattern guards to HIR
118+
PatKind::Guard(inner, _) => pattern = inner,
117119
PatKind::Slice(pats) => break self.lower_pat_slice(pats),
118120
PatKind::Rest => {
119121
// If we reach here the `..` pattern is not semantically allowed.

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,6 +1709,12 @@ impl<'a> State<'a> {
17091709
self.print_expr(e, FixupContext::default());
17101710
}
17111711
}
1712+
PatKind::Guard(subpat, condition) => {
1713+
self.print_pat(subpat);
1714+
self.space();
1715+
self.word_space("if");
1716+
self.print_expr(condition, FixupContext::default());
1717+
}
17121718
PatKind::Slice(elts) => {
17131719
self.word("[");
17141720
self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));

compiler/rustc_lint/src/unused.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ impl EarlyLintPass for UnusedParens {
12351235
self.check_unused_parens_pat(cx, &f.pat, false, false, keep_space);
12361236
},
12371237
// Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
1238-
Ident(.., Some(p)) | Box(p) | Deref(p) => self.check_unused_parens_pat(cx, p, true, false, keep_space),
1238+
Ident(.., Some(p)) | Box(p) | Deref(p) | Guard(p, _) => self.check_unused_parens_pat(cx, p, true, false, keep_space),
12391239
// Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
12401240
// Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
12411241
Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not, keep_space),

compiler/rustc_passes/src/input_stats.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
556556
Slice,
557557
Rest,
558558
Never,
559+
Guard,
559560
Paren,
560561
MacCall,
561562
Err

0 commit comments

Comments
 (0)