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