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}