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