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