nova_ast/pattern.rs
1//! Pattern AST nodes (used in `let`, `match` arms, `for` loops).
2
3use nova_diagnostics::Spanned;
4
5use crate::{expr::Literal, Path};
6
7/// A pattern.
8#[derive(Debug, Clone)]
9pub enum Pattern {
10 /// `_` — wildcard, matches anything without binding.
11 Wildcard,
12
13 /// A literal value pattern: `0`, `true`, `'a'`, `"str"`.
14 Lit(Literal),
15
16 /// A bare identifier binding: `x`, `mut y`.
17 Ident { is_mut: bool, name: Spanned<String> },
18
19 /// A binding with a sub-pattern: `x @ 0..=9`.
20 Binding {
21 name: Spanned<String>,
22 inner: Box<Spanned<Pattern>>,
23 },
24
25 /// A tuple-struct / enum variant pattern: `Some(x)`, `Ok(v)`.
26 TupleStruct {
27 path: Path,
28 fields: Vec<Spanned<Pattern>>,
29 },
30
31 /// A record / struct pattern: `Point { x, y }`.
32 Record {
33 path: Path,
34 fields: Vec<FieldPat>,
35 rest: bool,
36 },
37
38 /// A tuple pattern: `(a, b, c)`.
39 Tuple(Vec<Spanned<Pattern>>),
40
41 /// An array pattern: `[a, b, c]`.
42 Array(Vec<Spanned<Pattern>>),
43
44 /// An or-pattern: `None | Some(0)`.
45 Or(Vec<Spanned<Pattern>>),
46
47 /// A range pattern: `0..=9`, `'a'..='z'`.
48 Range {
49 lo: Box<Spanned<Pattern>>,
50 hi: Box<Spanned<Pattern>>,
51 inclusive: bool,
52 },
53
54 /// A bare path that could be an enum variant without payload: `None`, `MyEnum::Variant`.
55 Path(Path),
56}
57
58/// A single field in a record pattern.
59#[derive(Debug, Clone)]
60pub struct FieldPat {
61 pub name: Spanned<String>,
62 /// `None` means shorthand `{ x }` which binds to a variable named `x`.
63 pub pattern: Option<Spanned<Pattern>>,
64}