hax_rust_engine/ast.rs
1//! The core abstract syntax tree (AST) representation for hax.
2//!
3//! This module defines the primary data structures used to represent
4//! typed syntax.
5//!
6//! The design of this AST is designed under the following constraints:
7//! 1. Valid (cargo check) pretty-printed Rust can be produced out of it.
8//! 2. The Rust THIR AST from the frontend can be imported into this AST.
9//! 3. The AST defined in the OCaml engine can be imported into this AST.
10//! 4. This AST can be exported to the OCaml engine.
11//! 5. This AST should be suitable for AST transformations.
12
13pub mod diagnostics;
14pub mod fragment;
15pub mod identifiers;
16pub mod literals;
17pub mod resugared;
18pub mod span;
19pub mod utils;
20pub mod visitors;
21
22use crate::{ast::diagnostics::Context, symbol::Symbol};
23use diagnostics::Diagnostic;
24use fragment::Fragment;
25use hax_rust_engine_macros::*;
26pub use identifiers::*;
27use literals::*;
28use resugared::*;
29use span::Span;
30
31/// Represents a generic value used in type applications (e.g., `T` in `Vec<T>`).
32#[derive_group_for_ast]
33pub enum GenericValue {
34 /// A type-level generic value.
35 ///
36 /// # Example:
37 /// `i32` in `Vec<i32>`
38 Ty(Ty),
39 /// A const-level generic value.
40 ///
41 /// # Example:
42 /// `12` in `Foo<12>`
43 Expr(Expr),
44 /// A lifetime.
45 ///
46 /// # Example:
47 /// `'a` in `foo<'a>`
48 Lifetime,
49}
50
51/// Built-in primitive types.
52#[derive_group_for_ast]
53pub enum PrimitiveTy {
54 /// The `bool` type.
55 Bool,
56 /// An integer type (e.g., `i32`, `u8`).
57 Int(IntKind),
58 /// A float type (e.g. `f32`)
59 Float(FloatKind),
60 /// The `char` type
61 Char,
62 /// The `str` type
63 Str,
64}
65
66/// Represent a Rust lifetime region.
67#[derive_group_for_ast]
68pub struct Region;
69
70/// A indirection for the representation of types.
71#[derive_group_for_ast]
72pub struct Ty(pub(crate) Box<TyKind>);
73
74impl Ty {
75 /// The type `bool`
76 pub fn bool() -> Self {
77 Self(Box::new(TyKind::Primitive(PrimitiveTy::Bool)))
78 }
79 /// The type `int`
80 pub fn int(size: IntSize, signedness: Signedness) -> Self {
81 Self(Box::new(TyKind::Primitive(PrimitiveTy::Int(IntKind {
82 size,
83 signedness,
84 }))))
85 }
86 /// The `int` check
87 pub fn is_int(&self) -> bool {
88 let Self(b) = self;
89 matches!(
90 &**b,
91 TyKind::Primitive(PrimitiveTy::Int(IntKind {
92 size: _,
93 signedness: _,
94 }))
95 )
96 }
97 /// The (hax) type `Prop`
98 pub fn prop() -> Self {
99 Self(Box::new(TyKind::App {
100 head: crate::names::hax_lib::prop::Prop,
101 args: vec![],
102 }))
103 }
104}
105
106/// Describes any Rust type (e.g., `i32`, `Vec<T>`, `fn(i32) -> bool`).
107#[derive_group_for_ast]
108pub enum TyKind {
109 /// A primitive type.
110 ///
111 /// # Example:
112 /// `i32`, `bool`
113 Primitive(PrimitiveTy),
114
115 /// A type application (generic type).
116 ///
117 /// # Example:
118 /// `Vec<i32>`
119 App {
120 /// The type being applied (`Vec` in the example).
121 head: GlobalId,
122 /// The arguments (`[i32]` in the example).
123 args: Vec<GenericValue>,
124 },
125
126 /// A function or closure type.
127 ///
128 /// # Example:
129 /// `fn(i32) -> bool` or `Fn(i32) -> bool`
130 Arrow {
131 /// `i32` in the example
132 inputs: Vec<Ty>,
133 /// `bool` in the example
134 output: Ty,
135 },
136
137 // TODO: Should we keep this type?
138 /// A reference type.
139 ///
140 /// # Example:
141 /// `&i32`, `&mut i32`
142 Ref {
143 /// The type inside the reference
144 inner: Ty,
145 /// Is the reference mutable?
146 mutable: bool,
147 /// The region of this reference
148 region: Region,
149 },
150
151 /// A parameter type
152 Param(LocalId),
153
154 // TODO: Should we keep this type?
155 /// A slice type.
156 ///
157 /// # Example:
158 /// `&[i32]`
159 Slice(Ty),
160
161 /// An array type.
162 ///
163 /// # Example:
164 /// `&[i32; 10]`
165 Array {
166 /// The type of the items of the array
167 ty: Ty,
168 /// The length of the array
169 length: Box<Expr>,
170 },
171
172 /// A raw pointer type
173 RawPointer,
174
175 /// An associated type
176 ///
177 /// # Example:
178 /// ```rust,ignore
179 /// fn f<T: Tr>() -> T::A {...}
180 /// ```
181 AssociatedType {
182 /// Impl expr for `Tr<T>` in the example
183 impl_: ImplExpr,
184 /// `Tr::A` in the example
185 item: GlobalId,
186 },
187
188 /// An opaque type
189 ///
190 /// # Example:
191 /// ```rust,ignore
192 /// type Foo = impl Bar;
193 /// ```
194 Opaque(GlobalId),
195
196 /// A `dyn` type
197 ///
198 /// # Example:
199 /// ```rust,ignore
200 /// dyn Tr
201 /// ```
202 Dyn(Vec<DynTraitGoal>),
203
204 /// A resugared type.
205 /// This variant is introduced before printing only.
206 /// Phases must not produce this variant.
207 Resugared(ResugaredTyKind),
208
209 /// Fallback constructor to carry errors.
210 Error(ErrorNode),
211}
212
213#[derive_group_for_ast]
214/// Represent a node of the AST where an error occurred.
215pub struct ErrorNode {
216 /// The node from the AST at the time something failed
217 pub fragment: Box<Fragment>,
218 /// The error(s) encountered.
219 pub diagnostics: Vec<Diagnostic>,
220}
221
222impl ErrorNode {
223 /// Creates an assertion failure out of an AST fragment and a message.
224 pub fn assertion_failure(
225 fragment: impl Into<Fragment> + HasMetadata,
226 context: Context,
227 message: impl Into<String>,
228 ) -> Self {
229 let span = fragment.span();
230 let fragment = fragment.into();
231 ErrorNode {
232 diagnostics: vec![Diagnostic::new(
233 fragment.clone(),
234 diagnostics::DiagnosticInfo {
235 context,
236 span,
237 kind: hax_types::diagnostics::Kind::AssertionFailure {
238 details: message.into(),
239 },
240 },
241 )],
242 fragment: Box::new(fragment),
243 }
244 }
245}
246
247/// A `dyn` trait. The generic arguments are known but the actual type
248/// implementing the trait is known dynamically.
249///
250/// # Example:
251/// ```rust,ignore
252/// dyn Tr<A, B>
253/// ```
254#[derive_group_for_ast]
255pub struct DynTraitGoal {
256 /// `Tr` in the example above
257 pub trait_: GlobalId,
258 /// `A, B` in the example above
259 pub non_self_args: Vec<GenericValue>,
260}
261
262/// Extra information attached to syntax nodes.
263#[derive_group_for_ast]
264pub struct Metadata {
265 /// The location in the source code.
266 pub span: Span,
267 /// Rust attributes.
268 pub attributes: Attributes,
269 // TODO: add phase/desugar informations
270}
271
272/// A typed expression with metadata.
273#[derive_group_for_ast]
274pub struct Expr {
275 /// The kind of expression.
276 pub kind: Box<ExprKind>,
277 /// The type of this expression.
278 pub ty: Ty,
279 /// Source span and attributes.
280 pub meta: Metadata,
281}
282
283/// A typed pattern with metadata.
284#[derive_group_for_ast]
285pub struct Pat {
286 /// The kind of pattern.
287 pub kind: Box<PatKind>,
288 /// The type of this pattern.
289 pub ty: Ty,
290 /// Source span and attributes.
291 pub meta: Metadata,
292}
293
294/// A pattern matching arm with metadata.
295#[derive_group_for_ast]
296pub struct Arm {
297 /// The pattern of the arm.
298 pub pat: Pat,
299 /// The body of the arm.
300 pub body: Expr,
301 /// The optional guard of the arm.
302 pub guard: Option<Guard>,
303 /// Source span and attributes.
304 pub meta: Metadata,
305}
306
307/// A pattern matching arm guard with metadata.
308#[derive_group_for_ast]
309pub struct Guard {
310 /// The kind of guard.
311 pub kind: GuardKind,
312 /// Source span and attributes.
313 pub meta: Metadata,
314}
315
316/// Represents different levels of borrowing.
317#[derive_group_for_ast]
318pub enum BorrowKind {
319 /// Shared reference
320 ///
321 /// # Example:
322 /// `&x`
323 Shared,
324 /// Unique reference: this is internal to rustc
325 Unique,
326 /// Mutable reference
327 ///
328 /// # Example:
329 /// `&mut x`
330 Mut,
331}
332
333/// Binding modes used in patterns.
334#[derive_group_for_ast]
335pub enum BindingMode {
336 /// Binding by value
337 ///
338 /// # Example:
339 /// `x`
340 ByValue,
341 /// Binding by reference
342 ///
343 /// # Example:
344 /// `ref x`, `ref mut x`
345 ByRef(BorrowKind),
346}
347
348/// Represents the various kinds of patterns.
349#[derive_group_for_ast]
350pub enum PatKind {
351 /// Wildcard pattern
352 ///
353 /// # Example:
354 /// `_`
355 Wild,
356
357 /// An ascription pattern
358 ///
359 /// # Example:
360 /// `p : ty`
361 Ascription {
362 /// The inner pattern (`p` in the example)
363 pat: Pat,
364 /// The (spanned) type ascription (`ty` in the example)
365 ty: SpannedTy,
366 },
367
368 /// An or pattern
369 ///
370 /// # Example:
371 /// `p | q`
372 /// Always contains at least 2 sub-patterns
373 Or {
374 /// A vector of sub-patterns
375 sub_pats: Vec<Pat>,
376 },
377
378 /// An array pattern
379 ///
380 /// # Example:
381 /// `[p, q]`
382 Array {
383 /// A vector of patterns
384 args: Vec<Pat>,
385 },
386
387 /// A dereference pattern
388 ///
389 /// # Example:
390 /// `&p`
391 Deref {
392 /// The inner pattern
393 sub_pat: Pat,
394 },
395
396 /// A constant pattern
397 ///
398 /// # Example:
399 /// `1`
400 Constant {
401 /// The literal
402 lit: Literal,
403 },
404
405 /// A variable binding.
406 ///
407 /// # Examples:
408 /// - `x` → `mutable: false`
409 /// - `mut x` → `mutable: true`
410 /// - `ref x` → `mode: ByRef(Shared)`
411 Binding {
412 /// Is the binding mutable? E.g. `x` is not mutable, `mut x` is.
413 mutable: bool,
414 /// The variable introduced by the binding pattern.
415 var: LocalId,
416 /// The binding mode, e.g. [`BindingMode::Shared`] for `ref x`.
417 mode: BindingMode,
418 /// The sub-pattern, if any.
419 /// For example, this is `Some(inner_pat)` for the pattern `variable @ inner_pat`.
420 sub_pat: Option<Pat>,
421 },
422
423 /// A constructor pattern
424 ///
425 /// # Example:
426 /// ```rust,ignore
427 /// Foo(x)
428 /// ```
429 Construct {
430 /// The identifier of the constructor we are matching
431 constructor: GlobalId,
432 /// Are we constructing a record? E.g. a struct or a variant with named fields.
433 is_record: bool,
434 /// Is this a struct? (meaning, *not* a variant from an enum)
435 is_struct: bool,
436 /// A list of fields.
437 fields: Vec<(GlobalId, Pat)>,
438 },
439
440 /// A resugared pattern.
441 /// This variant is introduced before printing only.
442 /// Phases must not produce this variant.
443 Resugared(ResugaredPatKind),
444
445 /// Fallback constructor to carry errors.
446 Error(ErrorNode),
447}
448
449/// Represents the various kinds of pattern guards.
450#[derive_group_for_ast]
451pub enum GuardKind {
452 /// An `if let` guard.
453 ///
454 /// # Example:
455 /// ```rust,ignore
456 /// match x {
457 /// Some(value) if let Some(x) = f(value) => x,
458 /// _ => ...,
459 /// }
460 /// ```
461 IfLet {
462 /// The left-hand side of the guard. `Some(x)` in the example.
463 lhs: Pat,
464 /// The right-hand side of the guard. `f(value)` in the example.
465 rhs: Expr,
466 },
467}
468
469// TODO: Replace by places, or just expressions
470/// The left-hand side of an assignment.
471#[derive_group_for_ast]
472#[allow(missing_docs)]
473pub enum Lhs {
474 LocalVar {
475 var: LocalId,
476 ty: Ty,
477 },
478 VecRef {
479 e: Box<Lhs>,
480 ty: Ty,
481 },
482 ArbitraryExpr(Box<Expr>),
483 FieldAccessor {
484 e: Box<Lhs>,
485 ty: Ty,
486 field: GlobalId,
487 },
488 ArrayAccessor {
489 e: Box<Lhs>,
490 ty: Ty,
491 index: Expr,
492 },
493}
494
495/// An `ImplExpr` describes the full data of a trait implementation. Because of
496/// generics, this may need to combine several concrete trait implementation
497/// items. For example, `((1u8, 2u8), "hello").clone()` combines the generic
498/// implementation of `Clone` for `(A, B)` with the concrete implementations for
499/// `u8` and `&str`, represented as a tree.
500#[derive_group_for_ast]
501pub struct ImplExpr {
502 /// The impl. expression itself.
503 pub kind: Box<ImplExprKind>,
504 /// The trait being implemented.
505 pub goal: TraitGoal,
506}
507
508/// Represents all the kinds of impl expr.
509///
510/// # Example:
511/// In the snippet below, the `clone` method on `x` corresponds to the implementation
512/// of `Clone` derived for `Vec<T>` (`ImplApp`) given the `LocalBound` on `T`.
513/// ```rust,ignore
514/// fn f<T: Clone>(x: Vec<T>) -> Vec<T> {
515/// x.clone()
516/// }
517/// ```
518#[derive_group_for_ast]
519pub enum ImplExprKind {
520 /// The trait implementation being defined.
521 ///
522 /// # Example:
523 /// The impl expr for `Type: Trait` used in `self.f()` is `Self_`.
524 /// ```rust,ignore
525 /// impl Trait for Type {
526 /// fn f(&self) {...}
527 /// fn g(&self) {self.f()}
528 /// }
529 /// ```
530 Self_,
531 /// A concrete `impl` block.
532 ///
533 /// # Example
534 /// ```rust,ignore
535 /// impl Clone for Type { // Consider this `impl` is called `impl0`
536 /// ...
537 /// }
538 /// fn f(x: Type) {
539 /// x.clone() // Here `clone` comes from `Concrete(impl0)`
540 /// }
541 /// ```
542 Concrete(TraitGoal),
543 /// A bound introduced by a generic clause.
544 ///
545 /// # Example:
546 /// ```rust,ignore
547 /// fn f<T: Clone>(x: T) -> T {
548 /// x.clone() // Here the method comes from the bound `T: Clone`
549 /// }
550 /// ```
551 LocalBound {
552 /// Local identifier to a bound.
553 id: Symbol,
554 },
555 /// A parent implementation.
556 ///
557 /// # Example:
558 /// ```rust,ignore
559 /// trait SubTrait: Clone {}
560 /// fn f<T: SubTrait>(x: T) -> T {
561 /// x.clone() // Here the method comes from the parent of the bound `T: SubTrait`
562 /// }
563 /// ```
564 Parent {
565 /// Parent implementation
566 impl_: ImplExpr,
567 /// Which implementation to pick in the parent
568 ident: ImplIdent,
569 },
570 /// A projected associated implementation.
571 ///
572 /// # Example:
573 /// In this snippet, `T::Item` is an `AssociatedType` where the subsequent `ImplExpr`
574 /// is a type projection of `ITerator`.
575 /// ```rust,ignore
576 /// fn f<T: Iterator>(x: T) -> Option<T::Item> {
577 /// x.next()
578 /// }
579 /// ```
580 Projection {
581 /// The base implementation from which we project
582 impl_: ImplExpr,
583 /// The item in the trait implemented by `impl_`
584 item: GlobalId,
585 /// Which implementation to pick on the item
586 ident: ImplIdent,
587 },
588 /// An instantiation of a generic implementation.
589 ///
590 /// # Example:
591 /// ```rust,ignore
592 /// fn f<T: Clone>(x: Vec<T>) -> Vec<T> {
593 /// x.clone() // The `Clone` implementation for `Vec` is instantiated with the local bound `T: Clone`
594 /// }
595 /// ```
596 ImplApp {
597 /// The head of the application
598 impl_: ImplExpr,
599 /// The arguments of the application
600 args: Vec<ImplExpr>,
601 },
602 /// The implementation provided by a dyn.
603 Dyn,
604 /// A trait implemented natively by rust.
605 Builtin(TraitGoal),
606 /// Fallback constructor to carry errors.
607 Error(ErrorNode),
608}
609
610/// Represents an impl item (associated type or function)
611///
612/// # Example:
613/// ```rust,ignore
614/// impl ... {
615/// fn assoc_fn<T>(...) {...}
616/// }
617/// ```
618#[derive_group_for_ast]
619pub struct ImplItem {
620 /// Metadata (span and attributes) for the impl item.
621 pub meta: Metadata,
622 /// Generics for this associated item. `T` in the example.
623 pub generics: Generics,
624 /// The associated item itself.
625 pub kind: ImplItemKind,
626 /// The unique identifier for this associated item.
627 pub ident: GlobalId,
628}
629
630/// Represents the kinds of impl items
631#[derive_group_for_ast]
632pub enum ImplItemKind {
633 /// An instantiation of associated type
634 ///
635 /// # Example:
636 /// The associated type `Error` in the following example.
637 /// ```rust,ignore
638 /// impl TryInto for ... {
639 /// type Error = u8;
640 /// }
641 /// ```
642 Type {
643 /// The type expression, `u8` in the example.
644 ty: Ty,
645 /// The parent bounds. In the example, there are none (in the definition
646 /// of `TryInto`, there is no `Error: Something` in the associated type
647 /// definition).
648 parent_bounds: Vec<(ImplExpr, ImplIdent)>,
649 },
650 /// A definition for a trait function
651 ///
652 /// # Example:
653 /// The associated function `into` in the following example.
654 /// ```rust,ignore
655 /// impl Into for T {
656 /// fn into(&self) -> T {...}
657 /// }
658 /// ```
659 Fn {
660 /// The body of the associated function (`...` in the example)
661 body: Expr,
662 /// The list of the argument for the associated function (`&self` in the example).
663 params: Vec<Param>,
664 },
665
666 /// A resugared impl item.
667 /// This variant is introduced before printing only.
668 /// Phases must not produce this variant.
669 Resugared(ResugaredImplItemKind),
670
671 /// Fallback constructor to carry errors.
672 Error(ErrorNode),
673}
674
675/// Represents a trait item (associated type, fn, or default)
676#[derive_group_for_ast]
677pub struct TraitItem {
678 /// Source span and attributes.
679 pub meta: Metadata,
680 /// The kind of trait item we are dealing with (an associated type or function).
681 pub kind: TraitItemKind,
682 /// The generics this associated item carries.
683 ///
684 /// # Example:
685 /// The generics `<B>` on `f`, **not** `<A>`.
686 /// ```rust,ignore
687 /// trait<A> ... {
688 /// fn f<B>(){}
689 /// }
690 /// ```
691 pub generics: Generics,
692 /// The identifier of the associateed item.
693 pub ident: GlobalId,
694}
695
696/// Represents the kinds of trait items
697#[derive_group_for_ast]
698pub enum TraitItemKind {
699 /// An associated type
700 Type(Vec<ImplIdent>),
701 /// An associated function
702 Fn(Ty),
703 /// An associated function with a default body.
704 /// A arrow type (like what is given in `TraitItemKind::Ty`) can be
705 /// reconstructed using the types of the parameters and of the body.
706 ///
707 /// # Example:
708 /// ```rust,ignore
709 /// impl ... {
710 /// fn f(x: u8) -> u8 { x + 2 }
711 /// }
712 /// ```
713 Default {
714 /// The parameters of the associated function (`[x: u8]` in the example).
715 params: Vec<Param>,
716 /// The default body of the associated function (`x + 2` in the example).
717 body: Expr,
718 },
719
720 /// A resugared trait item.
721 /// This variant is introduced before printing only.
722 /// Phases must not produce this variant.
723 Resugared(ResugaredTraitItemKind),
724
725 /// Fallback constructor to carry errors.
726 Error(ErrorNode),
727}
728
729/// A QuoteContent is a component of a quote: it can be a verbatim string, a Rust expression to embed in the quote, a pattern etc.
730///
731/// # Example:
732/// ```rust,ignore
733/// fstar!("f ${x + 3} + 10")
734/// ```
735/// results in `[Verbatim("f"), Expr([[x + 3]]), Verbatim(" + 10")]`
736#[derive_group_for_ast]
737pub enum QuoteContent {
738 /// A verbatim chunk of backend code.
739 Verbatim(String),
740 /// A Rust expression to inject in the quote.
741 Expr(Expr),
742 /// A Rust pattern to inject in the quote.
743 Pattern(Pat),
744 /// A Rust type to inject in the quote.
745 Ty(Ty),
746}
747
748/// Represents an inlined piece of backend code
749#[derive_group_for_ast]
750pub struct Quote(pub Vec<QuoteContent>);
751
752/// The origin of a quote item.
753#[derive_group_for_ast]
754pub struct ItemQuoteOrigin {
755 /// From which kind of item this quote was placed on?
756 pub item_kind: ItemQuoteOriginKind,
757 /// From what item this quote was placed on?
758 pub item_ident: GlobalId,
759 /// What was the position of the quote?
760 pub position: ItemQuoteOriginPosition,
761}
762
763/// The kind of a quote item's origin
764#[derive_group_for_ast]
765pub enum ItemQuoteOriginKind {
766 /// A function
767 Fn,
768 /// A type alias
769 TyAlias,
770 /// A type definition (`enum`, `union`, `struct`)
771 Type,
772 /// A macro invocation
773 /// TODO: drop
774 MacroInvocation,
775 /// A trait definition
776 Trait,
777 /// An `impl` block
778 Impl,
779 /// An alias
780 Alias,
781 /// A `use`
782 Use,
783 /// A quote
784 Quote,
785 /// An error
786 HaxError,
787 /// Something unknown
788 NotImplementedYet,
789}
790
791/// The position of a quote item relative to its origin
792#[derive_group_for_ast]
793pub enum ItemQuoteOriginPosition {
794 /// The quote was placed before an item
795 Before,
796 /// The quote was placed after an item
797 After,
798 /// The quote replaces an item
799 Replace,
800}
801
802/// The kind of a loop (resugared by respective `Reconstruct...Loops` phases).
803/// Useful for `FunctionalizeLoops`.
804#[derive_group_for_ast]
805pub enum LoopKind {
806 /// An unconditional loop.
807 ///
808 /// # Example:
809 /// `loop { ... }`
810 UnconditionalLoop,
811 /// A while loop.
812 ///
813 /// # Example:
814 /// ```rust,ignore
815 /// while(condition) { ... }
816 /// ```
817 WhileLoop {
818 /// The boolean condition
819 condition: Expr,
820 },
821 /// A for loop.
822 ///
823 /// # Example:
824 /// ```rust,ignore
825 /// for i in iterator { ... }
826 /// ```
827 ForLoop {
828 /// The pattern of the for loop (`i` in the example).
829 pat: Pat,
830 /// The iterator we're looping on (`iterator` in the example).
831 iterator: Expr,
832 },
833 /// A specialized for loop on a range.
834 ///
835 /// # Example:
836 /// ```rust,ignore
837 /// for i in start..end {
838 /// ...
839 /// }
840 /// ```
841 ForIndexLoop {
842 /// Where the range begins (`start` in the example).
843 start: Expr,
844 /// Where the range ends (`end` in the example).
845 end: Expr,
846 /// The binding used for the iteration.
847 var: LocalId,
848 /// The type of the binding `var`.
849 var_ty: Ty,
850 },
851}
852
853/// This is a marker to describe what control flow is present in a loop.
854/// It is added by phase `DropReturnBreakContinue` and the information is used in
855/// `FunctionalizeLoops`. We need it to replace the control flow nodes of the AST
856/// by an encoding in the `ControlFlow` enum.
857#[derive_group_for_ast]
858pub enum ControlFlowKind {
859 /// Contains no `return`, maybe some `break`s
860 BreakOnly,
861 /// Contains both at least one `return` and maybe some `break`s
862 BreakOrReturn,
863}
864
865/// Represent explicit mutation context for a loop.
866/// This is useful to make loops pure.
867#[derive_group_for_ast]
868pub struct LoopState {
869 /// The initial state of the loop.
870 pub init: Expr,
871 /// The pattern that destructures the state of the loop.
872 pub body_pat: Pat,
873}
874
875// TODO: Kill some nodes (e.g. `Array`)?
876/// Describes the shape of an expression.
877#[derive_group_for_ast]
878pub enum ExprKind {
879 /// If expression.
880 ///
881 /// # Example:
882 /// `if x > 0 { 1 } else { 2 }`
883 If {
884 /// The boolean condition (`x > 0` in the example).
885 condition: Expr,
886 /// The then branch (`1` in the example).
887 then: Expr,
888 /// An optional else branch (`Some(2)`in the example).
889 else_: Option<Expr>,
890 },
891
892 /// Function application.
893 ///
894 /// # Example:
895 /// `f(x, y)`
896 App {
897 /// The head of the function application (or, which function do we apply?).
898 head: Expr,
899 /// The arguments applied to the function.
900 args: Vec<Expr>,
901 /// The generic arguments applied to the function.
902 generic_args: Vec<GenericValue>,
903 /// If the function requires generic bounds to be called, `bounds_impls`
904 /// is a vector of impl. expressions for those bounds.
905 bounds_impls: Vec<ImplExpr>,
906 /// If we apply an associated function, contains the impl. expr used.
907 trait_: Option<(ImplExpr, Vec<GenericValue>)>,
908 },
909
910 /// A literal value.
911 ///
912 /// # Example:
913 /// `42`, `"hello"`
914 Literal(Literal),
915
916 /// An array literal.
917 ///
918 /// # Example:
919 /// `[1, 2, 3]`
920 Array(Vec<Expr>),
921
922 /// A constructor application
923 ///
924 /// # Example:
925 /// ```rust,ignore
926 /// MyEnum::MyVariant { x : 1, ...base }
927 /// ``````
928 Construct {
929 /// The identifier of the constructor we are building (`MyEnum::MyVariant` in the example).
930 constructor: GlobalId,
931 /// Are we constructing a record? E.g. a struct or a variant with named fields. (`true` in the example)
932 is_record: bool,
933 /// Is this a struct? Neaning, *not* a variant from an enum. (`false` in the example)
934 is_struct: bool,
935 /// A list of fields (`[(x, 1)]` in the example).
936 fields: Vec<(GlobalId, Expr)>,
937 /// The base expression, if any. (`Some(base)` in the example)
938 base: Option<Expr>,
939 },
940
941 /// A `match`` expression.
942 ///
943 /// # Example:
944 /// ```rust,ignore
945 /// match x {
946 /// pat1 => expr1,
947 /// pat2 => expr2,
948 /// }
949 /// ```
950 Match {
951 /// The expression on which we are matching. (`x` in the example)
952 scrutinee: Expr,
953 /// The arms of the match. (`pat1 => expr1` and `pat2 => expr2` in the example)
954 arms: Vec<Arm>,
955 },
956
957 /// A reference expression.
958 ///
959 /// # Examples:
960 /// - `&x` → `mutable: false`
961 /// - `&mut x` → `mutable: true`
962 Borrow {
963 /// Is the borrow mutable?
964 mutable: bool,
965 /// The expression we are borrowing
966 inner: Expr,
967 },
968
969 /// Raw borrow
970 ///
971 /// # Example:
972 /// `*const u8`
973 AddressOf {
974 /// Is the raw pointer mutable?
975 mutable: bool,
976 /// The expression on which we take a pointer
977 inner: Expr,
978 },
979
980 /// A `let` expression used in expressions.
981 ///
982 /// # Example:
983 /// `let x = 1; x + 1`
984 Let {
985 /// The left-hand side of the `let` expression. (`x` in the example)
986 lhs: Pat,
987 /// The right-hand side of the `let` expression. (`1` in the example)
988 rhs: Expr,
989 /// The body of the `let`. (`x + 1` in the example)
990 body: Expr,
991 },
992
993 /// A global identifier.
994 ///
995 /// # Example:
996 /// `std::mem::drop`
997 GlobalId(GlobalId),
998
999 /// A local variable.
1000 ///
1001 /// # Example:
1002 /// `x`
1003 LocalId(LocalId),
1004
1005 /// Type ascription
1006 Ascription {
1007 /// The expression being ascribed.
1008 e: Expr,
1009 /// The type
1010 ty: Ty,
1011 },
1012
1013 /// Variable mutation
1014 ///
1015 /// # Example:
1016 /// `x = 1`
1017 Assign {
1018 /// the left-hand side (place) of the assign
1019 lhs: Lhs,
1020 /// The value we are assigning
1021 value: Expr,
1022 },
1023
1024 /// Loop
1025 ///
1026 /// # Example:
1027 /// `'label: loop { body }`
1028 Loop {
1029 /// The body of the loop.
1030 body: Expr,
1031 /// The kind of loop (e.g. `while`, `loop`, `for`...).
1032 kind: Box<LoopKind>,
1033 /// An optional loop state, that makes explicit the state mutated by the
1034 /// loop.
1035 state: Option<LoopState>,
1036 /// What kind of control flow is performed by this loop?
1037 control_flow: Option<ControlFlowKind>,
1038 /// Optional loop label.
1039 label: Option<Symbol>,
1040 },
1041
1042 /// The `break` exppression, that breaks out of a loop.
1043 ///
1044 /// # Example:
1045 /// `break 'label 3`
1046 Break {
1047 /// The value we break with. By default, this is `()`.
1048 ///
1049 /// # Example:
1050 /// ```rust,ignore
1051 /// loop { break 3; } + 3
1052 /// ```
1053 value: Expr,
1054 /// What loop shall we break? By default, the parent enclosing loop.
1055 label: Option<Symbol>,
1056 /// When a loop has a state (see [`ExprKind::Loop::state`]), this field
1057 /// `state` is `Some(_)`. This carries the updated state for the loop.
1058 state: Option<Expr>,
1059 },
1060
1061 /// Return from a function.
1062 ///
1063 /// # Example:
1064 /// `return 1`
1065 Return {
1066 /// The expression we return (`1` in the example).
1067 value: Expr,
1068 },
1069
1070 /// Continue (go to next loop iteration)
1071 ///
1072 /// # Example:
1073 /// `continue 'label`
1074 Continue {
1075 /// The loop we continue.
1076 label: Option<Symbol>,
1077 /// When a loop has a state (see [`ExprKind::Loop::state`]), this field
1078 /// `state` is `Some(_)`. This carries the updated state for the loop.
1079 state: Option<Expr>,
1080 },
1081
1082 /// Closure (anonymous function)
1083 ///
1084 /// # Example:
1085 /// `|x| x`
1086 Closure {
1087 /// The parameters of the closure
1088 params: Vec<Pat>,
1089 /// The body of the closure
1090 body: Expr,
1091 /// The captured expressions
1092 captures: Vec<Expr>,
1093 },
1094
1095 /// Block of safe or unsafe expression
1096 ///
1097 /// # Example:
1098 /// `unsafe { ... }`
1099 Block {
1100 /// The body of the block.
1101 body: Expr,
1102 /// The safety of the block.
1103 safety_mode: SafetyKind,
1104 },
1105
1106 /// A quote is an inlined piece of backend code.
1107 Quote {
1108 /// The contents of the quote.
1109 contents: Quote,
1110 },
1111
1112 /// A resugared expression.
1113 /// This variant is introduced before printing only.
1114 /// Phases must not produce this variant.
1115 Resugared(ResugaredExprKind),
1116
1117 /// Fallback constructor to carry errors.
1118 Error(ErrorNode),
1119}
1120
1121/// Represents the kinds of generic parameters
1122#[derive_group_for_ast]
1123pub enum GenericParamKind {
1124 /// A generic lifetime
1125 Lifetime,
1126 /// A generic type
1127 Type,
1128 /// A generic constant
1129 Const {
1130 /// The type of the generic constant
1131 ty: Ty,
1132 },
1133}
1134
1135/// Represents an instantiated trait that needs to be implemented.
1136///
1137/// # Example:
1138/// A bound `_: std::ops::Add<u8>`
1139#[derive_group_for_ast]
1140pub struct TraitGoal {
1141 /// `std::ops::Add` in the example.
1142 pub trait_: GlobalId,
1143 /// `[u8]` in the example.
1144 pub args: Vec<GenericValue>,
1145}
1146
1147/// Represents a trait bound in a generic constraint
1148#[derive_group_for_ast]
1149pub struct ImplIdent {
1150 /// The trait goal of this impl identifier
1151 pub goal: TraitGoal,
1152 /// The name itself
1153 pub name: Symbol,
1154}
1155
1156/// A projection predicate expresses a constraint over an associated type:
1157/// ```rust,ignore
1158/// fn f<T: Foo<S = String>>(...)
1159/// ```
1160/// In this example `Foo` has an associated type `S`.
1161#[derive_group_for_ast]
1162pub struct ProjectionPredicate {
1163 /// The impl expression we project from
1164 pub impl_: ImplExpr,
1165 /// The associated type being projected
1166 pub assoc_item: GlobalId,
1167 /// The equality constraint on the associated type
1168 pub ty: Ty,
1169}
1170
1171/// A generic constraint (lifetime, type-class or equality)
1172#[derive_group_for_ast]
1173pub enum GenericConstraint {
1174 /// A lifetime
1175 Lifetime(String), // TODO: Remove `String`
1176 /// A type-class constraint (e.g. `T: Foo`)
1177 TypeClass(ImplIdent),
1178 /// An equality constraint on an associated type (e.g. `T::Assoc = u8`)
1179 Equality(ProjectionPredicate),
1180}
1181
1182/// A generic parameter (lifetime, type parameter or const parameter)
1183#[derive_group_for_ast]
1184pub struct GenericParam {
1185 /// The local identifier for the generic parameter
1186 pub ident: LocalId,
1187 /// Metadata (span and attributes) for the generic parameter.
1188 pub meta: Metadata,
1189 /// The kind of generic parameter.
1190 pub kind: GenericParamKind,
1191}
1192
1193/// Generic parameters and constraints (contained between `<>` in function declarations)
1194#[derive_group_for_ast]
1195pub struct Generics {
1196 /// A vector of generic parameters.
1197 pub params: Vec<GenericParam>,
1198 /// A vector of generic constraints.
1199 pub constraints: Vec<GenericConstraint>,
1200}
1201
1202/// Safety level of a function.
1203#[derive_group_for_ast]
1204pub enum SafetyKind {
1205 /// Safe function (default).
1206 Safe,
1207 /// Unsafe function.
1208 Unsafe,
1209}
1210
1211/// Represents a single attribute.
1212#[derive_group_for_ast]
1213pub struct Attribute {
1214 /// The kind of attribute (a comment, a tool attribute?).
1215 pub kind: AttributeKind,
1216 /// The span of the attribute.
1217 pub span: Span,
1218}
1219
1220/// Represents the kind of an attribute.
1221#[derive_group_for_ast]
1222pub enum AttributeKind {
1223 /// A tool attribute `#[path(tokens)]`
1224 Tool {
1225 /// The path to the tool
1226 path: String,
1227 /// The payload
1228 tokens: String,
1229 },
1230 /// A doc comment
1231 DocComment {
1232 /// What kind of comment? (single lines, block)
1233 kind: DocCommentKind,
1234 /// The contents of the comment
1235 body: String,
1236 },
1237 /// Hax attribute
1238 Hax(hax_lib_macros_types::AttrPayload),
1239}
1240
1241/// Represents the kind of a doc comment.
1242#[derive_group_for_ast]
1243pub enum DocCommentKind {
1244 /// Single line comment (`//...`)
1245 Line,
1246 /// Block comment (`/*...*/`)
1247 Block,
1248}
1249
1250/// A list of attributes.
1251pub type Attributes = Vec<Attribute>;
1252
1253/// A type with its associated span.
1254#[derive_group_for_ast]
1255pub struct SpannedTy {
1256 /// The span of the type
1257 pub span: Span,
1258 /// The type itself
1259 pub ty: Ty,
1260}
1261
1262/// A function or closure parameter.
1263///
1264/// # Example:
1265/// ```rust,ignore
1266/// (mut x, y): (T, u8)
1267/// ```
1268#[derive_group_for_ast]
1269pub struct Param {
1270 /// The pattern part (left-hand side) of a parameter (`(mut x, y)` in the example).
1271 pub pat: Pat,
1272 /// The type part (right-rand side) of a parameter (`(T, u8)` in the example).
1273 pub ty: Ty,
1274 /// The span of the type part (if available).
1275 pub ty_span: Option<Span>,
1276 /// Optionally, some attributes present on the parameter.
1277 pub attributes: Attributes,
1278}
1279
1280/// A variant of an enum or struct.
1281/// In our representation structs always have one variant with an argument for each field.
1282#[derive_group_for_ast]
1283pub struct Variant {
1284 /// Name of the variant
1285 pub name: GlobalId,
1286 /// Fields of this variant (named or anonymous)
1287 pub arguments: Vec<(GlobalId, Ty, Attributes)>,
1288 /// True if fields are named
1289 pub is_record: bool,
1290 // TODO Missing span
1291 /// Attributes of the variant
1292 pub attributes: Attributes,
1293}
1294
1295/// A top-level item in the module.
1296#[derive_group_for_ast]
1297pub enum ItemKind {
1298 /// A function or constant item.
1299 ///
1300 /// # Example:
1301 /// ```rust,ignore
1302 /// fn add<T: Clone>(x: i32, y: i32) -> i32 {
1303 /// x + y
1304 /// }
1305 /// ```
1306 /// Constants are represented as functions of arity zero, while functions always have a non-zero arity.
1307 Fn {
1308 /// The identifier of the function.
1309 ///
1310 /// # Example:
1311 /// `add`
1312 name: GlobalId,
1313
1314 /// The generic arguments and constraints of the function.
1315 ///
1316 /// # Example:
1317 /// the generic type `T` and the constraint `T: Clone`
1318 generics: Generics,
1319
1320 /// The body of the function
1321 ///
1322 /// # Example:
1323 /// `x + y`
1324 body: Expr,
1325
1326 /// The parameters of the function.
1327 ///
1328 /// # Example:
1329 /// `x: i32, y: i32`
1330 params: Vec<Param>,
1331
1332 /// The safety of the function.
1333 safety: SafetyKind,
1334 },
1335
1336 /// A type alias.
1337 ///
1338 /// # Example:
1339 /// ```rust,ignore
1340 /// type A = u8;
1341 /// ```
1342 TyAlias {
1343 /// Name of the alias
1344 ///
1345 /// # Example:
1346 /// `A`
1347 name: GlobalId,
1348
1349 /// Generic arguments and constraints
1350 generics: Generics,
1351
1352 /// Original type
1353 ///
1354 /// # Example:
1355 /// `u8`
1356 ty: Ty,
1357 },
1358
1359 /// A type definition (struct or enum)
1360 ///
1361 /// # Example:
1362 /// ```rust,ignore
1363 /// enum A {B, C}
1364 /// struct S {f: u8}
1365 /// ```
1366 Type {
1367 /// Name of this type
1368 ///
1369 /// # Example:
1370 /// `A`, `S`
1371 name: GlobalId,
1372
1373 /// Generic parameters and constraints
1374 generics: Generics,
1375
1376 /// Variants
1377 ///
1378 /// # Example:
1379 /// `{B, C}`
1380 variants: Vec<Variant>,
1381
1382 /// Is this a struct (or an enum)
1383 is_struct: bool,
1384 },
1385
1386 /// A trait definition.
1387 ///
1388 /// # Example:
1389 /// ```rust,ignore
1390 /// trait T<A> {
1391 /// type Assoc;
1392 /// fn m(x: Self::Assoc, y: Self) -> A;
1393 /// }
1394 /// ```
1395 Trait {
1396 /// Name of this trait
1397 ///
1398 /// # Example:
1399 /// `T`
1400 name: GlobalId,
1401
1402 /// Generic parameters and constraints
1403 ///
1404 /// # Example:
1405 /// `<A>`
1406 generics: Generics,
1407
1408 /// Items required to implement the trait
1409 ///
1410 /// # Example:
1411 /// `type Assoc;`, `fn m ...;`
1412 items: Vec<TraitItem>,
1413
1414 /// Safe or unsafe
1415 safety: SafetyKind,
1416 },
1417
1418 /// A trait implementation.
1419 ///
1420 /// # Example:
1421 /// ```rust,ignore
1422 /// impl T<u8> for u16 {
1423 /// type Assoc = u32;
1424 /// fn m(x: u32, y: u16) -> u8 {
1425 /// (x as u8) + (y as u8)
1426 /// }
1427 /// }
1428 /// ```
1429 Impl {
1430 /// Generic arguments and constraints
1431 generics: Generics,
1432
1433 /// The type we implement the trait for
1434 ///
1435 /// # Example:
1436 /// `u16`
1437 self_ty: Ty,
1438
1439 /// Instantiated trait that is being implemented
1440 ///
1441 /// # Example:
1442 /// `T<u8>`
1443 of_trait: (GlobalId, Vec<GenericValue>),
1444
1445 /// Items in this impl
1446 ///
1447 /// # Example:
1448 /// `fn m ...`, `type Assoc ...`
1449 items: Vec<ImplItem>,
1450
1451 /// Implementations of traits required for this impl
1452 parent_bounds: Vec<(ImplExpr, ImplIdent)>,
1453 },
1454
1455 /// Internal node introduced by phases, corresponds to an alias to any item.
1456 Alias {
1457 /// New name
1458 name: GlobalId,
1459 /// Original name
1460 item: GlobalId,
1461 },
1462
1463 // TODO: Should we keep `Use`?
1464 /// A `use` statement
1465 Use {
1466 /// Path to used item(s)
1467 path: Vec<String>,
1468
1469 /// Comes from external crate
1470 is_external: bool,
1471
1472 /// Optional `as`
1473 rename: Option<String>,
1474 },
1475
1476 /// A `Quote` node is inserted by phase TransformHaxLibInline to deal with some `hax_lib` features.
1477 /// For example insertion of verbatim backend code.
1478 Quote {
1479 /// Content of the quote
1480 quote: Quote,
1481
1482 /// Description of the quote target position
1483 origin: ItemQuoteOrigin,
1484 },
1485
1486 /// A Rust module (`mod`, inline or not).
1487 /// This exists solely because modules can have attributes relevant to the hax engine.
1488 RustModule,
1489
1490 /// Fallback constructor to carry errors.
1491 Error(ErrorNode),
1492
1493 /// A resugared item.
1494 /// This variant is introduced before printing only.
1495 /// Phases must not produce this variant.
1496 Resugared(ResugaredItemKind),
1497
1498 /// Item that is not implemented yet
1499 NotImplementedYet,
1500}
1501
1502/// A top-level item with metadata.
1503#[derive_group_for_ast]
1504pub struct Item {
1505 /// The global identifier of the item.
1506 pub ident: GlobalId,
1507 /// The kind of the item.
1508 pub kind: ItemKind,
1509 /// Source span and attributes.
1510 pub meta: Metadata,
1511}
1512
1513impl Item {
1514 /// Checks whether the item was marked opaque using `hax_lib::opaque`
1515 pub fn is_opaque(&self) -> bool {
1516 self.meta.attributes.iter().any(|a| {
1517 matches!(
1518 a.kind,
1519 AttributeKind::Hax(hax_lib_macros_types::AttrPayload::Erased)
1520 )
1521 })
1522 }
1523}
1524
1525/// A "flat" module: this contains only non-module items.
1526#[derive_group_for_ast]
1527pub struct Module {
1528 /// The global identifier of the module.
1529 pub ident: GlobalId,
1530 /// The list of items that belongs to this module.
1531 pub items: Vec<Item>,
1532 /// Source span and attributes.
1533 pub meta: Metadata,
1534}
1535
1536impl Generics {
1537 /// Returns Iterator over all type-class constraints (`GenericConstraint::TypeClass`)
1538 pub fn type_class_constraints(&self) -> impl Iterator<Item = &ImplIdent> {
1539 self.constraints.iter().filter_map(|c| match c {
1540 GenericConstraint::TypeClass(impl_id) => Some(impl_id),
1541 _ => None,
1542 })
1543 }
1544 /// Returns Iterator over all equality constraints (`GenericConstraint::Equality`)
1545 pub fn equality_constraints(&self) -> impl Iterator<Item = &ProjectionPredicate> {
1546 self.constraints.iter().filter_map(|c| match c {
1547 GenericConstraint::Equality(pp) => Some(pp),
1548 _ => None,
1549 })
1550 }
1551}
1552
1553/// Traits for utilities on AST data types
1554pub mod traits {
1555 use super::*;
1556 /// Marks AST data types that carry metadata (span + attributes)
1557 pub trait HasMetadata {
1558 /// Get metadata
1559 fn metadata(&self) -> &Metadata;
1560 /// Get mutable borrow on metadata
1561 fn metadata_mut(&mut self) -> &mut Metadata;
1562 }
1563 /// Marks AST data types that carry a span
1564 pub trait HasSpan {
1565 /// Get span
1566 fn span(&self) -> Span;
1567 /// Mutable borrow on the span
1568 fn span_mut(&mut self) -> &mut Span;
1569 }
1570 /// Marks AST data types that carry a Type
1571 pub trait Typed {
1572 /// Get type
1573 fn ty(&self) -> &Ty;
1574 }
1575 impl<T: HasMetadata> HasSpan for T {
1576 fn span(&self) -> Span {
1577 self.metadata().span
1578 }
1579 fn span_mut(&mut self) -> &mut Span {
1580 &mut self.metadata_mut().span
1581 }
1582 }
1583
1584 /// Marks types of the AST that carry a kind (an enum for the actual content)
1585 pub trait HasKind {
1586 /// Type carrying the kind, should be named `<Self>Kind`
1587 type Kind;
1588 /// Get kind
1589 fn kind(&self) -> &Self::Kind;
1590 /// Get mutable borrow on kind
1591 fn kind_mut(&mut self) -> &mut Self::Kind;
1592 }
1593
1594 macro_rules! derive_has_metadata {
1595 ($($ty:ty),*) => {
1596 $(impl HasMetadata for $ty {
1597 fn metadata(&self) -> &Metadata {
1598 &self.meta
1599 }
1600 fn metadata_mut(&mut self) -> &mut Metadata {
1601 &mut self.meta
1602 }
1603 })*
1604 };
1605 }
1606 macro_rules! derive_has_kind {
1607 ($($ty:ty => $kind:ty),*) => {
1608 $(impl HasKind for $ty {
1609 type Kind = $kind;
1610 fn kind(&self) -> &Self::Kind {
1611 &self.kind
1612 }
1613 fn kind_mut(&mut self) -> &mut Self::Kind {
1614 &mut self.kind
1615 }
1616 })*
1617 };
1618 }
1619
1620 derive_has_metadata!(
1621 Item,
1622 Expr,
1623 Pat,
1624 Guard,
1625 Arm,
1626 ImplItem,
1627 TraitItem,
1628 GenericParam
1629 );
1630 derive_has_kind!(
1631 Item => ItemKind, Expr => ExprKind, Pat => PatKind, Guard => GuardKind,
1632 GenericParam => GenericParamKind, ImplItem => ImplItemKind, TraitItem => TraitItemKind, ImplExpr => ImplExprKind
1633 );
1634
1635 impl HasSpan for Attribute {
1636 fn span(&self) -> Span {
1637 self.span
1638 }
1639 fn span_mut(&mut self) -> &mut Span {
1640 &mut self.span
1641 }
1642 }
1643
1644 impl Typed for Expr {
1645 fn ty(&self) -> &Ty {
1646 &self.ty
1647 }
1648 }
1649 impl Typed for Pat {
1650 fn ty(&self) -> &Ty {
1651 &self.ty
1652 }
1653 }
1654 impl Typed for SpannedTy {
1655 fn ty(&self) -> &Ty {
1656 &self.ty
1657 }
1658 }
1659
1660 impl HasSpan for SpannedTy {
1661 fn span(&self) -> Span {
1662 self.span
1663 }
1664 fn span_mut(&mut self) -> &mut Span {
1665 &mut self.span
1666 }
1667 }
1668
1669 impl ExprKind {
1670 /// Convert to full `Expr` with type, span and attributes
1671 pub fn into_expr(self, span: Span, ty: Ty, attributes: Vec<Attribute>) -> Expr {
1672 Expr {
1673 kind: Box::new(self),
1674 ty,
1675 meta: Metadata { span, attributes },
1676 }
1677 }
1678 }
1679
1680 /// Manual implementation of HasKind as the Ty struct contains a Box<TyKind>
1681 /// instead of a TyKind directly.
1682 impl HasKind for Ty {
1683 type Kind = TyKind;
1684
1685 fn kind(&self) -> &Self::Kind {
1686 &self.0
1687 }
1688 fn kind_mut(&mut self) -> &mut Self::Kind {
1689 &mut self.0
1690 }
1691 }
1692
1693 /// Fragments of the AST on which we can store an `ErrorNode`.
1694 pub trait FallibleAstNode {
1695 /// Replace the current node with an error.
1696 fn set_error(&mut self, error_node: ErrorNode);
1697 /// Extract an error if any.
1698 fn get_error(&self) -> Option<&ErrorNode>;
1699 }
1700 macro_rules! derive_error_node {
1701 ($($ty:ident => $kind:ident),*) => {$(
1702 impl FallibleAstNode for $ty {
1703 fn set_error(&mut self, mut error_node: ErrorNode) {
1704 if let Some(base) = self.get_error().cloned() {
1705 error_node.diagnostics.extend_from_slice(&base.diagnostics);
1706 }
1707 *self.kind_mut() = $kind::Error(error_node)
1708 }
1709 fn get_error(&self) -> Option<&ErrorNode> {
1710 match &self.kind() {
1711 $kind::Error(error_node) => Some(error_node),
1712 _ => None,
1713 }
1714 }
1715 }
1716 )*};
1717 }
1718
1719 derive_error_node!(Item => ItemKind, Pat => PatKind, Expr => ExprKind, Ty => TyKind);
1720}
1721pub use traits::*;