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 super-interfaces after `:` (spec chapter 4, section 8.2, rule 6).
464    pub supers: Vec<Ty>,
465    /// The methods: signatures, and defaults with a body.
466    pub methods: Vec<MethodSig>,
467}
468
469/// A method of an interface: a signature, or a default with its body (spec chapter 4,
470/// section 8.2, rule 4).
471#[derive(Clone, Debug, PartialEq)]
472pub struct MethodSig {
473    /// Doc comments.
474    pub docs: Vec<Doc>,
475    /// The method; its body is the default.
476    pub decl: FnDecl,
477}
478
479/// A block in `impl`: `Stack<T: Comparable>: Container<T> { methods }`.
480#[derive(Clone, Debug, PartialEq)]
481pub struct ImplBlock {
482    /// The implemented type.
483    pub type_name: Ident,
484    /// Type parameters declared in the head.
485    pub generics: Vec<GenericParam>,
486    /// The interface after `:`, if this is an interface implementation.
487    pub interface: Option<Ty>,
488    /// The methods, each with its doc comments.
489    pub methods: Vec<Method>,
490}
491
492/// A method inside an impl block.
493#[derive(Clone, Debug, PartialEq)]
494pub struct Method {
495    /// Doc comments.
496    pub docs: Vec<Doc>,
497    /// The function.
498    pub decl: FnDecl,
499    /// The whole method.
500    pub span: Span,
501}
502
503/// A function or method declaration.
504#[derive(Clone, Debug, PartialEq)]
505pub struct FnDecl {
506    /// `pub`
507    pub public: bool,
508    /// `intrinsic`
509    pub intrinsic: bool,
510    /// The signature.
511    pub sig: FnSig,
512    /// The body; absent for `intrinsic` functions and on some errors.
513    pub body: Option<Block>,
514    /// The word `override` before `fn`, which replaces a default (spec chapter 4, section 8.3).
515    pub overrides: Option<Span>,
516}
517
518/// Name, type parameters, parameters and result.
519#[derive(Clone, Debug, PartialEq)]
520pub struct FnSig {
521    /// The name.
522    pub name: Ident,
523    /// Type parameters.
524    pub generics: Vec<GenericParam>,
525    /// Parameters, `self` included.
526    pub params: Vec<Param>,
527    /// The written result type; `None` means `Void`.
528    pub ret: Option<Ty>,
529    /// `where T: Bound` after the result type: bounds that a method adds to the type parameters
530    /// of its `impl` block (spec chapter 4, section 8.6).
531    pub where_bounds: Vec<GenericParam>,
532    /// From `fn` to the end of the result type.
533    pub span: Span,
534}
535
536/// How a value is passed (spec chapter 5, section 5).
537#[derive(Clone, Copy, Debug, PartialEq, Eq)]
538pub enum Mode {
539    /// No marker: read access.
540    Read,
541    /// `mut`
542    Mut,
543    /// `own`
544    Own,
545}
546
547/// A parameter.
548#[derive(Clone, Debug, PartialEq)]
549pub struct Param {
550    /// The mode.
551    pub mode: Mode,
552    /// `self` or a named parameter.
553    pub kind: ParamKind,
554    /// The whole parameter.
555    pub span: Span,
556}
557
558/// The two kinds of parameters.
559#[derive(Clone, Debug, PartialEq)]
560pub enum ParamKind {
561    /// `self`
562    SelfParam,
563    /// `name: Type`
564    Named {
565        /// The name.
566        name: Ident,
567        /// The type.
568        ty: Ty,
569    },
570}
571
572/// `test "name" { body }`
573#[derive(Clone, Debug, PartialEq)]
574pub struct TestDecl {
575    /// The test name.
576    pub name: StrLit,
577    /// The body.
578    pub body: Block,
579}
580
581/// A written type.
582#[derive(Clone, Debug, PartialEq)]
583pub struct Ty {
584    /// Node id.
585    pub id: NodeId,
586    /// What it is.
587    pub kind: TyKind,
588    /// Where it is.
589    pub span: Span,
590}
591
592/// The forms of a written type.
593#[derive(Clone, Debug, PartialEq)]
594pub enum TyKind {
595    /// `Int`, `List<User>`, `model.User`.
596    Path {
597        /// The name.
598        path: Path,
599        /// Type arguments.
600        args: Vec<Ty>,
601    },
602    /// `fn(Int, mut List<Int>) -> Bool`
603    Fn {
604        /// Parameter modes and types.
605        params: Vec<(Mode, Ty)>,
606        /// The result; `None` means `Void`.
607        ret: Option<Box<Ty>>,
608    },
609    /// `Self`
610    SelfType,
611    /// A type that could not be parsed.
612    Error,
613}
614
615/// A block of statements.
616#[derive(Clone, Debug, PartialEq)]
617pub struct Block {
618    /// The statements. A final expression statement is the value of the block.
619    pub stmts: Vec<Stmt>,
620    /// From `{` to `}`.
621    pub span: Span,
622}
623
624/// A statement.
625#[derive(Clone, Debug, PartialEq)]
626pub struct Stmt {
627    /// What it is.
628    pub kind: StmtKind,
629    /// Where it is.
630    pub span: Span,
631}
632
633/// The forms of statements.
634#[derive(Clone, Debug, PartialEq)]
635pub enum StmtKind {
636    /// `let x: T = e`, `var x = e`, `let _ = e`.
637    Let {
638        /// `var`
639        mutable: bool,
640        /// The name; `None` for `let _`.
641        name: Option<Ident>,
642        /// The written type.
643        ty: Option<Ty>,
644        /// The initializer.
645        value: Expr,
646    },
647    /// `let Point { x, y } = e`, `var Config { name, .. } = e`: a destructuring `let` (0.2).
648    LetPattern {
649        /// `var`
650        mutable: bool,
651        /// The pattern; the types check that it always matches.
652        pattern: Pat,
653        /// The initializer.
654        value: Expr,
655    },
656    /// `place op= value`
657    Assign {
658        /// The place.
659        target: Expr,
660        /// `=`, `+=`, ...
661        op: AssignOp,
662        /// The value.
663        value: Expr,
664    },
665    /// `label: while cond { body }`
666    While {
667        /// The label of the loop.
668        label: Option<Ident>,
669        /// The condition.
670        cond: Expr,
671        /// The body.
672        body: Block,
673    },
674    /// `label: while let pattern = mode? value { body }` (0.2), or a chain of conditions with a
675    /// `let` among them (spec chapter 3, section 5, rule 14a).
676    WhileLet {
677        /// The label of the loop.
678        label: Option<Ident>,
679        /// The items of the condition, evaluated before every iteration; at least one is a `let`.
680        items: Vec<CondItem>,
681        /// The body.
682        body: Block,
683    },
684    /// `label: for x in mode? collection { body }` or `for i in a..b { body }`.
685    For {
686        /// The label of the loop.
687        label: Option<Ident>,
688        /// The loop variable.
689        var: Ident,
690        /// What is iterated.
691        iter: ForIter,
692        /// The body.
693        body: Block,
694    },
695    /// An expression used as a statement.
696    Expr(Expr),
697}
698
699/// What a `for` loop walks over.
700#[derive(Clone, Debug, PartialEq)]
701pub enum ForIter {
702    /// A collection with an optional mode.
703    Collection {
704        /// `mut`, `own` or read.
705        mode: Mode,
706        /// The collection.
707        expr: Expr,
708    },
709    /// `start..end` or `start..=end`.
710    Range {
711        /// The first value.
712        start: Expr,
713        /// The bound.
714        end: Expr,
715        /// `..=`
716        inclusive: bool,
717    },
718}
719
720/// Assignment operators.
721#[derive(Clone, Copy, Debug, PartialEq, Eq)]
722#[allow(missing_docs)]
723pub enum AssignOp {
724    Assign,
725    Add,
726    Sub,
727    Mul,
728    Div,
729    Rem,
730    BitAnd,
731    BitOr,
732    BitXor,
733    Shl,
734    Shr,
735}
736
737/// One item of the condition of an `if let` or a `while let`, joined to the others by `&&` (spec
738/// chapter 3, section 5, rule 14a).
739#[derive(Clone, Debug, PartialEq)]
740pub enum CondItem {
741    /// `let pattern = mode? value`
742    Let {
743        /// The pattern.
744        pattern: Pat,
745        /// The mode marker of the value.
746        mode: Mode,
747        /// The matched value.
748        value: Expr,
749    },
750    /// A `Bool` expression.
751    Bool(Expr),
752}
753
754impl CondItem {
755    /// From the start of the pattern, or of the expression, to the end of the item.
756    pub fn span(&self) -> Span {
757        match self {
758            CondItem::Let { pattern, value, .. } => pattern.span.to(value.span),
759            CondItem::Bool(e) => e.span,
760        }
761    }
762}
763
764/// An expression.
765#[derive(Clone, Debug, PartialEq)]
766pub struct Expr {
767    /// Node id.
768    pub id: NodeId,
769    /// What it is.
770    pub kind: ExprKind,
771    /// Where it is.
772    pub span: Span,
773}
774
775/// The forms of expressions.
776#[derive(Clone, Debug, PartialEq)]
777pub enum ExprKind {
778    /// An integer literal.
779    Int(u64),
780    /// A float literal.
781    Float(f64),
782    /// A string literal.
783    Str(String),
784    /// An interpolated string `f"..."` (0.2).
785    FStr(Vec<FStrPart>),
786    /// `true` or `false`.
787    Bool(bool),
788    /// `()`
789    Unit,
790    /// A name.
791    Name(Ident),
792    /// `self`
793    SelfValue,
794    /// `Self`
795    SelfType,
796    /// `(e)`
797    Paren(Box<Expr>),
798    /// `[a, b]`
799    List(Vec<Expr>),
800    /// `["a": 1]`, `[:]`
801    Map(Vec<(Expr, Expr)>),
802    /// `Path.<T> { field: value, shorthand, ..base }`
803    StructLit {
804        /// The type name.
805        path: Path,
806        /// Explicit type arguments `.<T>`.
807        type_args: Vec<Ty>,
808        /// The fields.
809        fields: Vec<FieldInit>,
810        /// The base of the update syntax `..base` (0.2).
811        base: Option<Box<Expr>>,
812    },
813    /// `base.name`
814    Field {
815        /// The left side.
816        base: Box<Expr>,
817        /// The name after the dot.
818        name: Ident,
819    },
820    /// `base.<T, U>`
821    TypeArgs {
822        /// The left side.
823        base: Box<Expr>,
824        /// The type arguments.
825        args: Vec<Ty>,
826    },
827    /// `callee(args)`
828    Call {
829        /// What is called.
830        callee: Box<Expr>,
831        /// The arguments.
832        args: Vec<Arg>,
833    },
834    /// `base[index]`
835    Index {
836        /// The collection.
837        base: Box<Expr>,
838        /// The index.
839        index: Box<Expr>,
840    },
841    /// `base[a..b]` and the other slice forms.
842    Slice {
843        /// The collection.
844        base: Box<Expr>,
845        /// The start, if written.
846        start: Option<Box<Expr>>,
847        /// The end, if written.
848        end: Option<Box<Expr>>,
849        /// `..=`
850        inclusive: bool,
851    },
852    /// `e?`
853    Try(Box<Expr>),
854    /// `-e`, `!e`, `~e`
855    Unary {
856        /// The operator.
857        op: UnaryOp,
858        /// The operand.
859        operand: Box<Expr>,
860    },
861    /// `a op b`
862    Binary {
863        /// The operator.
864        op: BinaryOp,
865        /// Left operand.
866        lhs: Box<Expr>,
867        /// Right operand.
868        rhs: Box<Expr>,
869    },
870    /// `|x, y: Int| body` or `|x| -> T { body }`.
871    Closure {
872        /// The parameters.
873        params: Vec<ClosureParam>,
874        /// The written result type.
875        ret: Option<Ty>,
876        /// The body.
877        body: Box<Expr>,
878    },
879    /// `{ ... }` as the body of a closure or a match arm.
880    Block(Block),
881    /// `if cond { } else ...`
882    If {
883        /// The condition.
884        cond: Box<Expr>,
885        /// The first branch.
886        then: Block,
887        /// `else` followed by a block or another `if`.
888        otherwise: Option<Box<Expr>>,
889    },
890    /// `if let pattern = mode? value { } else ...` (0.2), or a chain of conditions with a `let`
891    /// among them (spec chapter 3, section 5, rule 14a).
892    IfLet {
893        /// The items of the condition; at least one is a `let`.
894        items: Vec<CondItem>,
895        /// The branch taken when every item succeeds.
896        then: Block,
897        /// `else` followed by a block or another `if`.
898        otherwise: Option<Box<Expr>>,
899    },
900    /// `label: loop { body }` (0.2).
901    Loop {
902        /// The label of the loop.
903        label: Option<Ident>,
904        /// The body.
905        body: Block,
906    },
907    /// `match mode? scrutinee { arms }`
908    Match {
909        /// The mode marker.
910        mode: Mode,
911        /// The matched value.
912        scrutinee: Box<Expr>,
913        /// The arms.
914        arms: Vec<Arm>,
915    },
916    /// `return e?`
917    Return(Option<Box<Expr>>),
918    /// `break`, `break label`, `break value`. The parser takes a name after `break` as a label
919    /// when an enclosing loop has that label.
920    Break {
921        /// The label of the loop that is left.
922        label: Option<Ident>,
923        /// The value of the `loop` that is left.
924        value: Option<Box<Expr>>,
925    },
926    /// `continue`, `continue label`.
927    Continue {
928        /// The label of the loop that is continued.
929        label: Option<Ident>,
930    },
931    /// Something that could not be parsed; a diagnostic was reported.
932    Error,
933}
934
935/// A part of an interpolated string.
936#[derive(Clone, Debug, PartialEq)]
937pub enum FStrPart {
938    /// Text.
939    Text(String),
940    /// An interpolated expression, with its format specification.
941    Expr(Expr, Option<FormatSpec>),
942}
943
944/// How an interpolation is aligned in its width.
945#[derive(Clone, Copy, Debug, PartialEq, Eq)]
946pub enum Align {
947    /// `<`
948    Left,
949    /// `^`
950    Center,
951    /// `>`
952    Right,
953}
954
955/// A format specification `[[fill] align] ["0"] [width] ["." precision]` after the `:` of an
956/// interpolation (spec chapter 1, section 5.3a; chapter 7, section 4.4).
957#[derive(Clone, Debug, PartialEq, Eq)]
958pub struct FormatSpec {
959    /// The fill character, if one is written.
960    pub fill: Option<char>,
961    /// The alignment, if one is written.
962    pub align: Option<Align>,
963    /// `0`: pad a number with zeros after its sign.
964    pub zero: bool,
965    /// The width.
966    pub width: Option<u32>,
967    /// The number of digits after the point of a `Float`.
968    pub precision: Option<u32>,
969    /// Where the specification is, after the `:`.
970    pub span: Span,
971}
972
973impl FormatSpec {
974    /// The specification as it is written, such as `*>8.2`.
975    pub fn text(&self) -> String {
976        let mut out = String::new();
977        if let Some(f) = self.fill {
978            out.push(f);
979        }
980        match self.align {
981            Some(Align::Left) => out.push('<'),
982            Some(Align::Center) => out.push('^'),
983            Some(Align::Right) => out.push('>'),
984            None => {}
985        }
986        if self.zero {
987            out.push('0');
988        }
989        if let Some(w) = self.width {
990            out.push_str(&w.to_string());
991        }
992        if let Some(p) = self.precision {
993            out.push_str(&format!(".{p}"));
994        }
995        out
996    }
997}
998
999/// A field in a struct literal.
1000#[derive(Clone, Debug, PartialEq)]
1001pub struct FieldInit {
1002    /// Node id, for what a shorthand field names.
1003    pub id: NodeId,
1004    /// The field name.
1005    pub name: Ident,
1006    /// The value; `None` for the shorthand `User { id }`.
1007    pub value: Option<Expr>,
1008}
1009
1010/// An argument of a call.
1011#[derive(Clone, Debug, PartialEq)]
1012pub struct Arg {
1013    /// `mut`, `own` or none.
1014    pub mode: Mode,
1015    /// The value.
1016    pub value: Expr,
1017}
1018
1019/// A closure parameter.
1020#[derive(Clone, Debug, PartialEq)]
1021pub struct ClosureParam {
1022    /// The name.
1023    pub name: Ident,
1024    /// The written type.
1025    pub ty: Option<Ty>,
1026}
1027
1028/// An arm of a `match`.
1029#[derive(Clone, Debug, PartialEq)]
1030pub struct Arm {
1031    /// The pattern.
1032    pub pattern: Pat,
1033    /// `if` guard.
1034    pub guard: Option<Expr>,
1035    /// The result.
1036    pub body: Expr,
1037    /// The whole arm.
1038    pub span: Span,
1039}
1040
1041/// Unary operators.
1042#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1043pub enum UnaryOp {
1044    /// `-`
1045    Neg,
1046    /// `!`
1047    Not,
1048    /// `~`
1049    BitNot,
1050}
1051
1052/// Binary operators.
1053#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1054#[allow(missing_docs)]
1055pub enum BinaryOp {
1056    Mul,
1057    Div,
1058    Rem,
1059    Add,
1060    Sub,
1061    Shl,
1062    Shr,
1063    BitAnd,
1064    BitXor,
1065    BitOr,
1066    Eq,
1067    NotEq,
1068    Lt,
1069    Le,
1070    Gt,
1071    Ge,
1072    And,
1073    Or,
1074}
1075
1076impl BinaryOp {
1077    /// The operator as written.
1078    pub fn symbol(self) -> &'static str {
1079        match self {
1080            BinaryOp::Mul => "*",
1081            BinaryOp::Div => "/",
1082            BinaryOp::Rem => "%",
1083            BinaryOp::Add => "+",
1084            BinaryOp::Sub => "-",
1085            BinaryOp::Shl => "<<",
1086            BinaryOp::Shr => ">>",
1087            BinaryOp::BitAnd => "&",
1088            BinaryOp::BitXor => "^",
1089            BinaryOp::BitOr => "|",
1090            BinaryOp::Eq => "==",
1091            BinaryOp::NotEq => "!=",
1092            BinaryOp::Lt => "<",
1093            BinaryOp::Le => "<=",
1094            BinaryOp::Gt => ">",
1095            BinaryOp::Ge => ">=",
1096            BinaryOp::And => "&&",
1097            BinaryOp::Or => "||",
1098        }
1099    }
1100
1101    /// Whether this is one of the non-associative comparison operators.
1102    pub fn is_comparison(self) -> bool {
1103        matches!(
1104            self,
1105            BinaryOp::Eq
1106                | BinaryOp::NotEq
1107                | BinaryOp::Lt
1108                | BinaryOp::Le
1109                | BinaryOp::Gt
1110                | BinaryOp::Ge
1111        )
1112    }
1113}
1114
1115/// A pattern in a `match` arm.
1116#[derive(Clone, Debug, PartialEq)]
1117pub struct Pat {
1118    /// Node id.
1119    pub id: NodeId,
1120    /// What it is.
1121    pub kind: PatKind,
1122    /// Where it is.
1123    pub span: Span,
1124}
1125
1126/// The forms of patterns (spec chapter 3, section 7).
1127#[derive(Clone, Debug, PartialEq)]
1128pub enum PatKind {
1129    /// `_`
1130    Wild,
1131    /// A lone name: a binding, or a payload-less variant or constant (decided later).
1132    Name(Ident),
1133    /// An integer, possibly negative.
1134    Int {
1135        /// `-`
1136        negative: bool,
1137        /// The magnitude.
1138        value: u64,
1139    },
1140    /// A string.
1141    Str(String),
1142    /// `true` or `false`.
1143    Bool(bool),
1144    /// A dotted path without payload: `StorageError.Full`.
1145    Path(Path),
1146    /// `Some(x)`, `Shape.Circle(r)`.
1147    Tuple {
1148        /// The variant.
1149        path: Path,
1150        /// The payload patterns.
1151        items: Vec<Pat>,
1152    },
1153    /// `Point { x, y: 0, .. }`.
1154    Struct {
1155        /// The struct or variant.
1156        path: Path,
1157        /// The field patterns.
1158        fields: Vec<FieldPat>,
1159        /// `..` at the end.
1160        rest: bool,
1161    },
1162    /// `A | B`
1163    Or(Vec<Pat>),
1164    /// A pattern that could not be parsed.
1165    Error,
1166}
1167
1168/// A field in a struct pattern.
1169#[derive(Clone, Debug, PartialEq)]
1170pub struct FieldPat {
1171    /// Node id, for the binding of a shorthand field.
1172    pub id: NodeId,
1173    /// The field name.
1174    pub name: Ident,
1175    /// The sub-pattern; `None` for the shorthand `{ x }`.
1176    pub pat: Option<Pat>,
1177}