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