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