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