Skip to main content

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::*;