Skip to main content

bhc_ast/
lib.rs

1//! Abstract syntax tree definitions for BHC.
2//!
3//! This crate defines the AST produced by parsing Haskell 2026 source code.
4//! The AST preserves source locations and syntactic structure.
5
6#![warn(missing_docs)]
7
8use bhc_index::define_index;
9use bhc_intern::{Ident, Symbol};
10use bhc_span::Span;
11
12define_index! {
13    /// Index into the expression arena.
14    pub struct ExprId;
15
16    /// Index into the pattern arena.
17    pub struct PatId;
18
19    /// Index into the type arena.
20    pub struct TypeId;
21
22    /// Index into the declaration arena.
23    pub struct DeclId;
24}
25
26// ============================================================
27// Documentation Comments
28// ============================================================
29
30/// The kind of documentation comment.
31#[derive(Clone, Copy, Debug, PartialEq, Eq)]
32pub enum DocKind {
33    /// Preceding documentation: `-- |` or `{- | -}`
34    /// Documents the following item.
35    Preceding,
36    /// Trailing documentation: `-- ^` or `{- ^ -}`
37    /// Documents the preceding item.
38    Trailing,
39}
40
41/// A Haddock-style documentation comment.
42#[derive(Clone, Debug)]
43pub struct DocComment {
44    /// The raw text content of the documentation.
45    pub text: String,
46    /// The kind of documentation (preceding or trailing).
47    pub kind: DocKind,
48    /// The span of the comment in source.
49    pub span: Span,
50}
51
52impl DocComment {
53    /// Create a new preceding documentation comment.
54    #[must_use]
55    pub fn preceding(text: String, span: Span) -> Self {
56        Self {
57            text,
58            kind: DocKind::Preceding,
59            span,
60        }
61    }
62
63    /// Create a new trailing documentation comment.
64    #[must_use]
65    pub fn trailing(text: String, span: Span) -> Self {
66        Self {
67            text,
68            kind: DocKind::Trailing,
69            span,
70        }
71    }
72}
73
74/// A Haskell module.
75#[derive(Clone, Debug)]
76pub struct Module {
77    /// Module documentation comment.
78    pub doc: Option<DocComment>,
79    /// Module pragmas (LANGUAGE, OPTIONS_GHC, etc.).
80    pub pragmas: Vec<Pragma>,
81    /// Module name.
82    pub name: Option<ModuleName>,
83    /// Export list.
84    pub exports: Option<Vec<Export>>,
85    /// Import declarations.
86    pub imports: Vec<ImportDecl>,
87    /// Top-level declarations.
88    pub decls: Vec<Decl>,
89    /// Span of the entire module.
90    pub span: Span,
91}
92
93// ============================================================
94// Pragmas
95// ============================================================
96
97/// A pragma in the source code.
98#[derive(Clone, Debug)]
99pub struct Pragma {
100    /// The kind of pragma.
101    pub kind: PragmaKind,
102    /// The span.
103    pub span: Span,
104}
105
106/// The kind of pragma.
107#[derive(Clone, Debug)]
108pub enum PragmaKind {
109    /// Language extension: `{-# LANGUAGE GADTs #-}`
110    Language(Vec<Symbol>),
111    /// GHC options: `{-# OPTIONS_GHC -Wall #-}`
112    OptionsGhc(String),
113    /// Inline pragma: `{-# INLINE foo #-}`
114    Inline(Ident),
115    /// No-inline pragma: `{-# NOINLINE foo #-}`
116    NoInline(Ident),
117    /// Inlinable pragma: `{-# INLINABLE foo #-}`
118    Inlinable(Ident),
119    /// Specialize pragma: `{-# SPECIALIZE foo :: Int -> Int #-}`
120    Specialize(Ident, Type),
121    /// Unpack pragma: `{-# UNPACK #-}`
122    Unpack,
123    /// No-unpack pragma: `{-# NOUNPACK #-}`
124    NoUnpack,
125    /// Source pragma (for generated code): `{-# SOURCE #-}`
126    Source,
127    /// Complete pragma: `{-# COMPLETE Pat1, Pat2 #-}`
128    Complete(Vec<Ident>),
129    /// Minimal pragma: `{-# MINIMAL foo | bar #-}`
130    Minimal(String),
131    /// Deprecated pragma: `{-# DEPRECATED foo "message" #-}`
132    Deprecated(Option<Vec<Ident>>, String),
133    /// Warning pragma: `{-# WARNING foo "message" #-}`
134    Warning(Option<Vec<Ident>>, String),
135    /// Unknown/unsupported pragma (preserved for compatibility)
136    Other(String),
137}
138
139/// Known language extensions.
140#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
141pub enum Extension {
142    // Type system
143    /// GADTs
144    GADTs,
145    /// Type families
146    TypeFamilies,
147    /// Data kinds
148    DataKinds,
149    /// Kind signatures
150    KindSignatures,
151    /// Rank-N types
152    RankNTypes,
153    /// Existential quantification
154    ExistentialQuantification,
155    /// Scoped type variables
156    ScopedTypeVariables,
157    /// Type applications
158    TypeApplications,
159    /// Flexible instances
160    FlexibleInstances,
161    /// Flexible contexts
162    FlexibleContexts,
163    /// Multi-param type classes
164    MultiParamTypeClasses,
165    /// Functional dependencies
166    FunctionalDependencies,
167    /// Undecidable instances
168    UndecidableInstances,
169    /// Overlapping instances
170    OverlappingInstances,
171    /// Constraint kinds
172    ConstraintKinds,
173
174    // Syntax
175    /// Lambda case
176    LambdaCase,
177    /// Multi-way if
178    MultiWayIf,
179    /// Block arguments
180    BlockArguments,
181    /// Pattern guards
182    PatternGuards,
183    /// View patterns
184    ViewPatterns,
185    /// Pattern synonyms
186    PatternSynonyms,
187    /// Record wild cards
188    RecordWildCards,
189    /// Named field puns
190    NamedFieldPuns,
191    /// Overloaded strings
192    OverloadedStrings,
193    /// Tuple sections
194    TupleSections,
195    /// Overloaded lists
196    OverloadedLists,
197    /// Numeric underscores
198    NumericUnderscores,
199    /// Hex float literals
200    HexFloatLiterals,
201    /// Binary literals
202    BinaryLiterals,
203    /// Negative literals
204    NegativeLiterals,
205
206    // Strictness
207    /// Bang patterns
208    BangPatterns,
209    /// Strict data
210    StrictData,
211    /// Strict
212    Strict,
213
214    // Deriving
215    /// Derive functor
216    DeriveFunctor,
217    /// Derive foldable
218    DeriveFoldable,
219    /// Derive traversable
220    DeriveTraversable,
221    /// Derive generic
222    DeriveGeneric,
223    /// Derive data typeable
224    DeriveDataTypeable,
225    /// Derive lift
226    DeriveLift,
227    /// Deriving via
228    DerivingVia,
229    /// Deriving strategies
230    DerivingStrategies,
231    /// Generalized newtype deriving
232    GeneralizedNewtypeDeriving,
233    /// Standalone deriving
234    StandaloneDeriving,
235
236    // FFI
237    /// Foreign function interface
238    ForeignFunctionInterface,
239    /// C API FFI
240    CApiFFI,
241    /// Unsafe FFI
242    UnliftedFFITypes,
243
244    // Other
245    /// Template Haskell
246    TemplateHaskell,
247    /// Template Haskell quotes
248    TemplateHaskellQuotes,
249    /// Quasi quotes
250    QuasiQuotes,
251    /// Type operators
252    TypeOperators,
253    /// Explicit forall
254    ExplicitForAll,
255    /// Explicit namespaces
256    ExplicitNamespaces,
257    /// Empty data declarations
258    EmptyDataDecls,
259    /// Empty case
260    EmptyCase,
261    /// Instance sigs
262    InstanceSigs,
263    /// Default signatures
264    DefaultSignatures,
265    /// Named defaults
266    NamedDefaults,
267    /// C preprocessor
268    CPP,
269
270    /// Unknown extension (preserved)
271    Unknown(Symbol),
272}
273
274/// Classification of extension support status.
275#[derive(Clone, Copy, Debug, PartialEq, Eq)]
276pub enum ExtensionStatus {
277    /// Fully implemented or always-on in BHC.
278    Supported,
279    /// Recognized but not yet implemented — emits a warning.
280    Unimplemented,
281    /// Unknown extension name.
282    Unknown,
283}
284
285impl Extension {
286    /// Classify this extension's support status in BHC.
287    #[must_use]
288    pub fn status(&self) -> ExtensionStatus {
289        match self {
290            // Type system — implemented or always-on
291            Self::GADTs
292            | Self::TypeFamilies
293            | Self::DataKinds
294            | Self::KindSignatures
295            | Self::ScopedTypeVariables
296            | Self::TypeApplications
297            | Self::FlexibleInstances
298            | Self::FlexibleContexts
299            | Self::MultiParamTypeClasses
300            | Self::FunctionalDependencies
301            | Self::TypeOperators
302            | Self::ExplicitForAll => ExtensionStatus::Supported,
303
304            // Syntax — always-on in BHC
305            Self::LambdaCase
306            | Self::MultiWayIf
307            | Self::BlockArguments
308            | Self::PatternGuards
309            | Self::ViewPatterns
310            | Self::PatternSynonyms
311            | Self::RecordWildCards
312            | Self::NamedFieldPuns
313            | Self::OverloadedStrings
314            | Self::TupleSections
315            | Self::OverloadedLists
316            | Self::NumericUnderscores
317            | Self::BinaryLiterals
318            | Self::NegativeLiterals => ExtensionStatus::Supported,
319
320            // Strictness — always-on or handled
321            Self::BangPatterns | Self::StrictData | Self::Strict => ExtensionStatus::Supported,
322
323            // Deriving — implemented
324            Self::DeriveFunctor
325            | Self::DeriveFoldable
326            | Self::DeriveTraversable
327            | Self::DeriveGeneric
328            | Self::DerivingVia
329            | Self::DerivingStrategies
330            | Self::GeneralizedNewtypeDeriving
331            | Self::StandaloneDeriving
332            | Self::DeriveDataTypeable => ExtensionStatus::Supported,
333
334            // FFI — implemented
335            Self::ForeignFunctionInterface => ExtensionStatus::Supported,
336
337            // Other — implemented
338            Self::EmptyDataDecls
339            | Self::EmptyCase
340            | Self::InstanceSigs
341            | Self::DefaultSignatures
342            | Self::ExplicitNamespaces
343            | Self::CPP => ExtensionStatus::Supported,
344
345            // Extensions that are accepted for compatibility but silently
346            // relaxed (BHC doesn't enforce the restriction they lift)
347            Self::UndecidableInstances | Self::OverlappingInstances => ExtensionStatus::Supported,
348
349            // Existential quantification in data constructors
350            Self::ExistentialQuantification => ExtensionStatus::Supported,
351
352            // Rank-N polymorphism (forall in function argument positions)
353            Self::RankNTypes => ExtensionStatus::Supported,
354
355            // Recognized but not yet implemented
356            Self::ConstraintKinds
357            | Self::HexFloatLiterals
358            | Self::DeriveLift
359            | Self::CApiFFI
360            | Self::UnliftedFFITypes
361            | Self::TemplateHaskell
362            | Self::TemplateHaskellQuotes
363            | Self::QuasiQuotes
364            | Self::NamedDefaults => ExtensionStatus::Unimplemented,
365
366            // Unknown — check if it's a recognized GHC extension we silently accept
367            Self::Unknown(name) => {
368                match name.as_str() {
369                    // Common GHC extensions we silently accept for compatibility
370                    "Arrows"
371                    | "MonoLocalBinds"
372                    | "ImpredicativeTypes"
373                    | "TypeFamilyDependencies"
374                    | "DeriveAnyClass"
375                    | "RoleAnnotations"
376                    | "AllowAmbiguousTypes"
377                    | "TypeSynonymInstances"
378                    | "PackageImports"
379                    | "NoImplicitPrelude"
380                    | "NoMonomorphismRestriction"
381                    | "DisambiguateRecordFields"
382                    | "DuplicateRecordFields"
383                    | "ApplicativeDo"
384                    | "NumDecimals"
385                    | "MagicHash"
386                    | "UnboxedTuples"
387                    | "TypeInType"
388                    | "PolyKinds"
389                    | "StarIsType"
390                    | "ImportQualifiedPost"
391                    | "StandaloneKindSignatures"
392                    | "QuantifiedConstraints"
393                    | "LinearTypes"
394                    | "UnicodeSyntax"
395                    | "ParallelListComp"
396                    | "TransformListComp"
397                    | "MonadComprehensions"
398                    | "ExtendedDefaultRules"
399                    | "PostfixOperators"
400                    | "ScopedTypeVariables"
401                    | "NoFieldSelectors" => ExtensionStatus::Supported,
402                    _ => ExtensionStatus::Unknown,
403                }
404            }
405        }
406    }
407
408    /// Parse an extension name.
409    #[must_use]
410    pub fn from_name(name: &str) -> Self {
411        match name {
412            // Type system
413            "GADTs" => Self::GADTs,
414            "TypeFamilies" => Self::TypeFamilies,
415            "DataKinds" => Self::DataKinds,
416            "KindSignatures" => Self::KindSignatures,
417            "RankNTypes" | "Rank2Types" | "PolymorphicComponents" => Self::RankNTypes,
418            "ExistentialQuantification" => Self::ExistentialQuantification,
419            "ScopedTypeVariables" => Self::ScopedTypeVariables,
420            "TypeApplications" => Self::TypeApplications,
421            "FlexibleInstances" => Self::FlexibleInstances,
422            "FlexibleContexts" => Self::FlexibleContexts,
423            "MultiParamTypeClasses" => Self::MultiParamTypeClasses,
424            "FunctionalDependencies" => Self::FunctionalDependencies,
425            "UndecidableInstances" => Self::UndecidableInstances,
426            "OverlappingInstances" | "IncoherentInstances" => Self::OverlappingInstances,
427            "ConstraintKinds" => Self::ConstraintKinds,
428
429            // Syntax
430            "LambdaCase" => Self::LambdaCase,
431            "MultiWayIf" => Self::MultiWayIf,
432            "BlockArguments" => Self::BlockArguments,
433            "PatternGuards" => Self::PatternGuards,
434            "ViewPatterns" => Self::ViewPatterns,
435            "PatternSynonyms" => Self::PatternSynonyms,
436            "RecordWildCards" => Self::RecordWildCards,
437            "NamedFieldPuns" => Self::NamedFieldPuns,
438            "OverloadedStrings" => Self::OverloadedStrings,
439            "TupleSections" => Self::TupleSections,
440            "OverloadedLists" => Self::OverloadedLists,
441            "NumericUnderscores" => Self::NumericUnderscores,
442            "HexFloatLiterals" => Self::HexFloatLiterals,
443            "BinaryLiterals" => Self::BinaryLiterals,
444            "NegativeLiterals" => Self::NegativeLiterals,
445
446            // Strictness
447            "BangPatterns" => Self::BangPatterns,
448            "StrictData" => Self::StrictData,
449            "Strict" => Self::Strict,
450
451            // Deriving
452            "DeriveFunctor" => Self::DeriveFunctor,
453            "DeriveFoldable" => Self::DeriveFoldable,
454            "DeriveTraversable" => Self::DeriveTraversable,
455            "DeriveGeneric" => Self::DeriveGeneric,
456            "DeriveDataTypeable" => Self::DeriveDataTypeable,
457            "DeriveLift" => Self::DeriveLift,
458            "DerivingVia" => Self::DerivingVia,
459            "DerivingStrategies" => Self::DerivingStrategies,
460            "GeneralizedNewtypeDeriving" | "GeneralisedNewtypeDeriving" => {
461                Self::GeneralizedNewtypeDeriving
462            }
463            "StandaloneDeriving" => Self::StandaloneDeriving,
464
465            // FFI
466            "ForeignFunctionInterface" | "FFI" => Self::ForeignFunctionInterface,
467            "CApiFFI" => Self::CApiFFI,
468            "UnliftedFFITypes" => Self::UnliftedFFITypes,
469
470            // Other
471            "TemplateHaskell" => Self::TemplateHaskell,
472            "TemplateHaskellQuotes" => Self::TemplateHaskellQuotes,
473            "QuasiQuotes" => Self::QuasiQuotes,
474            "TypeOperators" => Self::TypeOperators,
475            "ExplicitForAll" => Self::ExplicitForAll,
476            "ExplicitNamespaces" => Self::ExplicitNamespaces,
477            "EmptyDataDecls" => Self::EmptyDataDecls,
478            "EmptyCase" => Self::EmptyCase,
479            "InstanceSigs" => Self::InstanceSigs,
480            "DefaultSignatures" => Self::DefaultSignatures,
481            "NamedDefaults" => Self::NamedDefaults,
482            "CPP" => Self::CPP,
483
484            _ => Self::Unknown(Symbol::intern(name)),
485        }
486    }
487}
488
489/// A qualified module name like `Data.List`.
490#[derive(Clone, Debug, PartialEq, Eq, Hash)]
491pub struct ModuleName {
492    /// The components of the name.
493    pub parts: Vec<Symbol>,
494    /// The span.
495    pub span: Span,
496}
497
498impl std::fmt::Display for ModuleName {
499    /// Get the fully qualified name as a dotted string (e.g. `Data.Map`).
500    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
501        let joined = self
502            .parts
503            .iter()
504            .map(|s| s.as_str())
505            .collect::<Vec<_>>()
506            .join(".");
507        f.write_str(&joined)
508    }
509}
510
511/// An export specification.
512#[derive(Clone, Debug)]
513pub enum Export {
514    /// Export a value: `foo`
515    Var(Ident, Span),
516    /// Export a type with optional constructors: `Foo(..)` or `Foo(A, B)`
517    Type(Ident, Option<Vec<Ident>>, Span),
518    /// Export a module: `module Data.List`
519    Module(ModuleName, Span),
520    /// Export a pattern synonym: `pattern Foo`
521    Pattern(Ident, Span),
522}
523
524/// An import declaration.
525#[derive(Clone, Debug)]
526pub struct ImportDecl {
527    /// The module being imported.
528    pub module: ModuleName,
529    /// Whether this is a qualified import.
530    pub qualified: bool,
531    /// The alias for qualified imports.
532    pub alias: Option<ModuleName>,
533    /// The import specification (hiding or explicit).
534    pub spec: Option<ImportSpec>,
535    /// The span.
536    pub span: Span,
537}
538
539/// Import specification.
540#[derive(Clone, Debug)]
541pub enum ImportSpec {
542    /// Import only the listed items.
543    Only(Vec<Import>),
544    /// Import everything except the listed items.
545    Hiding(Vec<Import>),
546}
547
548/// A single import item.
549#[derive(Clone, Debug)]
550pub enum Import {
551    /// Import a value.
552    Var(Ident, Span),
553    /// Import a type with optional constructors.
554    Type(Ident, Option<Vec<Ident>>, Span),
555    /// Import a pattern synonym: `pattern Foo`
556    Pattern(Ident, Span),
557}
558
559/// A top-level declaration.
560#[derive(Clone, Debug)]
561pub enum Decl {
562    /// Type signature: `foo :: Int -> Int`
563    TypeSig(TypeSig),
564    /// Function/value binding: `foo x = x + 1`
565    FunBind(FunBind),
566    /// Data type: `data Foo = A | B Int`
567    DataDecl(DataDecl),
568    /// Type alias: `type Foo = Bar`
569    TypeAlias(TypeAlias),
570    /// Newtype: `newtype Foo = Foo Bar`
571    Newtype(NewtypeDecl),
572    /// Class definition: `class Eq a where ...`
573    ClassDecl(ClassDecl),
574    /// Instance definition: `instance Eq Int where ...`
575    InstanceDecl(InstanceDecl),
576    /// Foreign import/export
577    Foreign(ForeignDecl),
578    /// Fixity declaration: `infixl 6 +`
579    Fixity(FixityDecl),
580    /// Pragma declaration: `{-# MINIMAL ... #-}`
581    PragmaDecl(Pragma),
582    /// Standalone deriving: `deriving instance Show Foo`
583    StandaloneDeriving(StandaloneDeriving),
584    /// Pattern synonym: `pattern Zero = Lit 0`
585    PatternSynonym(PatternSynonymDecl),
586    /// Standalone type family: `type family F a` or `type family F a where ...`
587    TypeFamilyDecl(TypeFamilyDecl),
588    /// Standalone type family instance: `type instance F Int = Bool`
589    TypeInstanceDecl(TypeInstanceDecl),
590    /// Standalone data family: `data family F a`
591    DataFamilyDecl(DataFamilyDecl),
592    /// Data family instance: `data instance F Int = Con1 Int | Con2`
593    DataInstanceDecl(DataInstanceDecl),
594}
595
596/// A standalone deriving declaration: `deriving instance Show Foo`
597#[derive(Clone, Debug)]
598pub struct StandaloneDeriving {
599    /// The class to derive (e.g., Show, Eq).
600    pub class: Ident,
601    /// The type to derive for (e.g., Foo).
602    pub ty: Type,
603    /// Source span.
604    pub span: Span,
605}
606
607/// A pattern synonym declaration: `pattern Zero = Lit 0`
608#[derive(Clone, Debug)]
609pub struct PatternSynonymDecl {
610    /// The pattern synonym name (e.g., Zero).
611    pub name: Ident,
612    /// Pattern variables.
613    pub args: Vec<Ident>,
614    /// Direction: bidirectional (`=`) or unidirectional (`<-`).
615    pub direction: PatSynDir,
616    /// The RHS pattern.
617    pub pattern: Pat,
618    /// Source span.
619    pub span: Span,
620}
621
622/// Whether a type family is open or closed.
623#[derive(Clone, Copy, Debug, PartialEq, Eq)]
624pub enum TypeFamilyKind {
625    /// Open type family: `type family F a`
626    Open,
627    /// Closed type family: `type family F a where ...`
628    Closed,
629}
630
631/// A standalone type family declaration.
632///
633/// Open:   `type family F a`
634/// Closed: `type family F a where F Int = Bool; F a = ()`
635#[derive(Clone, Debug)]
636pub struct TypeFamilyDecl {
637    /// Documentation comment.
638    pub doc: Option<DocComment>,
639    /// The family name.
640    pub name: Ident,
641    /// Type parameters.
642    pub params: Vec<TyVar>,
643    /// Optional result kind signature.
644    pub kind: Option<Kind>,
645    /// Whether this family is open or closed.
646    pub family_kind: TypeFamilyKind,
647    /// Equations (only for closed families).
648    pub equations: Vec<TypeFamilyEqn>,
649    /// The span.
650    pub span: Span,
651}
652
653/// A single equation in a closed type family.
654#[derive(Clone, Debug)]
655pub struct TypeFamilyEqn {
656    /// Type argument patterns.
657    pub args: Vec<Type>,
658    /// The right-hand side type.
659    pub rhs: Type,
660    /// The span.
661    pub span: Span,
662}
663
664/// A standalone type instance declaration (for open type families).
665///
666/// `type instance F Int = Bool`
667#[derive(Clone, Debug)]
668pub struct TypeInstanceDecl {
669    /// Documentation comment.
670    pub doc: Option<DocComment>,
671    /// The family name.
672    pub name: Ident,
673    /// Type argument patterns.
674    pub args: Vec<Type>,
675    /// The right-hand side type.
676    pub rhs: Type,
677    /// The span.
678    pub span: Span,
679}
680
681/// A standalone data family declaration: `data family F a`
682#[derive(Clone, Debug)]
683pub struct DataFamilyDecl {
684    /// Documentation comment.
685    pub doc: Option<DocComment>,
686    /// The family name.
687    pub name: Ident,
688    /// Type parameters.
689    pub params: Vec<TyVar>,
690    /// Optional result kind signature.
691    pub kind: Option<Kind>,
692    /// The span.
693    pub span: Span,
694}
695
696/// A data family instance: `data instance F Int = Con1 Int | Con2`
697#[derive(Clone, Debug)]
698pub struct DataInstanceDecl {
699    /// Documentation comment.
700    pub doc: Option<DocComment>,
701    /// The family name.
702    pub family_name: Ident,
703    /// Type argument patterns (e.g., `[Int]`).
704    pub args: Vec<Type>,
705    /// H98 constructors.
706    pub constrs: Vec<ConDecl>,
707    /// GADT constructors.
708    pub gadt_constrs: Vec<GadtConDecl>,
709    /// Deriving clauses.
710    pub deriving: Vec<DerivingClause>,
711    /// The span.
712    pub span: Span,
713}
714
715/// Direction of a pattern synonym.
716#[derive(Clone, Debug)]
717pub enum PatSynDir {
718    /// `pattern Foo x = Con x 0` — usable in both patterns and expressions.
719    Bidirectional,
720    /// `pattern Foo x <- Con x _` — usable only in patterns.
721    Unidirectional,
722}
723
724/// A type signature.
725#[derive(Clone, Debug)]
726pub struct TypeSig {
727    /// Documentation comment.
728    pub doc: Option<DocComment>,
729    /// The names being typed.
730    pub names: Vec<Ident>,
731    /// The type.
732    pub ty: Type,
733    /// The span.
734    pub span: Span,
735}
736
737/// A function binding.
738#[derive(Clone, Debug)]
739pub struct FunBind {
740    /// Documentation comment.
741    pub doc: Option<DocComment>,
742    /// The function name.
743    pub name: Ident,
744    /// The clauses (pattern matches).
745    pub clauses: Vec<Clause>,
746    /// The span.
747    pub span: Span,
748}
749
750/// A clause in a function binding.
751#[derive(Clone, Debug)]
752pub struct Clause {
753    /// The patterns for arguments.
754    pub pats: Vec<Pat>,
755    /// The right-hand side.
756    pub rhs: Rhs,
757    /// Local bindings.
758    pub wheres: Vec<Decl>,
759    /// The span.
760    pub span: Span,
761}
762
763/// The right-hand side of a binding.
764#[derive(Clone, Debug)]
765pub enum Rhs {
766    /// Simple: `= expr`
767    Simple(Expr, Span),
768    /// Guarded: `| guard = expr`
769    Guarded(Vec<GuardedRhs>, Span),
770}
771
772/// A guarded right-hand side.
773#[derive(Clone, Debug)]
774pub struct GuardedRhs {
775    /// The guards (can be multiple, e.g., `| pat <- expr, cond`).
776    pub guards: Vec<Guard>,
777    /// The body expression.
778    pub body: Expr,
779    /// The span.
780    pub span: Span,
781}
782
783/// A guard in a guarded RHS.
784#[derive(Clone, Debug)]
785pub enum Guard {
786    /// A pattern guard: `pat <- expr`
787    Pattern(Pat, Expr, Span),
788    /// A boolean guard: `expr`
789    Expr(Expr, Span),
790}
791
792impl Guard {
793    /// Get the span of this guard.
794    #[must_use]
795    pub fn span(&self) -> Span {
796        match self {
797            Self::Pattern(_, _, s) | Self::Expr(_, s) => *s,
798        }
799    }
800}
801
802/// A deriving strategy annotation.
803#[derive(Clone, Debug)]
804pub enum DerivingStrategy {
805    /// No explicit strategy; use heuristic.
806    Default,
807    /// `stock` — use built-in derivation (Eq, Ord, Show, etc.).
808    Stock,
809    /// `newtype` — GeneralizedNewtypeDeriving.
810    Newtype,
811    /// `anyclass` — DeriveAnyClass (empty instance with defaults).
812    Anyclass,
813    /// `via SomeType` — DerivingVia.
814    Via(Type),
815}
816
817/// A single deriving clause entry: a strategy paired with a class name.
818#[derive(Clone, Debug)]
819pub struct DerivingClause {
820    /// The deriving strategy.
821    pub strategy: DerivingStrategy,
822    /// The class to derive.
823    pub class: Ident,
824}
825
826/// A data type declaration.
827#[derive(Clone, Debug)]
828pub struct DataDecl {
829    /// Documentation comment.
830    pub doc: Option<DocComment>,
831    /// The type name.
832    pub name: Ident,
833    /// Type parameters.
834    pub params: Vec<TyVar>,
835    /// Constructors (H98 syntax).
836    pub constrs: Vec<ConDecl>,
837    /// GADT constructors (where syntax).
838    pub gadt_constrs: Vec<GadtConDecl>,
839    /// Deriving clauses.
840    pub deriving: Vec<DerivingClause>,
841    /// The span.
842    pub span: Span,
843}
844
845/// A GADT constructor declaration: `ConName :: Type`.
846#[derive(Clone, Debug)]
847pub struct GadtConDecl {
848    /// Documentation comment.
849    pub doc: Option<DocComment>,
850    /// Constructor name.
851    pub name: Ident,
852    /// The full constructor type, e.g. `Int -> Expr Int`.
853    pub ty: Type,
854    /// The span.
855    pub span: Span,
856}
857
858/// A data constructor declaration.
859#[derive(Clone, Debug)]
860pub struct ConDecl {
861    /// Documentation comment.
862    pub doc: Option<DocComment>,
863    /// Constructor name.
864    pub name: Ident,
865    /// Constructor fields.
866    pub fields: ConFields,
867    /// Existentially quantified type variables (from `forall a.` syntax).
868    pub existential_vars: Vec<TyVar>,
869    /// Existential context constraints (from `C a =>` syntax).
870    pub existential_context: Vec<Constraint>,
871    /// The span.
872    pub span: Span,
873}
874
875/// Constructor fields.
876#[derive(Clone, Debug)]
877pub enum ConFields {
878    /// Positional: `Foo Int String`
879    Positional(Vec<Type>),
880    /// Record: `Foo { bar :: Int, baz :: String }`
881    Record(Vec<FieldDecl>),
882}
883
884/// A record field declaration.
885#[derive(Clone, Debug)]
886pub struct FieldDecl {
887    /// Documentation comment.
888    pub doc: Option<DocComment>,
889    /// Field name.
890    pub name: Ident,
891    /// Field type.
892    pub ty: Type,
893    /// The span.
894    pub span: Span,
895}
896
897/// A type alias declaration.
898#[derive(Clone, Debug)]
899pub struct TypeAlias {
900    /// Documentation comment.
901    pub doc: Option<DocComment>,
902    /// The alias name.
903    pub name: Ident,
904    /// Type parameters.
905    pub params: Vec<TyVar>,
906    /// The aliased type.
907    pub ty: Type,
908    /// The span.
909    pub span: Span,
910}
911
912/// A newtype declaration.
913#[derive(Clone, Debug)]
914pub struct NewtypeDecl {
915    /// Documentation comment.
916    pub doc: Option<DocComment>,
917    /// The type name.
918    pub name: Ident,
919    /// Type parameters.
920    pub params: Vec<TyVar>,
921    /// The constructor.
922    pub constr: ConDecl,
923    /// Deriving clauses.
924    pub deriving: Vec<DerivingClause>,
925    /// The span.
926    pub span: Span,
927}
928
929/// A type class declaration.
930#[derive(Clone, Debug)]
931pub struct ClassDecl {
932    /// Documentation comment.
933    pub doc: Option<DocComment>,
934    /// Superclass constraints.
935    pub context: Vec<Constraint>,
936    /// Class name.
937    pub name: Ident,
938    /// Type parameters (multi-param type classes).
939    pub params: Vec<TyVar>,
940    /// Functional dependencies.
941    pub fundeps: Vec<FunDep>,
942    /// Associated type declarations.
943    pub assoc_types: Vec<AssocType>,
944    /// Method signatures and default implementations.
945    pub methods: Vec<Decl>,
946    /// The span.
947    pub span: Span,
948}
949
950/// An associated type declaration within a type class.
951///
952/// Example: `type Elem c` in `class Collection c where type Elem c`
953#[derive(Clone, Debug)]
954pub struct AssocType {
955    /// The name of the associated type.
956    pub name: Ident,
957    /// Type parameters (in addition to class params).
958    pub params: Vec<TyVar>,
959    /// Optional kind signature.
960    pub kind: Option<Kind>,
961    /// Optional default type.
962    pub default: Option<Type>,
963    /// The span.
964    pub span: Span,
965}
966
967/// A kind (for kind signatures).
968#[derive(Clone, Debug)]
969pub enum Kind {
970    /// The kind of types: `*` or `Type`.
971    Star,
972    /// Function kind: `k1 -> k2`.
973    Arrow(Box<Kind>, Box<Kind>),
974    /// Named kind variable.
975    Var(Ident),
976}
977
978/// A functional dependency in a type class.
979#[derive(Clone, Debug)]
980pub struct FunDep {
981    /// Variables that determine others.
982    pub from: Vec<Ident>,
983    /// Variables that are determined.
984    pub to: Vec<Ident>,
985    /// The span.
986    pub span: Span,
987}
988
989/// An instance declaration.
990#[derive(Clone, Debug)]
991pub struct InstanceDecl {
992    /// Documentation comment.
993    pub doc: Option<DocComment>,
994    /// Instance constraints.
995    pub context: Vec<Constraint>,
996    /// Class name.
997    pub class: Ident,
998    /// Instance type.
999    pub ty: Type,
1000    /// Associated type definitions.
1001    pub assoc_type_defs: Vec<AssocTypeDef>,
1002    /// Method implementations.
1003    pub methods: Vec<Decl>,
1004    /// The span.
1005    pub span: Span,
1006}
1007
1008/// An associated type definition within an instance.
1009///
1010/// Example: `type Elem [a] = a` in `instance Collection [a] where type Elem [a] = a`
1011#[derive(Clone, Debug)]
1012pub struct AssocTypeDef {
1013    /// The name of the associated type.
1014    pub name: Ident,
1015    /// Type arguments (patterns for the associated type).
1016    pub args: Vec<Type>,
1017    /// The definition (right-hand side).
1018    pub rhs: Type,
1019    /// The span.
1020    pub span: Span,
1021}
1022
1023/// Safety annotation for foreign declarations.
1024#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1025pub enum ForeignSafety {
1026    /// Safe FFI call (default). May trigger GC, slower.
1027    Safe,
1028    /// Unsafe FFI call. Must be fast, no callbacks.
1029    Unsafe,
1030    /// Interruptible FFI call. Can be interrupted by async exceptions.
1031    Interruptible,
1032}
1033
1034/// A foreign declaration.
1035#[derive(Clone, Debug)]
1036pub struct ForeignDecl {
1037    /// Documentation comment.
1038    pub doc: Option<DocComment>,
1039    /// Import or export.
1040    pub kind: ForeignKind,
1041    /// Calling convention.
1042    pub convention: Symbol,
1043    /// Safety annotation.
1044    pub safety: ForeignSafety,
1045    /// External name.
1046    pub external_name: Option<String>,
1047    /// Haskell name.
1048    pub name: Ident,
1049    /// Type signature.
1050    pub ty: Type,
1051    /// The span.
1052    pub span: Span,
1053}
1054
1055/// Foreign declaration kind.
1056#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1057pub enum ForeignKind {
1058    /// Foreign import.
1059    Import,
1060    /// Foreign export.
1061    Export,
1062}
1063
1064/// A fixity declaration.
1065#[derive(Clone, Debug)]
1066pub struct FixityDecl {
1067    /// The fixity.
1068    pub fixity: Fixity,
1069    /// Precedence level (0-9).
1070    pub prec: u8,
1071    /// The operators.
1072    pub ops: Vec<Ident>,
1073    /// The span.
1074    pub span: Span,
1075}
1076
1077/// Operator fixity.
1078#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1079pub enum Fixity {
1080    /// Left associative.
1081    Left,
1082    /// Right associative.
1083    Right,
1084    /// Non-associative.
1085    None,
1086}
1087
1088/// An expression.
1089#[derive(Clone, Debug)]
1090pub enum Expr {
1091    /// Variable: `x`
1092    Var(Ident, Span),
1093    /// Qualified variable: `M.foo`, `Data.List.sort`
1094    QualVar(ModuleName, Ident, Span),
1095    /// Constructor: `Just`
1096    Con(Ident, Span),
1097    /// Qualified constructor: `M.Just`, `Data.Maybe.Nothing`
1098    QualCon(ModuleName, Ident, Span),
1099    /// Literal: `42`, `"hello"`
1100    Lit(Lit, Span),
1101    /// Application: `f x`
1102    App(Box<Expr>, Box<Expr>, Span),
1103    /// Lambda: `\x -> x`
1104    Lam(Vec<Pat>, Box<Expr>, Span),
1105    /// Let: `let x = 1 in x`
1106    Let(Vec<Decl>, Box<Expr>, Span),
1107    /// If: `if c then t else e`
1108    If(Box<Expr>, Box<Expr>, Box<Expr>, Span),
1109    /// Case: `case x of { ... }`
1110    Case(Box<Expr>, Vec<Alt>, Span),
1111    /// Do block: `do { ... }`
1112    Do(Vec<Stmt>, Span),
1113    /// Tuple: `(a, b, c)`
1114    Tuple(Vec<Expr>, Span),
1115    /// List: `[1, 2, 3]`
1116    List(Vec<Expr>, Span),
1117    /// Arithmetic sequence: `[1..10]`, `[1,3..10]`
1118    ArithSeq(ArithSeq, Span),
1119    /// List comprehension: `[x | x <- xs, x > 0]`
1120    ListComp(Box<Expr>, Vec<Stmt>, Span),
1121    /// Record construction: `Foo { bar = 1 }` or `Foo { bar = 1, .. }` (RecordWildCards)
1122    RecordCon(Ident, Vec<FieldBind>, bool, Span),
1123    /// Qualified record construction: `M.Foo { bar = 1 }`
1124    QualRecordCon(ModuleName, Ident, Vec<FieldBind>, bool, Span),
1125    /// Record update: `foo { bar = 1 }`
1126    RecordUpd(Box<Expr>, Vec<FieldBind>, Span),
1127    /// Infix operator: `a + b`
1128    Infix(Box<Expr>, Ident, Box<Expr>, Span),
1129    /// Negation: `-x`
1130    Neg(Box<Expr>, Span),
1131    /// Parenthesized expression
1132    Paren(Box<Expr>, Span),
1133    /// Type annotation: `x :: Int`
1134    Ann(Box<Expr>, Type, Span),
1135    /// Explicit type application: `f @Int`
1136    TypeApp(Box<Expr>, Type, Span),
1137    /// Lazy block (H26): `lazy { ... }`
1138    Lazy(Box<Expr>, Span),
1139    /// Wildcard/hole: `_` (used in patterns parsed as expressions)
1140    Wildcard(Span),
1141}
1142
1143impl Expr {
1144    /// Get the span of this expression.
1145    #[must_use]
1146    pub fn span(&self) -> Span {
1147        match self {
1148            Self::Var(_, s)
1149            | Self::QualVar(_, _, s)
1150            | Self::Con(_, s)
1151            | Self::QualCon(_, _, s)
1152            | Self::Lit(_, s)
1153            | Self::App(_, _, s)
1154            | Self::Lam(_, _, s)
1155            | Self::Let(_, _, s)
1156            | Self::If(_, _, _, s)
1157            | Self::Case(_, _, s)
1158            | Self::Do(_, s)
1159            | Self::Tuple(_, s)
1160            | Self::List(_, s)
1161            | Self::ArithSeq(_, s)
1162            | Self::ListComp(_, _, s)
1163            | Self::RecordCon(_, _, _, s)
1164            | Self::QualRecordCon(_, _, _, _, s)
1165            | Self::RecordUpd(_, _, s)
1166            | Self::Infix(_, _, _, s)
1167            | Self::Neg(_, s)
1168            | Self::Paren(_, s)
1169            | Self::Ann(_, _, s)
1170            | Self::TypeApp(_, _, s)
1171            | Self::Lazy(_, s)
1172            | Self::Wildcard(s) => *s,
1173        }
1174    }
1175}
1176
1177/// A literal value.
1178#[derive(Clone, Debug, PartialEq)]
1179pub enum Lit {
1180    /// Integer literal.
1181    Int(i64),
1182    /// Floating-point literal.
1183    Float(f64),
1184    /// Character literal.
1185    Char(char),
1186    /// String literal.
1187    String(String),
1188}
1189
1190/// An arithmetic sequence.
1191#[derive(Clone, Debug)]
1192pub enum ArithSeq {
1193    /// `[from..]`
1194    From(Box<Expr>),
1195    /// `[from, then..]`
1196    FromThen(Box<Expr>, Box<Expr>),
1197    /// `[from..to]`
1198    FromTo(Box<Expr>, Box<Expr>),
1199    /// `[from, then..to]`
1200    FromThenTo(Box<Expr>, Box<Expr>, Box<Expr>),
1201}
1202
1203/// A case alternative.
1204#[derive(Clone, Debug)]
1205pub struct Alt {
1206    /// The pattern.
1207    pub pat: Pat,
1208    /// The right-hand side.
1209    pub rhs: Rhs,
1210    /// Local bindings.
1211    pub wheres: Vec<Decl>,
1212    /// The span.
1213    pub span: Span,
1214}
1215
1216/// A statement in a do block or list comprehension.
1217#[derive(Clone, Debug)]
1218pub enum Stmt {
1219    /// Generator: `x <- xs`
1220    Generator(Pat, Expr, Span),
1221    /// Qualifier/guard: `x > 0`
1222    Qualifier(Expr, Span),
1223    /// Let binding: `let x = 1`
1224    LetStmt(Vec<Decl>, Span),
1225}
1226
1227/// A field binding in a record.
1228#[derive(Clone, Debug)]
1229pub struct FieldBind {
1230    /// Optional module qualifier for disambiguated record fields (e.g., `XMonad.borderWidth`).
1231    pub qualifier: Option<ModuleName>,
1232    /// Field name.
1233    pub name: Ident,
1234    /// Field value (None for punning: `Foo { bar }` means `Foo { bar = bar }`)
1235    pub value: Option<Expr>,
1236    /// The span.
1237    pub span: Span,
1238}
1239
1240/// A pattern.
1241#[derive(Clone, Debug)]
1242pub enum Pat {
1243    /// Wildcard: `_`
1244    Wildcard(Span),
1245    /// Variable: `x`
1246    Var(Ident, Span),
1247    /// Literal: `42`
1248    Lit(Lit, Span),
1249    /// Constructor: `Just x`
1250    Con(Ident, Vec<Pat>, Span),
1251    /// Qualified constructor: `M.Just x`, `Data.Maybe.Nothing`
1252    QualCon(ModuleName, Ident, Vec<Pat>, Span),
1253    /// Infix constructor: `x : xs`
1254    Infix(Box<Pat>, Ident, Box<Pat>, Span),
1255    /// Tuple: `(a, b)`
1256    Tuple(Vec<Pat>, Span),
1257    /// List: `[a, b, c]`
1258    List(Vec<Pat>, Span),
1259    /// Record: `Foo { bar = x }` or `Foo { bar = x, .. }` (RecordWildCards)
1260    Record(Ident, Vec<FieldPat>, bool, Span),
1261    /// Qualified record: `M.Foo { bar = x }` or `M.Foo { .. }` (RecordWildCards)
1262    QualRecord(ModuleName, Ident, Vec<FieldPat>, bool, Span),
1263    /// As-pattern: `xs@(x:_)`
1264    As(Ident, Box<Pat>, Span),
1265    /// Lazy pattern: `~pat`
1266    Lazy(Box<Pat>, Span),
1267    /// Bang pattern: `!pat`
1268    Bang(Box<Pat>, Span),
1269    /// Parenthesized pattern
1270    Paren(Box<Pat>, Span),
1271    /// Type annotation: `x :: Int`
1272    Ann(Box<Pat>, Type, Span),
1273    /// View pattern: `(expr -> pat)` (ViewPatterns extension)
1274    View(Box<Expr>, Box<Pat>, Span),
1275}
1276
1277impl Pat {
1278    /// Get the span of this pattern.
1279    #[must_use]
1280    pub fn span(&self) -> Span {
1281        match self {
1282            Self::Wildcard(s)
1283            | Self::Var(_, s)
1284            | Self::Lit(_, s)
1285            | Self::Con(_, _, s)
1286            | Self::QualCon(_, _, _, s)
1287            | Self::Infix(_, _, _, s)
1288            | Self::Tuple(_, s)
1289            | Self::List(_, s)
1290            | Self::Record(_, _, _, s)
1291            | Self::QualRecord(_, _, _, _, s)
1292            | Self::As(_, _, s)
1293            | Self::Lazy(_, s)
1294            | Self::Bang(_, s)
1295            | Self::Paren(_, s)
1296            | Self::Ann(_, _, s)
1297            | Self::View(_, _, s) => *s,
1298        }
1299    }
1300}
1301
1302/// A field pattern in a record.
1303#[derive(Clone, Debug)]
1304pub struct FieldPat {
1305    /// Optional module qualifier for disambiguated record fields (e.g., `XMonad.modMask`).
1306    pub qualifier: Option<ModuleName>,
1307    /// Field name.
1308    pub name: Ident,
1309    /// Pattern (None for punning).
1310    pub pat: Option<Pat>,
1311    /// The span.
1312    pub span: Span,
1313}
1314
1315/// A type.
1316#[derive(Clone, Debug)]
1317pub enum Type {
1318    /// Type variable: `a`
1319    Var(TyVar, Span),
1320    /// Type constructor: `Int`, `Maybe`
1321    Con(Ident, Span),
1322    /// Qualified type constructor: `M.Map`, `Data.List.Sort`
1323    QualCon(ModuleName, Ident, Span),
1324    /// Application: `Maybe Int`
1325    App(Box<Type>, Box<Type>, Span),
1326    /// Function type: `a -> b`
1327    Fun(Box<Type>, Box<Type>, Span),
1328    /// Tuple type: `(a, b)`
1329    Tuple(Vec<Type>, Span),
1330    /// List type: `[a]`
1331    List(Box<Type>, Span),
1332    /// Parenthesized type
1333    Paren(Box<Type>, Span),
1334    /// Forall type: `forall a. a -> a`
1335    Forall(Vec<TyVar>, Box<Type>, Span),
1336    /// Constrained type: `Eq a => a -> a -> Bool`
1337    Constrained(Vec<Constraint>, Box<Type>, Span),
1338
1339    // === M9 Dependent Types Preview ===
1340    /// Promoted list: `'[1024, 768]` for tensor shapes
1341    PromotedList(Vec<Type>, Span),
1342    /// Type-level natural literal: `1024` in type position
1343    NatLit(u64, Span),
1344
1345    /// Strict type annotation: `!Int` in constructor fields
1346    Bang(Box<Type>, Span),
1347
1348    /// Lazy type annotation: `~Int` in constructor fields
1349    Lazy(Box<Type>, Span),
1350
1351    /// Infix type operator: `a :+: b` (requires TypeOperators)
1352    InfixOp(Box<Type>, Ident, Box<Type>, Span),
1353}
1354
1355impl Type {
1356    /// Get the span of this type.
1357    #[must_use]
1358    pub fn span(&self) -> Span {
1359        match self {
1360            Self::Var(_, s)
1361            | Self::Con(_, s)
1362            | Self::QualCon(_, _, s)
1363            | Self::App(_, _, s)
1364            | Self::Fun(_, _, s)
1365            | Self::Tuple(_, s)
1366            | Self::List(_, s)
1367            | Self::Paren(_, s)
1368            | Self::Forall(_, _, s)
1369            | Self::Constrained(_, _, s)
1370            | Self::PromotedList(_, s)
1371            | Self::NatLit(_, s)
1372            | Self::Bang(_, s)
1373            | Self::Lazy(_, s)
1374            | Self::InfixOp(_, _, _, s) => *s,
1375        }
1376    }
1377}
1378
1379/// A type variable.
1380#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1381pub struct TyVar {
1382    /// The name.
1383    pub name: Ident,
1384    /// The span.
1385    pub span: Span,
1386}
1387
1388/// A type class constraint.
1389#[derive(Clone, Debug)]
1390pub struct Constraint {
1391    /// The class name.
1392    pub class: Ident,
1393    /// The type arguments.
1394    pub args: Vec<Type>,
1395    /// The span.
1396    pub span: Span,
1397}