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