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