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}