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}