Skip to main content

wolf_ast/
lib.rs

1//! The syntax tree of wolfpack (spec chapters 2 and 3).
2//!
3//! The tree mirrors the source closely: it keeps sections in written order, doc comments and
4//! spans, and it may contain [`ExprKind::Error`] and similar nodes where the parser recovered from
5//! an error. Meaning is assigned by later phases; for example `a.b.c` is a chain of field accesses
6//! here, whether `a` turns out to be a module, a type or a variable.
7
8mod dump;
9
10use wolf_span::Span;
11
12pub use dump::dump;
13
14/// Identifies an expression, pattern or type node, for side tables in later phases.
15#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
16pub struct NodeId(pub u32);
17
18/// A name with its position.
19#[derive(Clone, Debug, PartialEq)]
20pub struct Ident {
21    /// The text of the name.
22    pub name: String,
23    /// Where it is.
24    pub span: Span,
25}
26
27/// A dotted name such as `users.model` or `StorageError.Full`.
28#[derive(Clone, Debug, PartialEq)]
29pub struct Path {
30    /// The parts between the dots, at least one.
31    pub segments: Vec<Ident>,
32    /// The whole path.
33    pub span: Span,
34}
35
36/// A doc comment.
37#[derive(Clone, Debug, PartialEq)]
38pub struct Doc {
39    /// The text after the marker.
40    pub text: String,
41    /// `true` for `//!` and `/*! */`.
42    pub inner: bool,
43    /// Where it is.
44    pub span: Span,
45}
46
47/// A whole source file.
48#[derive(Clone, Debug, PartialEq)]
49pub struct File {
50    /// Inner doc comments before the `module` line: the module documentation.
51    pub docs: Vec<Doc>,
52    /// The `module` line, if present.
53    pub module: Option<Path>,
54    /// Sections in the order they are written.
55    pub sections: Vec<Section>,
56}
57
58/// The nine parts of a file, in their required order (spec chapter 2, section 2).
59#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
60pub enum SectionKind {
61    /// `imports`
62    Imports,
63    /// `extern`
64    Extern,
65    /// `config`
66    Config,
67    /// `types`
68    Types,
69    /// `interfaces`
70    Interfaces,
71    /// `impl`
72    Impl,
73    /// `functions`
74    Functions,
75    /// `tests`
76    Tests,
77}
78
79impl SectionKind {
80    /// All sections in their required order.
81    pub const ALL: [SectionKind; 8] = [
82        SectionKind::Imports,
83        SectionKind::Extern,
84        SectionKind::Config,
85        SectionKind::Types,
86        SectionKind::Interfaces,
87        SectionKind::Impl,
88        SectionKind::Functions,
89        SectionKind::Tests,
90    ];
91
92    /// The name of the section as written in source.
93    pub fn name(self) -> &'static str {
94        match self {
95            SectionKind::Imports => "imports",
96            SectionKind::Extern => "extern",
97            SectionKind::Config => "config",
98            SectionKind::Types => "types",
99            SectionKind::Interfaces => "interfaces",
100            SectionKind::Impl => "impl",
101            SectionKind::Functions => "functions",
102            SectionKind::Tests => "tests",
103        }
104    }
105
106    /// The section with this name.
107    pub fn from_name(name: &str) -> Option<SectionKind> {
108        SectionKind::ALL
109            .into_iter()
110            .find(|kind| kind.name() == name)
111    }
112}
113
114/// A section and its entries.
115#[derive(Clone, Debug, PartialEq)]
116pub struct Section {
117    /// Which section.
118    pub kind: SectionKind,
119    /// The section name in the header.
120    pub name_span: Span,
121    /// From the name to the closing `}`.
122    pub span: Span,
123    /// The entries. They may include entries that belong to another section; the parser reports
124    /// those (E0205) and keeps them.
125    pub items: Vec<Item>,
126}
127
128/// A declaration inside a section.
129#[derive(Clone, Debug, PartialEq)]
130pub struct Item {
131    /// Outer doc comments before it.
132    pub docs: Vec<Doc>,
133    /// What it is.
134    pub kind: ItemKind,
135    /// The whole declaration.
136    pub span: Span,
137}
138
139/// The kinds of declarations.
140#[derive(Clone, Debug, PartialEq)]
141pub enum ItemKind {
142    /// An entry of `imports`.
143    Import(Import),
144    /// A target block of `extern`: `go { ... }`.
145    ExternTarget(ExternTarget),
146    /// A constant of `config`.
147    Config(ConfigEntry),
148    /// `struct`
149    Struct(StructDecl),
150    /// `enum`
151    Enum(EnumDecl),
152    /// `type Name = Type`
153    Alias(AliasDecl),
154    /// `intrinsic type Name<T>`: a built-in type declared in std (chapter 7, section 1).
155    IntrinsicType(IntrinsicTypeDecl),
156    /// `interface`
157    Interface(InterfaceDecl),
158    /// A block of `impl`.
159    Impl(ImplBlock),
160    /// `fn`
161    Fn(FnDecl),
162    /// `test "name" { ... }`
163    Test(TestDecl),
164}
165
166impl ItemKind {
167    /// The section this kind of declaration belongs in. Functions are also allowed in `tests`.
168    pub fn home(&self) -> SectionKind {
169        match self {
170            ItemKind::Import(_) => SectionKind::Imports,
171            ItemKind::ExternTarget(_) => SectionKind::Extern,
172            ItemKind::Config(_) => SectionKind::Config,
173            ItemKind::Struct(_)
174            | ItemKind::Enum(_)
175            | ItemKind::Alias(_)
176            | ItemKind::IntrinsicType(_) => SectionKind::Types,
177            ItemKind::Interface(_) => SectionKind::Interfaces,
178            ItemKind::Impl(_) => SectionKind::Impl,
179            ItemKind::Fn(_) => SectionKind::Functions,
180            ItemKind::Test(_) => SectionKind::Tests,
181        }
182    }
183
184    /// A short description for diagnostics: "`struct`", "import", ...
185    pub fn describe(&self) -> &'static str {
186        match self {
187            ItemKind::Import(_) => "import",
188            ItemKind::ExternTarget(_) => "extern block",
189            ItemKind::Config(_) => "constant",
190            ItemKind::Struct(_) => "`struct`",
191            ItemKind::Enum(_) => "`enum`",
192            ItemKind::Alias(_) => "type alias",
193            ItemKind::IntrinsicType(_) => "`intrinsic type`",
194            ItemKind::Interface(_) => "`interface`",
195            ItemKind::Impl(_) => "`impl` block",
196            ItemKind::Fn(_) => "`fn`",
197            ItemKind::Test(_) => "test",
198        }
199    }
200}
201
202/// An import (spec chapter 6, section 2).
203#[derive(Clone, Debug, PartialEq)]
204pub struct Import {
205    /// `pub` import (a re-export).
206    pub public: bool,
207    /// The module path.
208    pub path: Path,
209    /// `as name` after a whole-module import.
210    pub alias: Option<Ident>,
211    /// The `.{A, B as C}` group, if present.
212    pub names: Option<Vec<ImportName>>,
213}
214
215/// One name in an import group.
216#[derive(Clone, Debug, PartialEq)]
217pub struct ImportName {
218    /// The imported name.
219    pub name: Ident,
220    /// `as` alias.
221    pub alias: Option<Ident>,
222}
223
224/// A target block inside `extern`.
225#[derive(Clone, Debug, PartialEq)]
226pub struct ExternTarget {
227    /// `ts`, `go` or `rust` (anything else is reported).
228    pub target: Ident,
229    /// The declarations.
230    pub decls: Vec<ExternDecl>,
231}
232
233/// A declaration inside an extern target block.
234#[derive(Clone, Debug, PartialEq)]
235pub struct ExternDecl {
236    /// Doc comments.
237    pub docs: Vec<Doc>,
238    /// `pub`
239    pub public: bool,
240    /// Function or type.
241    pub kind: ExternDeclKind,
242    /// The target path after `from`.
243    pub from: StrLit,
244    /// The whole declaration.
245    pub span: Span,
246}
247
248/// What an extern declaration declares.
249#[derive(Clone, Debug, PartialEq)]
250pub enum ExternDeclKind {
251    /// `fn name(params) -> T`
252    Fn(FnSig),
253    /// `type Name`
254    Type(Ident),
255}
256
257/// A string literal with its position.
258#[derive(Clone, Debug, PartialEq)]
259pub struct StrLit {
260    /// The value with escapes resolved.
261    pub value: String,
262    /// Where it is.
263    pub span: Span,
264}
265
266/// `name: Type = value` in `config`.
267#[derive(Clone, Debug, PartialEq)]
268pub struct ConfigEntry {
269    /// `pub`
270    pub public: bool,
271    /// The name.
272    pub name: Ident,
273    /// The written type.
274    pub ty: Ty,
275    /// The initializer.
276    pub value: Expr,
277}
278
279/// A type parameter with its bounds: `T: Comparable + Copyable`.
280#[derive(Clone, Debug, PartialEq)]
281pub struct GenericParam {
282    /// The name.
283    pub name: Ident,
284    /// The interfaces after `:`.
285    pub bounds: Vec<Ty>,
286}
287
288/// `struct Name<T> { fields }`
289#[derive(Clone, Debug, PartialEq)]
290pub struct StructDecl {
291    /// `pub`
292    pub public: bool,
293    /// The name.
294    pub name: Ident,
295    /// Type parameters.
296    pub generics: Vec<GenericParam>,
297    /// The fields.
298    pub fields: Vec<Field>,
299}
300
301/// A field of a struct or of a variant.
302#[derive(Clone, Debug, PartialEq)]
303pub struct Field {
304    /// Doc comments.
305    pub docs: Vec<Doc>,
306    /// `pub` (always `false` in variants).
307    pub public: bool,
308    /// The name.
309    pub name: Ident,
310    /// The type.
311    pub ty: Ty,
312    /// The whole field.
313    pub span: Span,
314}
315
316/// `enum Name<T> { variants }`
317#[derive(Clone, Debug, PartialEq)]
318pub struct EnumDecl {
319    /// `pub`
320    pub public: bool,
321    /// The name.
322    pub name: Ident,
323    /// Type parameters.
324    pub generics: Vec<GenericParam>,
325    /// The variants.
326    pub variants: Vec<Variant>,
327}
328
329/// A variant of an enum.
330#[derive(Clone, Debug, PartialEq)]
331pub struct Variant {
332    /// Doc comments.
333    pub docs: Vec<Doc>,
334    /// The name.
335    pub name: Ident,
336    /// The payload.
337    pub payload: VariantPayload,
338    /// The whole variant.
339    pub span: Span,
340}
341
342/// The data a variant carries.
343#[derive(Clone, Debug, PartialEq)]
344pub enum VariantPayload {
345    /// `Full`
346    None,
347    /// `Io(String)`
348    Tuple(Vec<Ty>),
349    /// `Moved { x: Int, y: Int }`
350    Struct(Vec<Field>),
351}
352
353/// `type Name<T> = Type`
354#[derive(Clone, Debug, PartialEq)]
355pub struct AliasDecl {
356    /// `pub`
357    pub public: bool,
358    /// The name.
359    pub name: Ident,
360    /// Type parameters.
361    pub generics: Vec<GenericParam>,
362    /// The aliased type.
363    pub ty: Ty,
364}
365
366/// `intrinsic type Name<T>`
367#[derive(Clone, Debug, PartialEq)]
368pub struct IntrinsicTypeDecl {
369    /// `pub`
370    pub public: bool,
371    /// The name.
372    pub name: Ident,
373    /// Type parameters.
374    pub generics: Vec<GenericParam>,
375}
376
377/// `interface Name<T> { signatures }`
378#[derive(Clone, Debug, PartialEq)]
379pub struct InterfaceDecl {
380    /// `pub`
381    pub public: bool,
382    /// The name.
383    pub name: Ident,
384    /// Type parameters.
385    pub generics: Vec<GenericParam>,
386    /// The method signatures.
387    pub methods: Vec<MethodSig>,
388}
389
390/// A signature inside an interface.
391#[derive(Clone, Debug, PartialEq)]
392pub struct MethodSig {
393    /// Doc comments.
394    pub docs: Vec<Doc>,
395    /// The signature.
396    pub sig: FnSig,
397}
398
399/// A block in `impl`: `Stack<T: Comparable>: Container<T> { methods }`.
400#[derive(Clone, Debug, PartialEq)]
401pub struct ImplBlock {
402    /// The implemented type.
403    pub type_name: Ident,
404    /// Type parameters declared in the head.
405    pub generics: Vec<GenericParam>,
406    /// The interface after `:`, if this is an interface implementation.
407    pub interface: Option<Ty>,
408    /// The methods, each with its doc comments.
409    pub methods: Vec<Method>,
410}
411
412/// A method inside an impl block.
413#[derive(Clone, Debug, PartialEq)]
414pub struct Method {
415    /// Doc comments.
416    pub docs: Vec<Doc>,
417    /// The function.
418    pub decl: FnDecl,
419    /// The whole method.
420    pub span: Span,
421}
422
423/// A function or method declaration.
424#[derive(Clone, Debug, PartialEq)]
425pub struct FnDecl {
426    /// `pub`
427    pub public: bool,
428    /// `intrinsic`
429    pub intrinsic: bool,
430    /// The signature.
431    pub sig: FnSig,
432    /// The body; absent for `intrinsic` functions and on some errors.
433    pub body: Option<Block>,
434}
435
436/// Name, type parameters, parameters and result.
437#[derive(Clone, Debug, PartialEq)]
438pub struct FnSig {
439    /// The name.
440    pub name: Ident,
441    /// Type parameters.
442    pub generics: Vec<GenericParam>,
443    /// Parameters, `self` included.
444    pub params: Vec<Param>,
445    /// The written result type; `None` means `Void`.
446    pub ret: Option<Ty>,
447    /// From `fn` to the end of the result type.
448    pub span: Span,
449}
450
451/// How a value is passed (spec chapter 5, section 5).
452#[derive(Clone, Copy, Debug, PartialEq, Eq)]
453pub enum Mode {
454    /// No marker: read access.
455    Read,
456    /// `mut`
457    Mut,
458    /// `own`
459    Own,
460}
461
462/// A parameter.
463#[derive(Clone, Debug, PartialEq)]
464pub struct Param {
465    /// The mode.
466    pub mode: Mode,
467    /// `self` or a named parameter.
468    pub kind: ParamKind,
469    /// The whole parameter.
470    pub span: Span,
471}
472
473/// The two kinds of parameters.
474#[derive(Clone, Debug, PartialEq)]
475pub enum ParamKind {
476    /// `self`
477    SelfParam,
478    /// `name: Type`
479    Named {
480        /// The name.
481        name: Ident,
482        /// The type.
483        ty: Ty,
484    },
485}
486
487/// `test "name" { body }`
488#[derive(Clone, Debug, PartialEq)]
489pub struct TestDecl {
490    /// The test name.
491    pub name: StrLit,
492    /// The body.
493    pub body: Block,
494}
495
496/// A written type.
497#[derive(Clone, Debug, PartialEq)]
498pub struct Ty {
499    /// Node id.
500    pub id: NodeId,
501    /// What it is.
502    pub kind: TyKind,
503    /// Where it is.
504    pub span: Span,
505}
506
507/// The forms of a written type.
508#[derive(Clone, Debug, PartialEq)]
509pub enum TyKind {
510    /// `Int`, `List<User>`, `model.User`.
511    Path {
512        /// The name.
513        path: Path,
514        /// Type arguments.
515        args: Vec<Ty>,
516    },
517    /// `fn(Int, mut List<Int>) -> Bool`
518    Fn {
519        /// Parameter modes and types.
520        params: Vec<(Mode, Ty)>,
521        /// The result; `None` means `Void`.
522        ret: Option<Box<Ty>>,
523    },
524    /// `Self`
525    SelfType,
526    /// A type that could not be parsed.
527    Error,
528}
529
530/// A block of statements.
531#[derive(Clone, Debug, PartialEq)]
532pub struct Block {
533    /// The statements. A final expression statement is the value of the block.
534    pub stmts: Vec<Stmt>,
535    /// From `{` to `}`.
536    pub span: Span,
537}
538
539/// A statement.
540#[derive(Clone, Debug, PartialEq)]
541pub struct Stmt {
542    /// What it is.
543    pub kind: StmtKind,
544    /// Where it is.
545    pub span: Span,
546}
547
548/// The forms of statements.
549#[derive(Clone, Debug, PartialEq)]
550pub enum StmtKind {
551    /// `let x: T = e`, `var x = e`, `let _ = e`.
552    Let {
553        /// `var`
554        mutable: bool,
555        /// The name; `None` for `let _`.
556        name: Option<Ident>,
557        /// The written type.
558        ty: Option<Ty>,
559        /// The initializer.
560        value: Expr,
561    },
562    /// `place op= value`
563    Assign {
564        /// The place.
565        target: Expr,
566        /// `=`, `+=`, ...
567        op: AssignOp,
568        /// The value.
569        value: Expr,
570    },
571    /// `while cond { body }`
572    While {
573        /// The condition.
574        cond: Expr,
575        /// The body.
576        body: Block,
577    },
578    /// `for x in mode? collection { body }` or `for i in a..b { body }`.
579    For {
580        /// The loop variable.
581        var: Ident,
582        /// What is iterated.
583        iter: ForIter,
584        /// The body.
585        body: Block,
586    },
587    /// An expression used as a statement.
588    Expr(Expr),
589}
590
591/// What a `for` loop walks over.
592#[derive(Clone, Debug, PartialEq)]
593pub enum ForIter {
594    /// A collection with an optional mode.
595    Collection {
596        /// `mut`, `own` or read.
597        mode: Mode,
598        /// The collection.
599        expr: Expr,
600    },
601    /// `start..end` or `start..=end`.
602    Range {
603        /// The first value.
604        start: Expr,
605        /// The bound.
606        end: Expr,
607        /// `..=`
608        inclusive: bool,
609    },
610}
611
612/// Assignment operators.
613#[derive(Clone, Copy, Debug, PartialEq, Eq)]
614#[allow(missing_docs)]
615pub enum AssignOp {
616    Assign,
617    Add,
618    Sub,
619    Mul,
620    Div,
621    Rem,
622    BitAnd,
623    BitOr,
624    BitXor,
625    Shl,
626    Shr,
627}
628
629/// An expression.
630#[derive(Clone, Debug, PartialEq)]
631pub struct Expr {
632    /// Node id.
633    pub id: NodeId,
634    /// What it is.
635    pub kind: ExprKind,
636    /// Where it is.
637    pub span: Span,
638}
639
640/// The forms of expressions.
641#[derive(Clone, Debug, PartialEq)]
642pub enum ExprKind {
643    /// An integer literal.
644    Int(u64),
645    /// A float literal.
646    Float(f64),
647    /// A string literal.
648    Str(String),
649    /// `true` or `false`.
650    Bool(bool),
651    /// `()`
652    Unit,
653    /// A name.
654    Name(Ident),
655    /// `self`
656    SelfValue,
657    /// `Self`
658    SelfType,
659    /// `(e)`
660    Paren(Box<Expr>),
661    /// `[a, b]`
662    List(Vec<Expr>),
663    /// `["a": 1]`, `[:]`
664    Map(Vec<(Expr, Expr)>),
665    /// `Path.<T> { field: value, shorthand }`
666    StructLit {
667        /// The type name.
668        path: Path,
669        /// Explicit type arguments `.<T>`.
670        type_args: Vec<Ty>,
671        /// The fields.
672        fields: Vec<FieldInit>,
673    },
674    /// `base.name`
675    Field {
676        /// The left side.
677        base: Box<Expr>,
678        /// The name after the dot.
679        name: Ident,
680    },
681    /// `base.<T, U>`
682    TypeArgs {
683        /// The left side.
684        base: Box<Expr>,
685        /// The type arguments.
686        args: Vec<Ty>,
687    },
688    /// `callee(args)`
689    Call {
690        /// What is called.
691        callee: Box<Expr>,
692        /// The arguments.
693        args: Vec<Arg>,
694    },
695    /// `base[index]`
696    Index {
697        /// The collection.
698        base: Box<Expr>,
699        /// The index.
700        index: Box<Expr>,
701    },
702    /// `base[a..b]` and the other slice forms.
703    Slice {
704        /// The collection.
705        base: Box<Expr>,
706        /// The start, if written.
707        start: Option<Box<Expr>>,
708        /// The end, if written.
709        end: Option<Box<Expr>>,
710        /// `..=`
711        inclusive: bool,
712    },
713    /// `e?`
714    Try(Box<Expr>),
715    /// `-e`, `!e`, `~e`
716    Unary {
717        /// The operator.
718        op: UnaryOp,
719        /// The operand.
720        operand: Box<Expr>,
721    },
722    /// `a op b`
723    Binary {
724        /// The operator.
725        op: BinaryOp,
726        /// Left operand.
727        lhs: Box<Expr>,
728        /// Right operand.
729        rhs: Box<Expr>,
730    },
731    /// `|x, y: Int| body` or `|x| -> T { body }`.
732    Closure {
733        /// The parameters.
734        params: Vec<ClosureParam>,
735        /// The written result type.
736        ret: Option<Ty>,
737        /// The body.
738        body: Box<Expr>,
739    },
740    /// `{ ... }` as the body of a closure or a match arm.
741    Block(Block),
742    /// `if cond { } else ...`
743    If {
744        /// The condition.
745        cond: Box<Expr>,
746        /// The first branch.
747        then: Block,
748        /// `else` followed by a block or another `if`.
749        otherwise: Option<Box<Expr>>,
750    },
751    /// `match mode? scrutinee { arms }`
752    Match {
753        /// The mode marker.
754        mode: Mode,
755        /// The matched value.
756        scrutinee: Box<Expr>,
757        /// The arms.
758        arms: Vec<Arm>,
759    },
760    /// `return e?`
761    Return(Option<Box<Expr>>),
762    /// `break`
763    Break,
764    /// `continue`
765    Continue,
766    /// Something that could not be parsed; a diagnostic was reported.
767    Error,
768}
769
770/// A field in a struct literal.
771#[derive(Clone, Debug, PartialEq)]
772pub struct FieldInit {
773    /// Node id, for what a shorthand field names.
774    pub id: NodeId,
775    /// The field name.
776    pub name: Ident,
777    /// The value; `None` for the shorthand `User { id }`.
778    pub value: Option<Expr>,
779}
780
781/// An argument of a call.
782#[derive(Clone, Debug, PartialEq)]
783pub struct Arg {
784    /// `mut`, `own` or none.
785    pub mode: Mode,
786    /// The value.
787    pub value: Expr,
788}
789
790/// A closure parameter.
791#[derive(Clone, Debug, PartialEq)]
792pub struct ClosureParam {
793    /// The name.
794    pub name: Ident,
795    /// The written type.
796    pub ty: Option<Ty>,
797}
798
799/// An arm of a `match`.
800#[derive(Clone, Debug, PartialEq)]
801pub struct Arm {
802    /// The pattern.
803    pub pattern: Pat,
804    /// `if` guard.
805    pub guard: Option<Expr>,
806    /// The result.
807    pub body: Expr,
808    /// The whole arm.
809    pub span: Span,
810}
811
812/// Unary operators.
813#[derive(Clone, Copy, Debug, PartialEq, Eq)]
814pub enum UnaryOp {
815    /// `-`
816    Neg,
817    /// `!`
818    Not,
819    /// `~`
820    BitNot,
821}
822
823/// Binary operators.
824#[derive(Clone, Copy, Debug, PartialEq, Eq)]
825#[allow(missing_docs)]
826pub enum BinaryOp {
827    Mul,
828    Div,
829    Rem,
830    Add,
831    Sub,
832    Shl,
833    Shr,
834    BitAnd,
835    BitXor,
836    BitOr,
837    Eq,
838    NotEq,
839    Lt,
840    Le,
841    Gt,
842    Ge,
843    And,
844    Or,
845}
846
847impl BinaryOp {
848    /// The operator as written.
849    pub fn symbol(self) -> &'static str {
850        match self {
851            BinaryOp::Mul => "*",
852            BinaryOp::Div => "/",
853            BinaryOp::Rem => "%",
854            BinaryOp::Add => "+",
855            BinaryOp::Sub => "-",
856            BinaryOp::Shl => "<<",
857            BinaryOp::Shr => ">>",
858            BinaryOp::BitAnd => "&",
859            BinaryOp::BitXor => "^",
860            BinaryOp::BitOr => "|",
861            BinaryOp::Eq => "==",
862            BinaryOp::NotEq => "!=",
863            BinaryOp::Lt => "<",
864            BinaryOp::Le => "<=",
865            BinaryOp::Gt => ">",
866            BinaryOp::Ge => ">=",
867            BinaryOp::And => "&&",
868            BinaryOp::Or => "||",
869        }
870    }
871
872    /// Whether this is one of the non-associative comparison operators.
873    pub fn is_comparison(self) -> bool {
874        matches!(
875            self,
876            BinaryOp::Eq
877                | BinaryOp::NotEq
878                | BinaryOp::Lt
879                | BinaryOp::Le
880                | BinaryOp::Gt
881                | BinaryOp::Ge
882        )
883    }
884}
885
886/// A pattern in a `match` arm.
887#[derive(Clone, Debug, PartialEq)]
888pub struct Pat {
889    /// Node id.
890    pub id: NodeId,
891    /// What it is.
892    pub kind: PatKind,
893    /// Where it is.
894    pub span: Span,
895}
896
897/// The forms of patterns (spec chapter 3, section 7).
898#[derive(Clone, Debug, PartialEq)]
899pub enum PatKind {
900    /// `_`
901    Wild,
902    /// A lone name: a binding, or a payload-less variant or constant (decided later).
903    Name(Ident),
904    /// An integer, possibly negative.
905    Int {
906        /// `-`
907        negative: bool,
908        /// The magnitude.
909        value: u64,
910    },
911    /// A string.
912    Str(String),
913    /// `true` or `false`.
914    Bool(bool),
915    /// A dotted path without payload: `StorageError.Full`.
916    Path(Path),
917    /// `Some(x)`, `Shape.Circle(r)`.
918    Tuple {
919        /// The variant.
920        path: Path,
921        /// The payload patterns.
922        items: Vec<Pat>,
923    },
924    /// `Point { x, y: 0, .. }`.
925    Struct {
926        /// The struct or variant.
927        path: Path,
928        /// The field patterns.
929        fields: Vec<FieldPat>,
930        /// `..` at the end.
931        rest: bool,
932    },
933    /// `A | B`
934    Or(Vec<Pat>),
935    /// A pattern that could not be parsed.
936    Error,
937}
938
939/// A field in a struct pattern.
940#[derive(Clone, Debug, PartialEq)]
941pub struct FieldPat {
942    /// Node id, for the binding of a shorthand field.
943    pub id: NodeId,
944    /// The field name.
945    pub name: Ident,
946    /// The sub-pattern; `None` for the shorthand `{ x }`.
947    pub pat: Option<Pat>,
948}