Skip to main content

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}