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