Skip to main content

bhc_parser/
decl.rs

1//! Declaration parsing.
2
3use bhc_ast::*;
4use bhc_intern::{Ident, Symbol};
5use bhc_lexer::TokenKind;
6use bhc_span::Span;
7
8use crate::{ParseError, ParseResult, Parser};
9
10impl<'src> Parser<'src> {
11    /// Parse a complete module.
12    pub fn parse_module(&mut self) -> ParseResult<Module> {
13        let start = self.current_span();
14
15        // Parse pragmas at the start of the module
16        let pragmas = self.parse_pragmas();
17
18        // Collect doc comments that may appear before the module declaration (Haddock)
19        let doc = self.collect_doc_comments();
20
21        // Skip virtual tokens (VirtualSemi) that the layout rule may insert
22        // between a doc comment and the `module` keyword. The doc comment is
23        // the first real token, so the layout rule's `first_token` guard is
24        // already cleared and a VirtualSemi gets emitted before `module`.
25        self.skip_virtual_tokens();
26
27        // Optional module header
28        let (name, exports) = if self.eat(&TokenKind::Module) {
29            let name = self.parse_module_name()?;
30            // Skip virtual tokens between module name and export list `(` —
31            // when the `(` starts at column 1 the layout rule emits VirtualSemi.
32            self.skip_virtual_tokens();
33            let exports = if self.check(&TokenKind::LParen) {
34                Some(self.parse_export_list()?)
35            } else {
36                None
37            };
38            // Skip virtual tokens that the layout rule may insert between
39            // the export list `)` and `where` when they are on separate lines:
40            //   module Foo ( bar )
41            //   where          -- `where` on its own line
42            self.skip_virtual_tokens();
43            self.expect(&TokenKind::Where)?;
44            (Some(name), exports)
45        } else {
46            (None, None)
47        };
48
49        // Skip virtual brace from layout rule after `where`
50        self.skip_virtual_tokens();
51
52        // Imports
53        let mut imports = Vec::new();
54        while self.check(&TokenKind::Import) {
55            imports.push(self.parse_import()?);
56            // Skip virtual semicolons between imports
57            self.skip_virtual_tokens();
58        }
59
60        // Declarations
61        let mut decls = Vec::new();
62        while !self.at_eof() {
63            // Skip any virtual tokens, pragmas, and explicit semicolons between declarations
64            // Note: We do NOT skip doc comments here, since parse_top_decl collects them
65            self.skip_virtual_tokens();
66            self.skip_standalone_pragmas();
67            while self.eat(&TokenKind::Semi) || self.eat(&TokenKind::VirtualSemi) {
68                self.skip_virtual_tokens();
69                self.skip_standalone_pragmas();
70            }
71            if self.at_eof() {
72                break;
73            }
74
75            match self.parse_top_decl() {
76                Ok(decl) => decls.push(decl),
77                Err(e) => {
78                    // Try to recover
79                    self.emit(e.to_diagnostic(self.file_id));
80                    self.recover_to_next_decl();
81                    if self.at_eof() {
82                        break;
83                    }
84                }
85            }
86        }
87
88        let span = start.to(self.tokens.last().map(|t| t.span).unwrap_or(start));
89
90        // Merge consecutive clauses of the same function
91        let decls = self.merge_function_clauses(decls);
92
93        Ok(Module {
94            doc,
95            pragmas,
96            name,
97            exports,
98            imports,
99            decls,
100            span,
101        })
102    }
103
104    /// Merge consecutive function bindings with the same name into multi-clause functions.
105    ///
106    /// In Haskell, functions can be defined with multiple clauses:
107    /// ```haskell
108    /// fac 0 = 1
109    /// fac n = n * fac (n - 1)
110    /// ```
111    ///
112    /// These are parsed as separate `FunBind` declarations initially,
113    /// and this function merges them into a single `FunBind` with multiple clauses.
114    fn merge_function_clauses(&self, decls: Vec<Decl>) -> Vec<Decl> {
115        let mut result: Vec<Decl> = Vec::new();
116
117        for decl in decls {
118            match decl {
119                Decl::FunBind(mut fun_bind) => {
120                    // Don't merge $patbind declarations - each pattern binding is independent
121                    // (they all have the same synthetic name but are not clauses of the same function)
122                    if fun_bind.name.name.as_str() == "$patbind" {
123                        result.push(Decl::FunBind(fun_bind));
124                        continue;
125                    }
126
127                    // Check if the last declaration is a FunBind with the same name
128                    if let Some(Decl::FunBind(ref mut last)) = result.last_mut() {
129                        if last.name.name == fun_bind.name.name {
130                            // Merge clauses
131                            last.clauses.append(&mut fun_bind.clauses);
132                            // Update span to include all clauses
133                            last.span = last.span.to(fun_bind.span);
134                            continue;
135                        }
136                    }
137                    result.push(Decl::FunBind(fun_bind));
138                }
139                other => result.push(other),
140            }
141        }
142
143        result
144    }
145
146    /// Parse pragmas at the start of a module.
147    ///
148    /// Consumes all consecutive Pragma tokens and parses their contents.
149    /// Skips virtual tokens (VirtualSemi) between pragmas.
150    fn parse_pragmas(&mut self) -> Vec<Pragma> {
151        let mut pragmas = Vec::new();
152
153        loop {
154            // Skip virtual tokens between pragmas
155            while let Some(kind) = self.current_kind() {
156                if kind.is_virtual() {
157                    self.advance();
158                } else {
159                    break;
160                }
161            }
162
163            if let Some(tok) = self.current() {
164                if let TokenKind::Pragma(content) = &tok.node.kind {
165                    let span = tok.span;
166                    let content = content.clone();
167                    self.advance();
168
169                    if let Some(pragma) = self.parse_pragma_content(&content, span) {
170                        pragmas.push(pragma);
171                    }
172                    continue;
173                }
174            }
175            break;
176        }
177
178        pragmas
179    }
180
181    /// Parse the content of a pragma.
182    ///
183    /// The content is the text between `{-#` and `#-}`, e.g., `"LANGUAGE GADTs, TypeFamilies"`.
184    fn parse_pragma_content(&self, content: &str, span: Span) -> Option<Pragma> {
185        let content = content.trim();
186        if content.is_empty() {
187            return None;
188        }
189
190        // Split into pragma name and arguments
191        let mut parts = content.splitn(2, char::is_whitespace);
192        let pragma_name = parts.next()?.to_uppercase();
193        let args = parts.next().unwrap_or("").trim();
194
195        let kind = match pragma_name.as_str() {
196            "LANGUAGE" => {
197                // Parse comma-separated extension names
198                let extensions: Vec<Symbol> = args
199                    .split(',')
200                    .map(|s| Symbol::intern(s.trim()))
201                    .filter(|s| !s.as_str().is_empty())
202                    .collect();
203                PragmaKind::Language(extensions)
204            }
205            "OPTIONS_GHC" | "OPTIONS" => PragmaKind::OptionsGhc(args.to_string()),
206            "INLINE" => {
207                if let Some(name) = args.split_whitespace().next() {
208                    PragmaKind::Inline(Ident::new(Symbol::intern(name)))
209                } else {
210                    PragmaKind::Other(content.to_string())
211                }
212            }
213            "NOINLINE" | "NOTINLINE" => {
214                if let Some(name) = args.split_whitespace().next() {
215                    PragmaKind::NoInline(Ident::new(Symbol::intern(name)))
216                } else {
217                    PragmaKind::Other(content.to_string())
218                }
219            }
220            "INLINABLE" | "INLINEABLE" => {
221                if let Some(name) = args.split_whitespace().next() {
222                    PragmaKind::Inlinable(Ident::new(Symbol::intern(name)))
223                } else {
224                    PragmaKind::Other(content.to_string())
225                }
226            }
227            "UNPACK" => PragmaKind::Unpack,
228            "NOUNPACK" => PragmaKind::NoUnpack,
229            "SOURCE" => PragmaKind::Source,
230            "COMPLETE" => {
231                let names: Vec<Ident> = args
232                    .split(',')
233                    .map(|s| s.trim())
234                    .filter(|s| !s.is_empty())
235                    .map(|s| Ident::new(Symbol::intern(s)))
236                    .collect();
237                PragmaKind::Complete(names)
238            }
239            "MINIMAL" => PragmaKind::Minimal(args.to_string()),
240            "DEPRECATED" => {
241                // Simple parsing: everything after DEPRECATED is the message
242                // More sophisticated parsing would extract specific names
243                PragmaKind::Deprecated(None, args.to_string())
244            }
245            "WARNING" => PragmaKind::Warning(None, args.to_string()),
246            "SPECIALIZE" | "SPECIALISE" => {
247                // For now, store as Other since we'd need to parse the type signature
248                PragmaKind::Other(content.to_string())
249            }
250            _ => PragmaKind::Other(content.to_string()),
251        };
252
253        Some(Pragma { kind, span })
254    }
255
256    /// Skip standalone pragmas that can appear between declarations.
257    /// This includes INLINE, NOINLINE, DEPRECATED, WARNING, SPECIALISE, etc.
258    fn skip_standalone_pragmas(&mut self) {
259        while let Some(TokenKind::Pragma(_)) = self.current_kind() {
260            self.advance();
261        }
262    }
263
264    /// Parse a module name.
265    fn parse_module_name(&mut self) -> ParseResult<ModuleName> {
266        let start = self.current_span();
267        let mut parts = Vec::new();
268
269        let tok = self.current().ok_or(ParseError::UnexpectedEof {
270            expected: "module name".to_string(),
271        })?;
272
273        match &tok.node.kind {
274            // Simple module name: Foo
275            TokenKind::ConId(sym) => {
276                parts.push(*sym);
277                self.advance();
278
279                // Check for dot continuation (for manual A.B.C parsing)
280                while let Some(next) = self.current() {
281                    if matches!(&next.node.kind, TokenKind::Operator(s) if s.as_str() == ".") {
282                        self.advance();
283                        // Expect another ConId
284                        if let Some(tok) = self.current() {
285                            if let TokenKind::ConId(sym) = &tok.node.kind {
286                                parts.push(*sym);
287                                self.advance();
288                            } else {
289                                break;
290                            }
291                        } else {
292                            break;
293                        }
294                    } else {
295                        break;
296                    }
297                }
298            }
299            // Qualified module name: Data.List (lexer produces this as single token)
300            TokenKind::QualConId(qualifier, name) => {
301                // Split qualifier on dots and add parts
302                for part in qualifier.as_str().split('.') {
303                    parts.push(Symbol::intern(part));
304                }
305                parts.push(*name);
306                self.advance();
307            }
308            _ => {
309                return Err(ParseError::Unexpected {
310                    found: tok.node.kind.description().to_string(),
311                    expected: "module name".to_string(),
312                    span: tok.span,
313                });
314            }
315        }
316
317        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
318        Ok(ModuleName { parts, span })
319    }
320
321    /// Parse an export list.
322    fn parse_export_list(&mut self) -> ParseResult<Vec<Export>> {
323        self.expect(&TokenKind::LParen)?;
324        let mut exports = Vec::new();
325
326        // Skip any doc comments at the start of the export list
327        self.skip_doc_comments();
328
329        if !self.check(&TokenKind::RParen) {
330            exports.push(self.parse_export()?);
331            while self.eat(&TokenKind::Comma) {
332                // Skip doc comments between export items (Haddock section headers)
333                self.skip_doc_comments();
334                if self.check(&TokenKind::RParen) {
335                    break;
336                }
337                exports.push(self.parse_export()?);
338            }
339        }
340
341        self.expect(&TokenKind::RParen)?;
342        Ok(exports)
343    }
344
345    /// Parse a single export item.
346    fn parse_export(&mut self) -> ParseResult<Export> {
347        let start = self.current_span();
348
349        if self.eat(&TokenKind::Module) {
350            let name = self.parse_module_name()?;
351            let span = start.to(name.span);
352            return Ok(Export::Module(name, span));
353        }
354
355        // Check for `pattern` prefix (context-sensitive keyword for pattern synonym exports)
356        if self.check_ident_str("pattern") {
357            let pat_start = self.current_span();
358            self.advance(); // consume `pattern`
359            let tok = self.current().ok_or(ParseError::UnexpectedEof {
360                expected: "pattern synonym name".to_string(),
361            })?;
362            if let TokenKind::ConId(sym) = &tok.node.kind {
363                let ident = Ident::new(*sym);
364                let span = pat_start.to(tok.span);
365                self.advance();
366                return Ok(Export::Pattern(ident, span));
367            }
368            return Err(ParseError::Unexpected {
369                found: tok.node.kind.description().to_string(),
370                expected: "pattern synonym name (constructor)".to_string(),
371                span: tok.span,
372            });
373        }
374
375        let tok = self.current().ok_or(ParseError::UnexpectedEof {
376            expected: "export item".to_string(),
377        })?;
378
379        match &tok.node.kind.clone() {
380            TokenKind::Ident(sym) => {
381                let ident = Ident::new(*sym);
382                let span = tok.span;
383                self.advance();
384                Ok(Export::Var(ident, span))
385            }
386            TokenKind::ConId(sym) => {
387                let ident = Ident::new(*sym);
388                self.advance();
389
390                let constrs = if self.check(&TokenKind::LParen) {
391                    Some(self.parse_subspec()?)
392                } else {
393                    None
394                };
395
396                let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
397                Ok(Export::Type(ident, constrs, span))
398            }
399            // Handle operators in parentheses: module Foo ((+), (.), (!)) where
400            TokenKind::LParen => {
401                self.advance(); // consume (
402
403                // Expect an operator
404                let op_tok = self.current().ok_or(ParseError::UnexpectedEof {
405                    expected: "operator".to_string(),
406                })?;
407
408                let ident = match &op_tok.node.kind {
409                    TokenKind::Operator(sym) => Ident::new(*sym),
410                    TokenKind::ConOperator(sym) => Ident::new(*sym),
411                    // Special tokens that are valid operators when in parentheses
412                    TokenKind::Dot => Ident::new(Symbol::intern(".")),
413                    TokenKind::Bang => Ident::new(Symbol::intern("!")),
414                    TokenKind::At => Ident::new(Symbol::intern("@")),
415                    TokenKind::Tilde => Ident::new(Symbol::intern("~")),
416                    _ => {
417                        return Err(ParseError::Unexpected {
418                            found: op_tok.node.kind.description().to_string(),
419                            expected: "operator".to_string(),
420                            span: op_tok.span,
421                        });
422                    }
423                };
424                self.advance();
425
426                let end = self.expect(&TokenKind::RParen)?;
427                let span = start.to(end.span);
428                Ok(Export::Var(ident, span))
429            }
430            _ => Err(ParseError::Unexpected {
431                found: tok.node.kind.description().to_string(),
432                expected: "export item".to_string(),
433                span: tok.span,
434            }),
435        }
436    }
437
438    /// Parse a subspecification like `(..)` or `(A, B)`.
439    fn parse_subspec(&mut self) -> ParseResult<Vec<Ident>> {
440        self.expect(&TokenKind::LParen)?;
441
442        if self.eat(&TokenKind::DotDot) {
443            self.expect(&TokenKind::RParen)?;
444            return Ok(vec![]); // (..) means all
445        }
446
447        let mut names = Vec::new();
448        if !self.check(&TokenKind::RParen) {
449            names.push(self.parse_ident_or_con()?);
450            while self.eat(&TokenKind::Comma) {
451                if self.check(&TokenKind::RParen) {
452                    break;
453                }
454                names.push(self.parse_ident_or_con()?);
455            }
456        }
457
458        self.expect(&TokenKind::RParen)?;
459        Ok(names)
460    }
461
462    /// Parse an identifier or constructor.
463    /// Also handles operators in parentheses like `(:|)` or `(++)`.
464    fn parse_ident_or_con(&mut self) -> ParseResult<Ident> {
465        let tok = self.current().ok_or(ParseError::UnexpectedEof {
466            expected: "identifier".to_string(),
467        })?;
468
469        match &tok.node.kind {
470            TokenKind::Ident(sym) | TokenKind::ConId(sym) => {
471                let ident = Ident::new(*sym);
472                self.advance();
473                Ok(ident)
474            }
475            // Handle operators in parentheses: (:|), (++)
476            TokenKind::LParen => {
477                self.advance(); // consume (
478                let op_tok = self.current().ok_or(ParseError::UnexpectedEof {
479                    expected: "operator".to_string(),
480                })?;
481
482                let ident = match &op_tok.node.kind {
483                    TokenKind::Operator(sym) | TokenKind::ConOperator(sym) => Ident::new(*sym),
484                    _ => {
485                        return Err(ParseError::Unexpected {
486                            found: op_tok.node.kind.description().to_string(),
487                            expected: "operator".to_string(),
488                            span: op_tok.span,
489                        });
490                    }
491                };
492                self.advance();
493                self.expect(&TokenKind::RParen)?;
494                Ok(ident)
495            }
496            _ => Err(ParseError::Unexpected {
497                found: tok.node.kind.description().to_string(),
498                expected: "identifier".to_string(),
499                span: tok.span,
500            }),
501        }
502    }
503
504    /// Parse an import declaration.
505    pub fn parse_import(&mut self) -> ParseResult<ImportDecl> {
506        let start = self.current_span();
507        self.expect(&TokenKind::Import)?;
508
509        let qualified = self.eat(&TokenKind::Qualified);
510        let module = self.parse_module_name()?;
511
512        // Check for "as Alias" - 'as' is a context-sensitive keyword
513        let alias = if self.eat_ident_str("as") {
514            Some(self.parse_module_name()?)
515        } else {
516            None
517        };
518
519        let spec = self.parse_import_spec()?;
520        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
521
522        Ok(ImportDecl {
523            module,
524            qualified,
525            alias,
526            spec,
527            span,
528        })
529    }
530
531    /// Parse an import specification.
532    fn parse_import_spec(&mut self) -> ParseResult<Option<ImportSpec>> {
533        // Check for "hiding"
534        if self.eat(&TokenKind::Hiding) {
535            let imports = self.parse_import_list()?;
536            return Ok(Some(ImportSpec::Hiding(imports)));
537        }
538
539        if self.check(&TokenKind::LParen) {
540            let imports = self.parse_import_list()?;
541            return Ok(Some(ImportSpec::Only(imports)));
542        }
543
544        Ok(None)
545    }
546
547    /// Parse an import list.
548    fn parse_import_list(&mut self) -> ParseResult<Vec<Import>> {
549        self.expect(&TokenKind::LParen)?;
550        let mut imports = Vec::new();
551
552        if !self.check(&TokenKind::RParen) {
553            imports.push(self.parse_import_item()?);
554            while self.eat(&TokenKind::Comma) {
555                if self.check(&TokenKind::RParen) {
556                    break;
557                }
558                imports.push(self.parse_import_item()?);
559            }
560        }
561
562        self.expect(&TokenKind::RParen)?;
563        Ok(imports)
564    }
565
566    /// Parse a single import item.
567    fn parse_import_item(&mut self) -> ParseResult<Import> {
568        // Check for `pattern` prefix (context-sensitive keyword for pattern synonym imports)
569        if self.check_ident_str("pattern") {
570            let start = self.current_span();
571            self.advance(); // consume `pattern`
572            let tok = self.current().ok_or(ParseError::UnexpectedEof {
573                expected: "pattern synonym name".to_string(),
574            })?;
575            if let TokenKind::ConId(sym) = &tok.node.kind {
576                let ident = Ident::new(*sym);
577                let span = start.to(tok.span);
578                self.advance();
579                return Ok(Import::Pattern(ident, span));
580            }
581            return Err(ParseError::Unexpected {
582                found: tok.node.kind.description().to_string(),
583                expected: "pattern synonym name (constructor)".to_string(),
584                span: tok.span,
585            });
586        }
587
588        let tok = self.current().ok_or(ParseError::UnexpectedEof {
589            expected: "import item".to_string(),
590        })?;
591
592        match &tok.node.kind.clone() {
593            TokenKind::Ident(sym) => {
594                let ident = Ident::new(*sym);
595                let span = tok.span;
596                self.advance();
597                Ok(Import::Var(ident, span))
598            }
599            TokenKind::ConId(sym) => {
600                let ident = Ident::new(*sym);
601                let start = tok.span;
602                self.advance();
603
604                let constrs = if self.check(&TokenKind::LParen) {
605                    Some(self.parse_subspec()?)
606                } else {
607                    None
608                };
609
610                let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
611                Ok(Import::Type(ident, constrs, span))
612            }
613            // Handle operators in parentheses: import Data.Bits ((.|.))
614            TokenKind::LParen => {
615                let start = tok.span;
616                self.advance(); // consume (
617
618                // Expect an operator
619                let op_tok = self.current().ok_or(ParseError::UnexpectedEof {
620                    expected: "operator".to_string(),
621                })?;
622
623                let ident = match &op_tok.node.kind {
624                    TokenKind::Operator(sym) => Ident::new(*sym),
625                    TokenKind::ConOperator(sym) => Ident::new(*sym),
626                    // Special tokens that are valid operators when in parentheses
627                    TokenKind::Dot => Ident::new(Symbol::intern(".")),
628                    TokenKind::Bang => Ident::new(Symbol::intern("!")),
629                    TokenKind::At => Ident::new(Symbol::intern("@")),
630                    TokenKind::Tilde => Ident::new(Symbol::intern("~")),
631                    _ => {
632                        return Err(ParseError::Unexpected {
633                            found: op_tok.node.kind.description().to_string(),
634                            expected: "operator".to_string(),
635                            span: op_tok.span,
636                        });
637                    }
638                };
639                self.advance();
640
641                let end = self.expect(&TokenKind::RParen)?;
642                let span = start.to(end.span);
643                Ok(Import::Var(ident, span))
644            }
645            _ => Err(ParseError::Unexpected {
646                found: tok.node.kind.description().to_string(),
647                expected: "import item".to_string(),
648                span: tok.span,
649            }),
650        }
651    }
652
653    /// Parse a top-level declaration.
654    fn parse_top_decl(&mut self) -> ParseResult<Decl> {
655        // Collect Haddock documentation comments before declarations
656        let doc = self.collect_doc_comments();
657
658        // After doc comments, there may be a VirtualSemi if the next token
659        // is at the same indentation level. Skip it.
660        self.eat(&TokenKind::VirtualSemi);
661
662        let tok = self.current().ok_or(ParseError::UnexpectedEof {
663            expected: "declaration".to_string(),
664        })?;
665
666        match &tok.node.kind {
667            TokenKind::Data => self.parse_data_decl_with_doc(doc),
668            TokenKind::Type => self.parse_type_decl_with_doc(doc),
669            TokenKind::Newtype => self.parse_newtype_decl_with_doc(doc),
670            TokenKind::Class => self.parse_class_decl_with_doc(doc),
671            TokenKind::Instance => self.parse_instance_decl_with_doc(doc),
672            TokenKind::Foreign => self.parse_foreign_decl_with_doc(doc),
673            TokenKind::Infix | TokenKind::Infixl | TokenKind::Infixr => self.parse_fixity_decl(),
674            TokenKind::Deriving => self.parse_standalone_deriving(),
675            TokenKind::Ident(sym) if sym.as_str() == "pattern" => self.parse_pattern_synonym(),
676            TokenKind::Ident(_) => {
677                // Could be type signature or binding
678                self.parse_value_decl_with_doc(doc)
679            }
680            TokenKind::LParen => {
681                // Operator type signature or binding: (<+>) :: ... or (<+>) = ...
682                self.parse_value_decl_with_doc(doc)
683            }
684            _ => Err(ParseError::Unexpected {
685                found: tok.node.kind.description().to_string(),
686                expected: "declaration".to_string(),
687                span: tok.span,
688            }),
689        }
690    }
691
692    /// Parse local declarations (in let or where).
693    pub fn parse_local_decls(&mut self) -> ParseResult<Vec<Decl>> {
694        let mut decls = Vec::new();
695
696        if self.eat(&TokenKind::LBrace) {
697            // Explicit braces
698            if !self.check(&TokenKind::RBrace) {
699                decls.push(self.parse_value_decl()?);
700                while self.eat(&TokenKind::Semi) {
701                    if self.check(&TokenKind::RBrace) {
702                        break;
703                    }
704                    decls.push(self.parse_value_decl()?);
705                }
706            }
707            self.expect(&TokenKind::RBrace)?;
708        } else if self.eat(&TokenKind::VirtualLBrace) {
709            // Layout-based declarations (implicit braces)
710            // Note: `in` can also end a let-block (e.g., `let x = 1 in ...`)
711            if !self.check(&TokenKind::VirtualRBrace) && !self.check(&TokenKind::In) {
712                decls.push(self.parse_value_decl()?);
713                while self.eat(&TokenKind::VirtualSemi) {
714                    if self.check(&TokenKind::VirtualRBrace) || self.check(&TokenKind::In) {
715                        break;
716                    }
717                    decls.push(self.parse_value_decl()?);
718                }
719            }
720            // Accept either VirtualRBrace or implicitly end on `in`
721            if !self.eat(&TokenKind::VirtualRBrace) && !self.check(&TokenKind::In) {
722                // If neither, report error expecting VirtualRBrace
723                return Err(ParseError::Unexpected {
724                    found: self
725                        .current()
726                        .map(|t| t.node.kind.description().to_string())
727                        .unwrap_or("end of file".to_string()),
728                    expected: "layout `}`".to_string(),
729                    span: self.current_span(),
730                });
731            }
732        } else {
733            // Single declaration (no braces)
734            decls.push(self.parse_value_decl()?);
735        }
736
737        // Merge multi-clause functions in local declarations too
738        Ok(self.merge_function_clauses(decls))
739    }
740
741    /// Parse a value declaration (type signature or binding).
742    fn parse_value_decl(&mut self) -> ParseResult<Decl> {
743        // Collect Haddock documentation comments before value declarations
744        let doc = self.collect_doc_comments();
745        self.parse_value_decl_with_doc(doc)
746    }
747
748    /// Parse a value declaration with an optional doc comment.
749    fn parse_value_decl_with_doc(&mut self, doc: Option<DocComment>) -> ParseResult<Decl> {
750        // After doc comments, there may be a VirtualSemi if the next token
751        // is at the same indentation level. Skip it.
752        self.eat(&TokenKind::VirtualSemi);
753
754        // Handle pragmas in class/instance bodies (like {-# MINIMAL initialValue #-})
755        if let Some(TokenKind::Pragma(content)) = self.current_kind() {
756            let content = content.clone();
757            let span = self.current_span();
758            self.advance();
759            if let Some(pragma) = self.parse_pragma_content(&content, span) {
760                return Ok(Decl::PragmaDecl(pragma));
761            }
762            // If we couldn't parse the pragma content, return an empty pragma
763            return Ok(Decl::PragmaDecl(Pragma {
764                kind: PragmaKind::Other(content),
765                span,
766            }));
767        }
768
769        let start = self.current_span();
770
771        // Check for pattern binding: `(a, b) = expr` or `!pat = expr` or `~pat = expr`
772        // These start with a pattern, not a function name.
773        // A pattern binding is `(pat, ...) = expr` where the paren contains patterns, not an operator.
774        // To distinguish from `(<+>) = ...`, check if the token after `(` is NOT an operator.
775        if self.check(&TokenKind::LParen) {
776            // Peek ahead: is this (operator) or (pattern)?
777            if let Some(next) = self.peek_nth(1) {
778                let is_pattern_start = matches!(
779                    next.node.kind,
780                    TokenKind::Ident(_)
781                        | TokenKind::ConId(_)
782                        | TokenKind::Underscore
783                        | TokenKind::IntLit(_)
784                        | TokenKind::CharLit(_)
785                        | TokenKind::StringLit(_)
786                        | TokenKind::LParen
787                        | TokenKind::LBracket
788                        | TokenKind::Bang
789                        | TokenKind::Tilde
790                );
791                if is_pattern_start {
792                    // This is a pattern binding like (a, b) = expr
793                    return self.parse_pattern_binding(start);
794                }
795            }
796        }
797        // Also handle bang patterns and lazy patterns at top level: !pat = ... or ~pat = ...
798        if self.check(&TokenKind::Bang) || self.check(&TokenKind::Tilde) {
799            return self.parse_pattern_binding(start);
800        }
801
802        // Handle declarations starting with a constructor:
803        // This could be an infix operator definition like `Box f <*> Box x = Box (f x)`
804        // (i.e., `pat varop pat = rhs`) or a pattern binding like `Box x = expr`.
805        // The constructor may be qualified: `D.ReferenceMap autos = ...`.
806        if matches!(
807            self.current_kind(),
808            Some(TokenKind::ConId(_) | TokenKind::QualConId(_, _))
809        ) {
810            let saved_pos = self.pos;
811            // Try parsing a pattern (e.g., `Box f`)
812            if let Ok(left_pat) = self.parse_pattern() {
813                if self.is_infix_var_op_start() {
814                    // This is an infix operator definition: pat varop pat = rhs
815                    let op_name = self.parse_infix_op()?;
816                    let right_pat = self.parse_pattern()?;
817
818                    let mut extra_pats = Vec::new();
819                    while self.is_apat_start() {
820                        extra_pats.push(self.parse_atom_pattern()?);
821                    }
822
823                    let rhs = self.parse_binding_rhs()?;
824
825                    let wheres = if self.eat(&TokenKind::Where) {
826                        self.parse_local_decls()?
827                    } else {
828                        vec![]
829                    };
830
831                    let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
832
833                    let mut pats = vec![left_pat, right_pat];
834                    pats.extend(extra_pats);
835
836                    let clause = Clause {
837                        pats,
838                        rhs,
839                        wheres,
840                        span,
841                    };
842
843                    return Ok(Decl::FunBind(FunBind {
844                        doc: doc.clone(),
845                        name: op_name,
846                        clauses: vec![clause],
847                        span,
848                    }));
849                } else if self.check(&TokenKind::Eq) {
850                    // Pattern binding: `ConPat = expr`
851                    self.expect(&TokenKind::Eq)?;
852                    let expr = self.parse_expr()?;
853
854                    let wheres = if self.eat(&TokenKind::Where) {
855                        self.parse_local_decls()?
856                    } else {
857                        vec![]
858                    };
859
860                    let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
861
862                    let clause = Clause {
863                        pats: vec![left_pat],
864                        rhs: Rhs::Simple(expr, span),
865                        wheres,
866                        span,
867                    };
868
869                    return Ok(Decl::FunBind(FunBind {
870                        doc: doc.clone(),
871                        name: Ident::from_str("$patbind"),
872                        clauses: vec![clause],
873                        span,
874                    }));
875                } else {
876                    // Not an infix definition or pattern binding, backtrack
877                    self.pos = saved_pos;
878                }
879            } else {
880                // Pattern parse failed, backtrack
881                self.pos = saved_pos;
882            }
883        }
884
885        // Parse either a regular identifier or a parenthesized operator like (<+>)
886        let name = self.parse_var_or_op()?;
887
888        // Check for multi-name type signature: `a, b, c :: Type`
889        if self.check(&TokenKind::Comma) || self.check(&TokenKind::DoubleColon) {
890            // Collect all names for a potential type signature
891            let mut names = vec![name];
892            while self.eat(&TokenKind::Comma) {
893                names.push(self.parse_var_or_op()?);
894            }
895
896            if self.eat(&TokenKind::DoubleColon) {
897                // Type signature
898                let ty = self.parse_type()?;
899                let span = start.to(ty.span());
900                return Ok(Decl::TypeSig(TypeSig {
901                    doc,
902                    names,
903                    ty,
904                    span,
905                }));
906            } else if names.len() > 1 {
907                // We parsed multiple names but no ::, this is an error
908                let tok = self.current().unwrap();
909                return Err(ParseError::Unexpected {
910                    found: tok.node.kind.description().to_string(),
911                    expected: "`::`".to_string(),
912                    span: tok.span,
913                });
914            }
915            // Single name, no ::, fall through to function binding
916        }
917
918        // Function binding - if we get here, we have a single name (stored in `name`)
919        {
920            // Function binding - could be prefix or infix
921            let mut pats = Vec::new();
922
923            // Check for infix binding: `x `op` y = ...` or `x --> y = ...`
924            // BUT: if the operator is a constructor (starts with :), this is a pattern binding
925            // e.g., `cur :| visi = expr` is a pattern binding, not a function definition
926            let (actual_name, _is_infix) = if self.is_infix_con_op_start() {
927                // Constructor operator: this is actually a pattern binding like `x :| xs = expr`
928                // Rewind and parse as pattern binding
929                let pat_start = start;
930                // Build the infix pattern: name op pat
931                let left_pat = Pat::Var(name, start);
932                let op = self.parse_infix_op()?;
933                let right_pat = self.parse_pattern()?;
934                let pat_span = pat_start.to(right_pat.span());
935                let full_pat = Pat::Infix(Box::new(left_pat), op, Box::new(right_pat), pat_span);
936
937                // Parse `= expr`
938                self.expect(&TokenKind::Eq)?;
939                let expr = self.parse_expr()?;
940
941                // Parse optional where clause
942                let wheres = if self.eat(&TokenKind::Where) {
943                    self.parse_local_decls()?
944                } else {
945                    vec![]
946                };
947
948                let span = pat_start.to(self.tokens[self.pos.saturating_sub(1)].span);
949
950                // Represent as pattern binding with $patbind
951                let clause = Clause {
952                    pats: vec![full_pat],
953                    rhs: Rhs::Simple(expr, span),
954                    wheres,
955                    span,
956                };
957
958                return Ok(Decl::FunBind(FunBind {
959                    doc: doc.clone(),
960                    name: Ident::from_str("$patbind"),
961                    clauses: vec![clause],
962                    span,
963                }));
964            } else if self.is_infix_var_op_start() {
965                // Variable operator: this is an infix function binding like `x --> y = ...`
966                let first_pat = Pat::Var(name, start);
967                let op_name = self.parse_infix_op()?;
968                let second_pat = self.parse_pattern()?;
969                pats.push(first_pat);
970                pats.push(second_pat);
971                (op_name, true)
972            } else {
973                // Prefix: parse atomic patterns for function arguments
974                // (in Haskell, function LHS uses apat, not full patterns)
975                while self.is_apat_start() {
976                    pats.push(self.parse_atom_pattern()?);
977                }
978                (name, false)
979            };
980
981            // Parse RHS: either `= expr` or guarded: `| guard = expr`
982            let rhs = self.parse_binding_rhs()?;
983
984            // Parse optional where clause
985            let wheres = if self.eat(&TokenKind::Where) {
986                self.parse_local_decls()?
987            } else {
988                vec![]
989            };
990
991            let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
992
993            let clause = Clause {
994                pats,
995                rhs,
996                wheres,
997                span,
998            };
999
1000            Ok(Decl::FunBind(FunBind {
1001                doc,
1002                name: actual_name,
1003                clauses: vec![clause],
1004                span,
1005            }))
1006        }
1007    }
1008
1009    /// Parse a pattern binding: `(a, b) = expr` or `!pat = expr`
1010    /// These are bindings where the LHS is a pattern, not a function name.
1011    fn parse_pattern_binding(&mut self, start: Span) -> ParseResult<Decl> {
1012        // Parse the pattern
1013        let pat = self.parse_pattern()?;
1014
1015        // Expect `=`
1016        self.expect(&TokenKind::Eq)?;
1017
1018        // Parse the expression
1019        let expr = self.parse_expr()?;
1020
1021        // Parse optional where clause
1022        let wheres = if self.eat(&TokenKind::Where) {
1023            self.parse_local_decls()?
1024        } else {
1025            vec![]
1026        };
1027
1028        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
1029
1030        // Represent pattern binding as FunBind with a generated name
1031        // and the pattern as the first clause's single pattern.
1032        // This is a common representation that allows uniform handling.
1033        let clause = Clause {
1034            pats: vec![pat],
1035            rhs: Rhs::Simple(expr, span),
1036            wheres,
1037            span,
1038        };
1039
1040        // Use a special name to indicate this is a pattern binding
1041        // The generated name `$patbind` is not a valid Haskell identifier
1042        // so it won't conflict with user-defined names.
1043        Ok(Decl::FunBind(FunBind {
1044            doc: None, // Pattern bindings don't have documentation
1045            name: Ident::from_str("$patbind"),
1046            clauses: vec![clause],
1047            span,
1048        }))
1049    }
1050
1051    /// Parse the right-hand side of a binding: either `= expr` or guarded `| guard = expr`.
1052    fn parse_binding_rhs(&mut self) -> ParseResult<Rhs> {
1053        let start = self.current_span();
1054
1055        if self.check(&TokenKind::Pipe) {
1056            // Guarded RHS: `| guard = expr`
1057            let guards = self.parse_guarded_binding_rhss()?;
1058            let end_span = guards.last().map(|g| g.span).unwrap_or(start);
1059            Ok(Rhs::Guarded(guards, start.to(end_span)))
1060        } else {
1061            // Simple RHS: `= expr`
1062            self.expect(&TokenKind::Eq)?;
1063            let expr = self.parse_expr()?;
1064            let span = start.to(expr.span());
1065            Ok(Rhs::Simple(expr, span))
1066        }
1067    }
1068
1069    /// Parse guarded right-hand sides for bindings: `| guard = expr | guard = expr ...`
1070    fn parse_guarded_binding_rhss(&mut self) -> ParseResult<Vec<GuardedRhs>> {
1071        let mut guarded_rhss = Vec::new();
1072        while self.eat(&TokenKind::Pipe) {
1073            let guard_start = self.current_span();
1074            let guards = self.parse_guards()?;
1075            self.expect(&TokenKind::Eq)?;
1076            let body = self.parse_expr()?;
1077            let span = guard_start.to(body.span());
1078            guarded_rhss.push(GuardedRhs { guards, body, span });
1079        }
1080        Ok(guarded_rhss)
1081    }
1082
1083    /// Parse guards: `guard1, guard2, ...` where each guard is either:
1084    /// - A pattern guard: `pat <- expr`
1085    /// - A boolean guard: `expr`
1086    fn parse_guards(&mut self) -> ParseResult<Vec<Guard>> {
1087        let mut guards = Vec::new();
1088        guards.push(self.parse_single_guard()?);
1089        while self.eat(&TokenKind::Comma) {
1090            guards.push(self.parse_single_guard()?);
1091        }
1092        Ok(guards)
1093    }
1094
1095    /// Parse a single guard.
1096    fn parse_single_guard(&mut self) -> ParseResult<Guard> {
1097        let start = self.current_span();
1098
1099        // Try to parse as pattern guard first by looking ahead
1100        // Pattern guards have the form: pat <- expr
1101        // We need to check if there's a `<-` ahead
1102
1103        // Save position for backtracking
1104        let saved_pos = self.pos;
1105
1106        // Try parsing as pattern
1107        if let Ok(pat) = self.parse_pattern() {
1108            if self.eat(&TokenKind::LeftArrow) {
1109                // This is a pattern guard
1110                let expr = self.parse_expr()?;
1111                let span = start.to(expr.span());
1112                return Ok(Guard::Pattern(pat, expr, span));
1113            }
1114            // Not a pattern guard, backtrack
1115            self.pos = saved_pos;
1116        } else {
1117            // Couldn't parse as pattern, reset position
1118            self.pos = saved_pos;
1119        }
1120
1121        // Parse as boolean guard
1122        let expr = self.parse_expr()?;
1123        let span = start.to(expr.span());
1124        Ok(Guard::Expr(expr, span))
1125    }
1126
1127    /// Check if the current token starts an infix operator for bindings.
1128    /// This includes operators like `-->` and backtick-quoted identifiers like `` `elem` ``.
1129    #[allow(dead_code)]
1130    fn is_infix_op_start(&self) -> bool {
1131        matches!(
1132            self.current_kind(),
1133            Some(TokenKind::Operator(_) | TokenKind::ConOperator(_) | TokenKind::Backtick)
1134        )
1135    }
1136
1137    /// Check if the current token starts a constructor operator (starts with `:`)
1138    /// This indicates a pattern binding like `x :| xs = expr`
1139    fn is_infix_con_op_start(&self) -> bool {
1140        matches!(self.current_kind(), Some(TokenKind::ConOperator(_)))
1141    }
1142
1143    /// Check if the current token starts a variable operator (doesn't start with `:`)
1144    /// This indicates an infix function binding like `x --> y = expr`
1145    fn is_infix_var_op_start(&self) -> bool {
1146        matches!(
1147            self.current_kind(),
1148            Some(TokenKind::Operator(_) | TokenKind::Backtick)
1149        )
1150    }
1151
1152    /// Parse an infix operator for bindings.
1153    /// Handles `-->` style operators and `` `foo` `` backtick-quoted identifiers.
1154    fn parse_infix_op(&mut self) -> ParseResult<Ident> {
1155        if self.eat(&TokenKind::Backtick) {
1156            // Backtick-quoted identifier: `foo`
1157            let ident = self.parse_ident()?;
1158            self.expect(&TokenKind::Backtick)?;
1159            Ok(ident)
1160        } else {
1161            // Regular operator
1162            let tok = self.current().ok_or(ParseError::UnexpectedEof {
1163                expected: "operator".to_string(),
1164            })?;
1165
1166            match &tok.node.kind {
1167                TokenKind::Operator(sym) | TokenKind::ConOperator(sym) => {
1168                    let ident = Ident::new(*sym);
1169                    self.advance();
1170                    Ok(ident)
1171                }
1172                _ => Err(ParseError::Unexpected {
1173                    found: tok.node.kind.description().to_string(),
1174                    expected: "operator".to_string(),
1175                    span: tok.span,
1176                }),
1177            }
1178        }
1179    }
1180
1181    /// Parse an identifier.
1182    fn parse_ident(&mut self) -> ParseResult<Ident> {
1183        let tok = self.current().ok_or(ParseError::UnexpectedEof {
1184            expected: "identifier".to_string(),
1185        })?;
1186
1187        match &tok.node.kind {
1188            TokenKind::Ident(sym) => {
1189                let ident = Ident::new(*sym);
1190                self.advance();
1191                Ok(ident)
1192            }
1193            _ => Err(ParseError::Unexpected {
1194                found: tok.node.kind.description().to_string(),
1195                expected: "identifier".to_string(),
1196                span: tok.span,
1197            }),
1198        }
1199    }
1200
1201    /// Parse a variable name or parenthesized operator.
1202    /// Handles both `foo` and `(<+>)` style names.
1203    fn parse_var_or_op(&mut self) -> ParseResult<Ident> {
1204        if self.eat(&TokenKind::LParen) {
1205            // Parenthesized operator: (<+>)
1206            let tok = self.current().ok_or(ParseError::UnexpectedEof {
1207                expected: "operator".to_string(),
1208            })?;
1209
1210            let ident = match &tok.node.kind {
1211                TokenKind::Operator(sym) | TokenKind::ConOperator(sym) => {
1212                    let ident = Ident::new(*sym);
1213                    self.advance();
1214                    ident
1215                }
1216                // Handle special punctuation used as operators
1217                TokenKind::Dot => {
1218                    let ident = Ident::new(Symbol::intern("."));
1219                    self.advance();
1220                    ident
1221                }
1222                TokenKind::Minus => {
1223                    let ident = Ident::new(Symbol::intern("-"));
1224                    self.advance();
1225                    ident
1226                }
1227                TokenKind::Backslash => {
1228                    // List difference operator \\
1229                    let ident = Ident::new(Symbol::intern("\\"));
1230                    self.advance();
1231                    ident
1232                }
1233                _ => {
1234                    return Err(ParseError::Unexpected {
1235                        found: tok.node.kind.description().to_string(),
1236                        expected: "operator".to_string(),
1237                        span: tok.span,
1238                    });
1239                }
1240            };
1241
1242            self.expect(&TokenKind::RParen)?;
1243            Ok(ident)
1244        } else {
1245            // Regular identifier
1246            self.parse_ident()
1247        }
1248    }
1249
1250    /// Parse a data declaration.
1251    #[allow(dead_code)]
1252    fn parse_data_decl(&mut self) -> ParseResult<Decl> {
1253        self.parse_data_decl_with_doc(None)
1254    }
1255
1256    /// Parse a data declaration with optional documentation.
1257    fn parse_data_decl_with_doc(&mut self, doc: Option<DocComment>) -> ParseResult<Decl> {
1258        let start = self.current_span();
1259        self.expect(&TokenKind::Data)?;
1260
1261        // Check for data family / data instance
1262        if self.check_ident_str("family") {
1263            return self.parse_data_family_decl(start, doc);
1264        }
1265        if self.check(&TokenKind::Instance) {
1266            return self.parse_data_instance_decl(start, doc);
1267        }
1268
1269        // Check for infix operator data declaration: `data a :+: b = ...`
1270        // Pattern: Ident ConOperator Ident (type_var operator type_var)
1271        let (name, params) = if let Some(TokenKind::Ident(_)) = self.current_kind() {
1272            // Save position to try infix pattern
1273            let saved_pos = self.pos;
1274            if let Some(TokenKind::Ident(lhs_sym)) = self.current_kind().cloned() {
1275                let lhs_span = self.current_span();
1276                self.advance();
1277                if let Some(TokenKind::ConOperator(op_sym)) = self.current_kind().cloned() {
1278                    self.advance();
1279                    if let Some(TokenKind::Ident(rhs_sym)) = self.current_kind().cloned() {
1280                        let rhs_span = self.current_span();
1281                        self.advance();
1282                        // Successfully parsed infix: `a :+: b`
1283                        let op_name = Ident::new(op_sym);
1284                        let lhs_var = TyVar {
1285                            name: Ident::new(lhs_sym),
1286                            span: lhs_span,
1287                        };
1288                        let rhs_var = TyVar {
1289                            name: Ident::new(rhs_sym),
1290                            span: rhs_span,
1291                        };
1292                        (op_name, vec![lhs_var, rhs_var])
1293                    } else {
1294                        // Not infix pattern, backtrack
1295                        self.pos = saved_pos;
1296                        let name = self.parse_conid()?;
1297                        let params = self.parse_ty_var_list()?;
1298                        (name, params)
1299                    }
1300                } else {
1301                    // Not infix pattern, backtrack
1302                    self.pos = saved_pos;
1303                    let name = self.parse_conid()?;
1304                    let params = self.parse_ty_var_list()?;
1305                    (name, params)
1306                }
1307            } else {
1308                self.pos = saved_pos;
1309                let name = self.parse_conid()?;
1310                let params = self.parse_ty_var_list()?;
1311                (name, params)
1312            }
1313        } else {
1314            let name = self.parse_conid_or_op()?;
1315            let params = self.parse_ty_var_list()?;
1316            (name, params)
1317        };
1318
1319        // Three forms:
1320        // 1. H98: `data T a = Con1 a | Con2`
1321        // 2. GADT: `data T a where Con1 :: a -> T a; ...`
1322        // 3. EmptyDataDecls: `data T a`
1323        let (constrs, gadt_constrs, deriving) = if self.eat(&TokenKind::Eq) {
1324            let constrs = self.parse_constructors()?;
1325            let deriving = self.parse_deriving()?;
1326            (constrs, vec![], deriving)
1327        } else if self.check(&TokenKind::Where) {
1328            // GADT syntax
1329            let gadt_constrs = self.parse_gadt_constructors()?;
1330            let deriving = self.parse_deriving()?;
1331            (vec![], gadt_constrs, deriving)
1332        } else {
1333            let deriving = self.parse_deriving()?;
1334            (vec![], vec![], deriving)
1335        };
1336
1337        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
1338
1339        Ok(Decl::DataDecl(DataDecl {
1340            doc,
1341            name,
1342            params,
1343            constrs,
1344            gadt_constrs,
1345            deriving,
1346            span,
1347        }))
1348    }
1349
1350    /// Parse GADT constructors in a `where` block.
1351    ///
1352    /// Each entry is `ConName :: Type` separated by layout or semicolons.
1353    fn parse_gadt_constructors(&mut self) -> ParseResult<Vec<GadtConDecl>> {
1354        self.expect(&TokenKind::Where)?;
1355
1356        let mut constrs = Vec::new();
1357
1358        if self.eat(&TokenKind::LBrace) {
1359            // Explicit braces
1360            if !self.check(&TokenKind::RBrace) {
1361                constrs.push(self.parse_gadt_con_decl()?);
1362                while self.eat(&TokenKind::Semi) {
1363                    if self.check(&TokenKind::RBrace) {
1364                        break;
1365                    }
1366                    constrs.push(self.parse_gadt_con_decl()?);
1367                }
1368            }
1369            self.expect(&TokenKind::RBrace)?;
1370        } else if self.eat(&TokenKind::VirtualLBrace) {
1371            // Layout-based declarations
1372            if !self.check(&TokenKind::VirtualRBrace) {
1373                constrs.push(self.parse_gadt_con_decl()?);
1374                while self.eat(&TokenKind::VirtualSemi) {
1375                    if self.check(&TokenKind::VirtualRBrace) {
1376                        break;
1377                    }
1378                    constrs.push(self.parse_gadt_con_decl()?);
1379                }
1380            }
1381            self.eat(&TokenKind::VirtualRBrace);
1382        }
1383
1384        Ok(constrs)
1385    }
1386
1387    /// Parse a single GADT constructor declaration: `ConName :: Type`.
1388    fn parse_gadt_con_decl(&mut self) -> ParseResult<GadtConDecl> {
1389        let start = self.current_span();
1390        let name = self.parse_conid()?;
1391        self.expect(&TokenKind::DoubleColon)?;
1392        let ty = self.parse_type()?;
1393        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
1394        Ok(GadtConDecl {
1395            doc: None,
1396            name,
1397            ty,
1398            span,
1399        })
1400    }
1401
1402    /// Parse a constructor identifier.
1403    fn parse_conid(&mut self) -> ParseResult<Ident> {
1404        let tok = self.current().ok_or(ParseError::UnexpectedEof {
1405            expected: "constructor".to_string(),
1406        })?;
1407
1408        match &tok.node.kind {
1409            TokenKind::ConId(sym) => {
1410                let ident = Ident::new(*sym);
1411                self.advance();
1412                Ok(ident)
1413            }
1414            _ => Err(ParseError::Unexpected {
1415                found: tok.node.kind.description().to_string(),
1416                expected: "constructor".to_string(),
1417                span: tok.span,
1418            }),
1419        }
1420    }
1421
1422    /// Parse a constructor name: either a `ConId` or a parenthesized `ConOperator`.
1423    fn parse_conid_or_op(&mut self) -> ParseResult<Ident> {
1424        // Extract kind and span upfront to avoid borrow conflict
1425        let (kind, span) = match self.current() {
1426            Some(tok) => (tok.node.kind.clone(), tok.span),
1427            None => {
1428                return Err(ParseError::UnexpectedEof {
1429                    expected: "constructor".to_string(),
1430                });
1431            }
1432        };
1433
1434        match &kind {
1435            TokenKind::ConId(sym) => {
1436                let ident = Ident::new(*sym);
1437                self.advance();
1438                Ok(ident)
1439            }
1440            TokenKind::LParen => {
1441                // Check for parenthesized constructor operator: (:+:)
1442                let saved = self.pos;
1443                self.advance(); // consume (
1444                if let Some(TokenKind::ConOperator(sym)) = self.current_kind().cloned() {
1445                    let ident = Ident::new(sym);
1446                    self.advance(); // consume operator
1447                    if self.eat(&TokenKind::RParen) {
1448                        return Ok(ident);
1449                    }
1450                }
1451                // Not a parenthesized operator, backtrack
1452                self.pos = saved;
1453                Err(ParseError::Unexpected {
1454                    found: kind.description().to_string(),
1455                    expected: "constructor".to_string(),
1456                    span,
1457                })
1458            }
1459            _ => Err(ParseError::Unexpected {
1460                found: kind.description().to_string(),
1461                expected: "constructor".to_string(),
1462                span,
1463            }),
1464        }
1465    }
1466
1467    /// Parse type variable list.
1468    fn parse_ty_var_list(&mut self) -> ParseResult<Vec<TyVar>> {
1469        let mut vars = Vec::new();
1470        while let Some(tok) = self.current() {
1471            match &tok.node.kind {
1472                TokenKind::Ident(sym) => {
1473                    let span = tok.span;
1474                    let name = Ident::new(*sym);
1475                    self.advance();
1476                    vars.push(TyVar { name, span });
1477                }
1478                _ => break,
1479            }
1480        }
1481        Ok(vars)
1482    }
1483
1484    /// Parse data constructors.
1485    fn parse_constructors(&mut self) -> ParseResult<Vec<ConDecl>> {
1486        let mut constrs = vec![self.parse_constructor()?];
1487        // Collect trailing doc comments after constructor (e.g., `-- ^ description`)
1488        if let Some(trailing_doc) = self.collect_doc_comments() {
1489            // Attach trailing doc to the last constructor
1490            if let Some(last) = constrs.last_mut() {
1491                if last.doc.is_none() {
1492                    last.doc = Some(trailing_doc);
1493                }
1494            }
1495        }
1496        while self.eat(&TokenKind::Pipe) {
1497            // Collect doc comments before next constructor
1498            let doc = self.collect_doc_comments();
1499            let mut constr = self.parse_constructor()?;
1500            // If there was a preceding doc, use it
1501            if constr.doc.is_none() && doc.is_some() {
1502                constr.doc = doc;
1503            }
1504            constrs.push(constr);
1505            // Collect trailing doc comments after constructor
1506            if let Some(trailing_doc) = self.collect_doc_comments() {
1507                if let Some(last) = constrs.last_mut() {
1508                    if last.doc.is_none() {
1509                        last.doc = Some(trailing_doc);
1510                    }
1511                }
1512            }
1513        }
1514        Ok(constrs)
1515    }
1516
1517    /// Parse a single constructor.
1518    /// Supports existential quantification: `forall a. C a => Con a`
1519    fn parse_constructor(&mut self) -> ParseResult<ConDecl> {
1520        let start = self.current_span();
1521
1522        // Parse existential quantification: forall a b. ...
1523        let mut existential_vars = Vec::new();
1524        if self.eat(&TokenKind::Forall) {
1525            while let Some(tok) = self.current() {
1526                match &tok.node.kind {
1527                    TokenKind::Ident(sym) => {
1528                        let name = Ident::new(*sym);
1529                        let span = tok.span;
1530                        self.advance();
1531                        existential_vars.push(TyVar { name, span });
1532                    }
1533                    TokenKind::LParen => {
1534                        // Kind annotation like (a :: Type) — parse the var name, skip the rest
1535                        self.advance(); // consume (
1536                        if let Some(TokenKind::Ident(sym)) = self.current_kind() {
1537                            let name = Ident::new(*sym);
1538                            let span = self.current_span();
1539                            existential_vars.push(TyVar { name, span });
1540                        }
1541                        // Skip until matching )
1542                        let mut depth = 1;
1543                        while depth > 0 && !self.at_eof() {
1544                            if self.check(&TokenKind::LParen) {
1545                                depth += 1;
1546                            } else if self.check(&TokenKind::RParen) {
1547                                depth -= 1;
1548                            }
1549                            self.advance();
1550                        }
1551                    }
1552                    TokenKind::Dot => {
1553                        self.advance();
1554                        break;
1555                    }
1556                    _ => break,
1557                }
1558            }
1559        }
1560
1561        // Parse existential context: (C a, D b) => or C a =>
1562        let mut existential_context = Vec::new();
1563        if !existential_vars.is_empty() {
1564            let saved_pos = self.pos;
1565            if let Some(constraints) = self.try_parse_context()? {
1566                existential_context = constraints;
1567            } else {
1568                self.pos = saved_pos;
1569            }
1570        }
1571
1572        let name = self.parse_conid_or_op()?;
1573
1574        let fields = if self.check(&TokenKind::LBrace) {
1575            self.parse_record_fields()?
1576        } else {
1577            let types = self.parse_constr_types()?;
1578            ConFields::Positional(types)
1579        };
1580
1581        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
1582        Ok(ConDecl {
1583            doc: None,
1584            name,
1585            fields,
1586            existential_vars,
1587            existential_context,
1588            span,
1589        })
1590    }
1591
1592    /// Parse constructor argument types.
1593    fn parse_constr_types(&mut self) -> ParseResult<Vec<Type>> {
1594        let mut types = Vec::new();
1595        while self.is_atype_start() {
1596            types.push(self.parse_atype()?);
1597        }
1598        Ok(types)
1599    }
1600
1601    /// Parse record fields.
1602    fn parse_record_fields(&mut self) -> ParseResult<ConFields> {
1603        self.expect(&TokenKind::LBrace)?;
1604        let mut fields = Vec::new();
1605
1606        // Skip leading doc comments
1607        self.skip_doc_comments();
1608
1609        if !self.check(&TokenKind::RBrace) {
1610            fields.push(self.parse_field_decl()?);
1611            // Skip trailing doc comments after field (e.g., `-- ^ description`)
1612            self.skip_doc_comments();
1613            while self.eat(&TokenKind::Comma) {
1614                // Skip doc comments before next field
1615                self.skip_doc_comments();
1616                if self.check(&TokenKind::RBrace) {
1617                    break;
1618                }
1619                fields.push(self.parse_field_decl()?);
1620                // Skip trailing doc comments after field
1621                self.skip_doc_comments();
1622            }
1623        }
1624
1625        self.expect(&TokenKind::RBrace)?;
1626        Ok(ConFields::Record(fields))
1627    }
1628
1629    /// Parse a field declaration.
1630    fn parse_field_decl(&mut self) -> ParseResult<FieldDecl> {
1631        let start = self.current_span();
1632        let name = self.parse_ident()?;
1633        self.expect(&TokenKind::DoubleColon)?;
1634        let ty = self.parse_type()?;
1635        let span = start.to(ty.span());
1636        Ok(FieldDecl {
1637            doc: None,
1638            name,
1639            ty,
1640            span,
1641        })
1642    }
1643
1644    /// Parse all deriving clauses (there may be multiple in a row).
1645    fn parse_deriving(&mut self) -> ParseResult<Vec<DerivingClause>> {
1646        let mut all_clauses = Vec::new();
1647
1648        // Parse all consecutive deriving clauses
1649        loop {
1650            // Skip any virtual layout tokens between deriving clauses
1651            self.skip_virtual_tokens();
1652
1653            if self.check(&TokenKind::Deriving) {
1654                // Peek ahead: if next token after `deriving` is `instance`,
1655                // this is a standalone deriving declaration, not part of the
1656                // data type's deriving clause.
1657                if self.pos + 1 < self.tokens.len()
1658                    && self.tokens[self.pos + 1].node.kind == TokenKind::Instance
1659                {
1660                    break;
1661                }
1662                let clauses = self.parse_single_deriving()?;
1663                all_clauses.extend(clauses);
1664            } else {
1665                break;
1666            }
1667        }
1668
1669        Ok(all_clauses)
1670    }
1671
1672    /// Parse a single deriving clause.
1673    fn parse_single_deriving(&mut self) -> ParseResult<Vec<DerivingClause>> {
1674        if !self.eat(&TokenKind::Deriving) {
1675            return Ok(vec![]);
1676        }
1677
1678        // Detect deriving strategy: stock, newtype, anyclass
1679        let strategy = if self.eat_ident_str("stock") {
1680            DerivingStrategy::Stock
1681        } else if self.eat(&TokenKind::Newtype) {
1682            DerivingStrategy::Newtype
1683        } else if self.eat_ident_str("anyclass") {
1684            DerivingStrategy::Anyclass
1685        } else {
1686            DerivingStrategy::Default
1687        };
1688
1689        if self.eat(&TokenKind::LParen) {
1690            let mut classes = Vec::new();
1691            if !self.check(&TokenKind::RParen) {
1692                // Parse a type (which may be an application like `MonadState XState`)
1693                let ty = self.parse_type()?;
1694                // Extract the class name from the type
1695                classes.push(self.type_to_class_name(&ty));
1696                while self.eat(&TokenKind::Comma) {
1697                    if self.check(&TokenKind::RParen) {
1698                        break;
1699                    }
1700                    let ty = self.parse_type()?;
1701                    classes.push(self.type_to_class_name(&ty));
1702                }
1703            }
1704            self.expect(&TokenKind::RParen)?;
1705
1706            // Handle `via` clause (DerivingVia extension)
1707            let strategy = if self.eat_ident_str("via") {
1708                let via_type = self.parse_type()?;
1709                DerivingStrategy::Via(via_type)
1710            } else {
1711                strategy
1712            };
1713
1714            Ok(classes
1715                .into_iter()
1716                .map(|class| DerivingClause {
1717                    strategy: strategy.clone(),
1718                    class,
1719                })
1720                .collect())
1721        } else {
1722            // Single class without parens
1723            let ty = self.parse_type()?;
1724            let class = self.type_to_class_name(&ty);
1725            Ok(vec![DerivingClause { strategy, class }])
1726        }
1727    }
1728
1729    /// Extract the class name from a type (e.g., `MonadState XState` -> `MonadState`)
1730    fn type_to_class_name(&self, ty: &Type) -> Ident {
1731        match ty {
1732            Type::Con(name, _) => *name,
1733            Type::App(f, _, _) => self.type_to_class_name(f),
1734            Type::Paren(inner, _) => self.type_to_class_name(inner),
1735            _ => Ident::from_str("<unknown>"),
1736        }
1737    }
1738
1739    /// Parse a standalone deriving declaration: `deriving instance Show Foo`
1740    fn parse_standalone_deriving(&mut self) -> ParseResult<Decl> {
1741        let start = self.current_span();
1742        self.expect(&TokenKind::Deriving)?;
1743        self.expect(&TokenKind::Instance)?;
1744
1745        // Parse class name
1746        let class = self.parse_conid()?;
1747
1748        // Parse the type to derive for
1749        let ty = self.parse_type()?;
1750
1751        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
1752
1753        Ok(Decl::StandaloneDeriving(StandaloneDeriving {
1754            class,
1755            ty,
1756            span,
1757        }))
1758    }
1759
1760    /// Parse a pattern synonym: `pattern Zero = Lit 0`
1761    fn parse_pattern_synonym(&mut self) -> ParseResult<Decl> {
1762        let start = self.current_span();
1763        self.expect_ident_str("pattern")?;
1764
1765        // Parse the pattern synonym name (uppercase constructor-like)
1766        let name = self.parse_conid()?;
1767
1768        // Parse zero or more variable arguments
1769        let mut args = Vec::new();
1770        while let Some(&TokenKind::Ident(sym)) = self.current_kind() {
1771            self.advance();
1772            args.push(Ident::new(sym));
1773        }
1774
1775        // Check direction: `=` (bidirectional) or `<-` (unidirectional)
1776        let direction = if self.eat(&TokenKind::Eq) {
1777            PatSynDir::Bidirectional
1778        } else if self.eat(&TokenKind::LeftArrow) {
1779            PatSynDir::Unidirectional
1780        } else {
1781            return Err(ParseError::Unexpected {
1782                found: self.current().map_or("end of input".to_string(), |t| {
1783                    t.node.kind.description().to_string()
1784                }),
1785                expected: "'=' or '<-' in pattern synonym".to_string(),
1786                span: self.current_span(),
1787            });
1788        };
1789
1790        // Parse the RHS pattern
1791        let pattern = self.parse_pattern()?;
1792
1793        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
1794
1795        Ok(Decl::PatternSynonym(PatternSynonymDecl {
1796            name,
1797            args,
1798            direction,
1799            pattern,
1800            span,
1801        }))
1802    }
1803
1804    /// Parse a type alias.
1805    #[allow(dead_code)]
1806    fn parse_type_alias(&mut self) -> ParseResult<Decl> {
1807        self.parse_type_decl_with_doc(None)
1808    }
1809
1810    /// Parse a type alias with optional documentation.
1811    /// Dispatch `type` declarations: type alias, type family, or type instance.
1812    fn parse_type_decl_with_doc(&mut self, doc: Option<DocComment>) -> ParseResult<Decl> {
1813        let start = self.current_span();
1814        self.expect(&TokenKind::Type)?;
1815
1816        if self.check_ident_str("family") {
1817            return self.parse_type_family_decl(start, doc);
1818        }
1819        if self.check(&TokenKind::Instance) {
1820            return self.parse_type_instance_decl(start, doc);
1821        }
1822        // Fall through to existing type alias parsing
1823        self.parse_type_alias_after_type(start, doc)
1824    }
1825
1826    /// Parse a type alias after the `type` keyword has been consumed.
1827    fn parse_type_alias_after_type(
1828        &mut self,
1829        start: Span,
1830        doc: Option<DocComment>,
1831    ) -> ParseResult<Decl> {
1832        let name = self.parse_conid()?;
1833        let params = self.parse_ty_var_list()?;
1834
1835        self.expect(&TokenKind::Eq)?;
1836        let ty = self.parse_type()?;
1837
1838        let span = start.to(ty.span());
1839        Ok(Decl::TypeAlias(TypeAlias {
1840            doc,
1841            name,
1842            params,
1843            ty,
1844            span,
1845        }))
1846    }
1847
1848    /// Parse a standalone type family declaration.
1849    ///
1850    /// Open:   `type family F a`
1851    /// Closed: `type family F a where { F Int = Bool; F a = () }`
1852    fn parse_type_family_decl(
1853        &mut self,
1854        start: Span,
1855        doc: Option<DocComment>,
1856    ) -> ParseResult<Decl> {
1857        self.expect_ident_str("family")?;
1858
1859        let name = self.parse_conid()?;
1860        let params = self.parse_ty_var_list()?;
1861
1862        // Optional kind signature: `:: * -> *`
1863        let kind = if self.eat(&TokenKind::DoubleColon) {
1864            Some(self.parse_kind()?)
1865        } else {
1866            None
1867        };
1868
1869        // Check for `where` (closed family) vs end (open family)
1870        if self.eat(&TokenKind::Where) {
1871            let equations = self.parse_type_family_equations(&name)?;
1872            let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
1873            Ok(Decl::TypeFamilyDecl(TypeFamilyDecl {
1874                doc,
1875                name,
1876                params,
1877                kind,
1878                family_kind: TypeFamilyKind::Closed,
1879                equations,
1880                span,
1881            }))
1882        } else {
1883            let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
1884            Ok(Decl::TypeFamilyDecl(TypeFamilyDecl {
1885                doc,
1886                name,
1887                params,
1888                kind,
1889                family_kind: TypeFamilyKind::Open,
1890                equations: vec![],
1891                span,
1892            }))
1893        }
1894    }
1895
1896    /// Parse equations within a closed type family `where` block.
1897    fn parse_type_family_equations(
1898        &mut self,
1899        _family_name: &Ident,
1900    ) -> ParseResult<Vec<TypeFamilyEqn>> {
1901        let mut equations = Vec::new();
1902
1903        if self.eat(&TokenKind::LBrace) {
1904            // Explicit braces
1905            if !self.check(&TokenKind::RBrace) {
1906                equations.push(self.parse_type_family_equation()?);
1907                while self.eat(&TokenKind::Semi) {
1908                    if self.check(&TokenKind::RBrace) {
1909                        break;
1910                    }
1911                    equations.push(self.parse_type_family_equation()?);
1912                }
1913            }
1914            self.expect(&TokenKind::RBrace)?;
1915        } else if self.eat(&TokenKind::VirtualLBrace) {
1916            // Layout-based
1917            if !self.check(&TokenKind::VirtualRBrace) {
1918                equations.push(self.parse_type_family_equation()?);
1919                while self.eat(&TokenKind::VirtualSemi) {
1920                    if self.check(&TokenKind::VirtualRBrace) {
1921                        break;
1922                    }
1923                    equations.push(self.parse_type_family_equation()?);
1924                }
1925            }
1926            self.eat(&TokenKind::VirtualRBrace);
1927        } else {
1928            // Single equation on same line
1929            equations.push(self.parse_type_family_equation()?);
1930        }
1931
1932        Ok(equations)
1933    }
1934
1935    /// Parse a single type family equation: `F Int = Bool`
1936    fn parse_type_family_equation(&mut self) -> ParseResult<TypeFamilyEqn> {
1937        let start = self.current_span();
1938
1939        // Parse family name (skip it, we already know it)
1940        let _name = self.parse_conid()?;
1941
1942        // Parse type argument patterns
1943        let mut args = Vec::new();
1944        while !self.check(&TokenKind::Eq) && !self.at_eof() {
1945            args.push(self.parse_atype()?);
1946        }
1947
1948        self.expect(&TokenKind::Eq)?;
1949        let rhs = self.parse_type()?;
1950
1951        let span = start.to(rhs.span());
1952        Ok(TypeFamilyEqn { args, rhs, span })
1953    }
1954
1955    /// Parse a standalone type instance: `type instance F Int = Bool`
1956    fn parse_type_instance_decl(
1957        &mut self,
1958        start: Span,
1959        doc: Option<DocComment>,
1960    ) -> ParseResult<Decl> {
1961        self.expect(&TokenKind::Instance)?;
1962
1963        let name = self.parse_conid()?;
1964
1965        // Parse type argument patterns
1966        let mut args = Vec::new();
1967        while !self.check(&TokenKind::Eq) && !self.at_eof() {
1968            args.push(self.parse_atype()?);
1969        }
1970
1971        self.expect(&TokenKind::Eq)?;
1972        let rhs = self.parse_type()?;
1973
1974        let span = start.to(rhs.span());
1975        Ok(Decl::TypeInstanceDecl(TypeInstanceDecl {
1976            doc,
1977            name,
1978            args,
1979            rhs,
1980            span,
1981        }))
1982    }
1983
1984    /// Parse a standalone data family declaration: `data family F a`
1985    fn parse_data_family_decl(
1986        &mut self,
1987        start: Span,
1988        doc: Option<DocComment>,
1989    ) -> ParseResult<Decl> {
1990        self.expect_ident_str("family")?;
1991
1992        let name = self.parse_conid()?;
1993        let params = self.parse_ty_var_list()?;
1994
1995        // Optional kind signature: `:: * -> *`
1996        let kind = if self.eat(&TokenKind::DoubleColon) {
1997            Some(self.parse_kind()?)
1998        } else {
1999            None
2000        };
2001
2002        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
2003        Ok(Decl::DataFamilyDecl(DataFamilyDecl {
2004            doc,
2005            name,
2006            params,
2007            kind,
2008            span,
2009        }))
2010    }
2011
2012    /// Parse a data family instance: `data instance F Int = Con1 Int | Con2`
2013    fn parse_data_instance_decl(
2014        &mut self,
2015        start: Span,
2016        doc: Option<DocComment>,
2017    ) -> ParseResult<Decl> {
2018        self.expect(&TokenKind::Instance)?;
2019
2020        let family_name = self.parse_conid()?;
2021
2022        // Parse type argument patterns (stop at = or where)
2023        let mut args = Vec::new();
2024        while !self.check(&TokenKind::Eq) && !self.check(&TokenKind::Where) && !self.at_eof() {
2025            args.push(self.parse_atype()?);
2026        }
2027
2028        // Parse constructors (same as regular data decl)
2029        let (constrs, gadt_constrs, deriving) = if self.eat(&TokenKind::Eq) {
2030            let constrs = self.parse_constructors()?;
2031            let deriving = self.parse_deriving()?;
2032            (constrs, vec![], deriving)
2033        } else if self.check(&TokenKind::Where) {
2034            let gadt_constrs = self.parse_gadt_constructors()?;
2035            let deriving = self.parse_deriving()?;
2036            (vec![], gadt_constrs, deriving)
2037        } else {
2038            (vec![], vec![], vec![])
2039        };
2040
2041        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
2042        Ok(Decl::DataInstanceDecl(DataInstanceDecl {
2043            doc,
2044            family_name,
2045            args,
2046            constrs,
2047            gadt_constrs,
2048            deriving,
2049            span,
2050        }))
2051    }
2052
2053    /// Parse a newtype declaration.
2054    #[allow(dead_code)]
2055    fn parse_newtype_decl(&mut self) -> ParseResult<Decl> {
2056        self.parse_newtype_decl_with_doc(None)
2057    }
2058
2059    /// Parse a newtype declaration with optional documentation.
2060    fn parse_newtype_decl_with_doc(&mut self, doc: Option<DocComment>) -> ParseResult<Decl> {
2061        let start = self.current_span();
2062        self.expect(&TokenKind::Newtype)?;
2063
2064        let name = self.parse_conid()?;
2065        let params = self.parse_ty_var_list()?;
2066
2067        self.expect(&TokenKind::Eq)?;
2068        let constr = self.parse_constructor()?;
2069        let deriving = self.parse_deriving()?;
2070
2071        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
2072        Ok(Decl::Newtype(NewtypeDecl {
2073            doc,
2074            name,
2075            params,
2076            constr,
2077            deriving,
2078            span,
2079        }))
2080    }
2081
2082    /// Parse a class declaration.
2083    /// Handles multi-parameter type classes and functional dependencies.
2084    /// Examples:
2085    ///   - `class Eq a where ...`
2086    ///   - `class (Show a, Typeable a) => LayoutClass layout a where ...`
2087    ///   - `class MonadState s m | m -> s where ...`
2088    #[allow(dead_code)]
2089    fn parse_class_decl(&mut self) -> ParseResult<Decl> {
2090        self.parse_class_decl_with_doc(None)
2091    }
2092
2093    /// Parse a class declaration with optional documentation.
2094    fn parse_class_decl_with_doc(&mut self, doc: Option<DocComment>) -> ParseResult<Decl> {
2095        let start = self.current_span();
2096        self.expect(&TokenKind::Class)?;
2097
2098        let context = self.parse_optional_context()?;
2099        let name = self.parse_conid()?;
2100
2101        // Parse one or more type parameters
2102        let mut params = Vec::new();
2103        while self.check_ident() {
2104            let tok = self.current().unwrap();
2105            if let TokenKind::Ident(sym) = &tok.node.kind {
2106                let param_name = Ident::new(*sym);
2107                let span = tok.span;
2108                self.advance();
2109                params.push(TyVar {
2110                    name: param_name,
2111                    span,
2112                });
2113            }
2114        }
2115
2116        // Parse optional functional dependencies: | a -> b, c -> d
2117        let fundeps = if self.eat(&TokenKind::Pipe) {
2118            self.parse_fundeps()?
2119        } else {
2120            vec![]
2121        };
2122
2123        // The `where` clause is optional in Haskell
2124        // e.g., `class Foo a` with no methods
2125        let (methods, assoc_types) = if self.eat(&TokenKind::Where) {
2126            self.parse_class_body()?
2127        } else {
2128            (vec![], vec![])
2129        };
2130
2131        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
2132        Ok(Decl::ClassDecl(ClassDecl {
2133            doc,
2134            context,
2135            name,
2136            params,
2137            fundeps,
2138            methods,
2139            assoc_types,
2140            span,
2141        }))
2142    }
2143
2144    /// Parse functional dependencies: `a -> b, c d -> e`
2145    fn parse_fundeps(&mut self) -> ParseResult<Vec<FunDep>> {
2146        let mut fundeps = Vec::new();
2147
2148        loop {
2149            let start = self.current_span();
2150
2151            // Parse 'from' variables
2152            let mut from = Vec::new();
2153            while self.check_ident() {
2154                if let Some(TokenKind::Ident(sym)) = self.current_kind() {
2155                    from.push(Ident::new(*sym));
2156                    self.advance();
2157                }
2158            }
2159
2160            self.expect(&TokenKind::Arrow)?;
2161
2162            // Parse 'to' variables
2163            let mut to = Vec::new();
2164            while self.check_ident() {
2165                if let Some(TokenKind::Ident(sym)) = self.current_kind() {
2166                    to.push(Ident::new(*sym));
2167                    self.advance();
2168                }
2169            }
2170
2171            let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
2172            fundeps.push(FunDep { from, to, span });
2173
2174            if !self.eat(&TokenKind::Comma) {
2175                break;
2176            }
2177        }
2178
2179        Ok(fundeps)
2180    }
2181
2182    /// Parse optional class/instance context.
2183    /// Handles patterns like:
2184    ///   - `(Eq a, Show a) =>`
2185    ///   - `Eq a =>`
2186    ///   - `(a ~ Type) =>` (type equality constraint)
2187    fn parse_optional_context(&mut self) -> ParseResult<Vec<Constraint>> {
2188        // Save position in case we need to backtrack
2189        let saved_pos = self.pos;
2190
2191        let start_span = self.current_span();
2192
2193        let constraints = if self.check(&TokenKind::LParen) {
2194            // Could be tuple context `(C1 a, C2 a) =>` or type equality `(a ~ Type) =>`
2195            // or just a type in parens
2196            self.advance();
2197
2198            // Try parsing as constraints
2199            let mut constraints = Vec::new();
2200            if !self.check(&TokenKind::RParen) {
2201                // Parse first constraint - could be:
2202                // - ConId Type... (normal constraint like Eq a)
2203                // - Type ~ Type (type equality)
2204                // - Type (just a type, might be part of equality)
2205                let constraint = self.parse_constraint_item(start_span)?;
2206                if let Some(c) = constraint {
2207                    constraints.push(c);
2208                }
2209
2210                // Parse more constraints
2211                while self.eat(&TokenKind::Comma) {
2212                    let c_start = self.current_span();
2213                    let constraint = self.parse_constraint_item(c_start)?;
2214                    if let Some(c) = constraint {
2215                        constraints.push(c);
2216                    }
2217                }
2218            }
2219
2220            if !self.eat(&TokenKind::RParen) {
2221                // Not a valid context tuple, backtrack
2222                self.pos = saved_pos;
2223                return Ok(vec![]);
2224            }
2225            constraints
2226        } else if let Some(TokenKind::ConId(_)) = self.current_kind() {
2227            // Could be single constraint `Eq a =>`
2228            let class = self.parse_conid()?;
2229            // Parse type arguments until we see `=>` or run out
2230            let mut args = Vec::new();
2231            while !self.check(&TokenKind::FatArrow) && !self.at_eof() {
2232                // Don't parse operators as part of the constraint args
2233                if let Some(TokenKind::Operator(_)) = self.current_kind() {
2234                    break;
2235                }
2236                if let Ok(arg) = self.parse_atype() {
2237                    args.push(arg);
2238                } else {
2239                    break;
2240                }
2241            }
2242            let span = start_span.to(self.tokens[self.pos.saturating_sub(1)].span);
2243            vec![Constraint { class, args, span }]
2244        } else {
2245            return Ok(vec![]);
2246        };
2247
2248        // Check for `=>`
2249        if self.eat(&TokenKind::FatArrow) {
2250            Ok(constraints)
2251        } else {
2252            // No `=>` found, backtrack
2253            self.pos = saved_pos;
2254            Ok(vec![])
2255        }
2256    }
2257
2258    /// Parse a single constraint item within a context.
2259    /// Handles normal constraints (C a) and type equality (a ~ b).
2260    fn parse_constraint_item(&mut self, start_span: Span) -> ParseResult<Option<Constraint>> {
2261        // Try to parse as a normal constraint first: ConId Type...
2262        if let Some(TokenKind::ConId(_)) = self.current_kind() {
2263            let class = self.parse_conid()?;
2264            // Parse type arguments
2265            let mut args = Vec::new();
2266            while !self.check(&TokenKind::Comma)
2267                && !self.check(&TokenKind::RParen)
2268                && !self.at_eof()
2269            {
2270                // Don't parse `~` as part of args (it's a type operator)
2271                if let Some(TokenKind::Operator(sym)) = self.current_kind() {
2272                    if sym.as_str() == "~" {
2273                        break;
2274                    }
2275                }
2276                if let Ok(arg) = self.parse_atype() {
2277                    args.push(arg);
2278                } else {
2279                    break;
2280                }
2281            }
2282            let span = start_span.to(self.tokens[self.pos.saturating_sub(1)].span);
2283            return Ok(Some(Constraint { class, args, span }));
2284        }
2285
2286        // Try type equality constraint: a ~ Type
2287        // Skip the LHS type (use atype to not consume `~` as part of the type)
2288        if self.check_ident() || self.check(&TokenKind::LParen) {
2289            let saved = self.pos;
2290            // Try to parse just the atomic type on the left of ~
2291            if self.parse_atype().is_ok() {
2292                // Check for `~` token (type equality operator)
2293                if self.eat(&TokenKind::Tilde) {
2294                    // Parse RHS type (full type since nothing follows)
2295                    if self.parse_type().is_ok() {
2296                        // Successfully parsed type equality, but we'll represent it
2297                        // as an opaque constraint for now (class name (~))
2298                        let span = start_span.to(self.tokens[self.pos.saturating_sub(1)].span);
2299                        return Ok(Some(Constraint {
2300                            class: Ident::from_str("~"),
2301                            args: vec![], // We lose the actual types, but that's OK for now
2302                            span,
2303                        }));
2304                    }
2305                }
2306            }
2307            // Backtrack if it wasn't a type equality
2308            self.pos = saved;
2309        }
2310
2311        Ok(None)
2312    }
2313
2314    /// Parse class body (methods and associated type declarations).
2315    /// Returns (methods, assoc_types).
2316    fn parse_class_body(&mut self) -> ParseResult<(Vec<Decl>, Vec<AssocType>)> {
2317        let mut methods = Vec::new();
2318        let mut assoc_types = Vec::new();
2319
2320        if self.eat(&TokenKind::LBrace) {
2321            // Explicit braces
2322            if !self.check(&TokenKind::RBrace) {
2323                self.parse_class_body_item(&mut methods, &mut assoc_types)?;
2324                while self.eat(&TokenKind::Semi) {
2325                    if self.check(&TokenKind::RBrace) {
2326                        break;
2327                    }
2328                    self.parse_class_body_item(&mut methods, &mut assoc_types)?;
2329                }
2330            }
2331            self.expect(&TokenKind::RBrace)?;
2332        } else if self.eat(&TokenKind::VirtualLBrace) {
2333            // Layout-based declarations
2334            if !self.check(&TokenKind::VirtualRBrace) {
2335                self.parse_class_body_item(&mut methods, &mut assoc_types)?;
2336                while self.eat(&TokenKind::VirtualSemi) {
2337                    if self.check(&TokenKind::VirtualRBrace) {
2338                        break;
2339                    }
2340                    self.parse_class_body_item(&mut methods, &mut assoc_types)?;
2341                }
2342            }
2343            self.eat(&TokenKind::VirtualRBrace);
2344        }
2345
2346        // Merge multi-clause functions
2347        methods = self.merge_function_clauses(methods);
2348
2349        Ok((methods, assoc_types))
2350    }
2351
2352    /// Parse a single class body item (either a method or an associated type).
2353    fn parse_class_body_item(
2354        &mut self,
2355        methods: &mut Vec<Decl>,
2356        assoc_types: &mut Vec<AssocType>,
2357    ) -> ParseResult<()> {
2358        // Skip doc comments
2359        self.skip_doc_comments();
2360        self.eat(&TokenKind::VirtualSemi);
2361
2362        // Check for associated type: `type Name params`
2363        if self.check(&TokenKind::Type) {
2364            let assoc_type = self.parse_assoc_type_decl()?;
2365            assoc_types.push(assoc_type);
2366        } else if self.check(&TokenKind::Default) {
2367            // DefaultSignatures: `default methodName :: ConstrainedType`
2368            // Parse and discard — BHC handles default method bodies via FunBind.
2369            // The `default` keyword before a type sig is purely informational.
2370            self.advance(); // eat 'default'
2371            let _decl = self.parse_value_decl()?;
2372            // Discard: it's just a more-constrained type sig for the default
2373        } else {
2374            let decl = self.parse_value_decl()?;
2375            methods.push(decl);
2376        }
2377        Ok(())
2378    }
2379
2380    /// Parse an associated type declaration within a class.
2381    /// Example: `type Elem c` or `type Elem c :: * -> *` or `type Elem c = [c]`
2382    fn parse_assoc_type_decl(&mut self) -> ParseResult<AssocType> {
2383        let start = self.current_span();
2384        self.expect(&TokenKind::Type)?;
2385
2386        let name = self.parse_conid()?;
2387
2388        // Parse type parameters
2389        let mut params = Vec::new();
2390        while self.check_ident() {
2391            let tok = self.current().unwrap();
2392            if let TokenKind::Ident(sym) = &tok.node.kind {
2393                let param_name = Ident::new(*sym);
2394                let span = tok.span;
2395                self.advance();
2396                params.push(TyVar {
2397                    name: param_name,
2398                    span,
2399                });
2400            }
2401        }
2402
2403        // Parse optional kind signature: `:: * -> *`
2404        let kind = if self.eat(&TokenKind::DoubleColon) {
2405            Some(self.parse_kind()?)
2406        } else {
2407            None
2408        };
2409
2410        // Parse optional default type: `= Type`
2411        let default = if self.eat(&TokenKind::Eq) {
2412            Some(self.parse_type()?)
2413        } else {
2414            None
2415        };
2416
2417        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
2418        Ok(AssocType {
2419            name,
2420            params,
2421            kind,
2422            default,
2423            span,
2424        })
2425    }
2426
2427    /// Parse a kind (for kind signatures).
2428    fn parse_kind(&mut self) -> ParseResult<Kind> {
2429        let kind = self.parse_kind_atom()?;
2430
2431        // Check for arrow
2432        if self.eat(&TokenKind::Arrow) {
2433            let right = self.parse_kind()?;
2434            Ok(Kind::Arrow(Box::new(kind), Box::new(right)))
2435        } else {
2436            Ok(kind)
2437        }
2438    }
2439
2440    /// Parse an atomic kind.
2441    fn parse_kind_atom(&mut self) -> ParseResult<Kind> {
2442        // Check for `*` (Star token) or `Type`
2443        if self.check(&TokenKind::Star) {
2444            self.advance();
2445            return Ok(Kind::Star);
2446        }
2447        if let Some(TokenKind::Operator(sym)) = self.current_kind() {
2448            if sym.as_str() == "*" {
2449                self.advance();
2450                return Ok(Kind::Star);
2451            }
2452        }
2453
2454        if let Some(TokenKind::ConId(sym)) = self.current_kind() {
2455            if sym.as_str() == "Type" {
2456                self.advance();
2457                return Ok(Kind::Star);
2458            }
2459            // Named kind variable
2460            let name = Ident::new(*sym);
2461            self.advance();
2462            return Ok(Kind::Var(name));
2463        }
2464
2465        // Parenthesized kind
2466        if self.eat(&TokenKind::LParen) {
2467            let kind = self.parse_kind()?;
2468            self.expect(&TokenKind::RParen)?;
2469            return Ok(kind);
2470        }
2471
2472        Err(ParseError::Unexpected {
2473            found: self
2474                .current()
2475                .map(|t| t.node.kind.description().to_string())
2476                .unwrap_or("end of file".to_string()),
2477            expected: "kind (*, Type, or kind variable)".to_string(),
2478            span: self.current_span(),
2479        })
2480    }
2481
2482    /// Parse class methods (legacy, for compatibility).
2483    #[allow(dead_code)]
2484    fn parse_class_methods(&mut self) -> ParseResult<Vec<Decl>> {
2485        // Simplified - just parse as local decls
2486        self.parse_local_decls()
2487    }
2488
2489    /// Parse an instance declaration.
2490    #[allow(dead_code)]
2491    fn parse_instance_decl(&mut self) -> ParseResult<Decl> {
2492        self.parse_instance_decl_with_doc(None)
2493    }
2494
2495    /// Parse an instance declaration with optional documentation.
2496    fn parse_instance_decl_with_doc(&mut self, doc: Option<DocComment>) -> ParseResult<Decl> {
2497        let start = self.current_span();
2498        self.expect(&TokenKind::Instance)?;
2499
2500        let context = self.parse_optional_context()?;
2501        let class = self.parse_conid()?;
2502        let ty = self.parse_type()?;
2503
2504        // The `where` clause is optional in Haskell
2505        // e.g., `instance Message Resize` with no methods
2506        let (methods, assoc_type_defs) = if self.eat(&TokenKind::Where) {
2507            self.parse_instance_body()?
2508        } else {
2509            (vec![], vec![])
2510        };
2511
2512        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
2513        Ok(Decl::InstanceDecl(InstanceDecl {
2514            doc,
2515            context,
2516            class,
2517            ty,
2518            methods,
2519            assoc_type_defs,
2520            span,
2521        }))
2522    }
2523
2524    /// Parse instance body (methods and associated type definitions).
2525    /// Returns (methods, assoc_type_defs).
2526    fn parse_instance_body(&mut self) -> ParseResult<(Vec<Decl>, Vec<AssocTypeDef>)> {
2527        let mut methods = Vec::new();
2528        let mut assoc_type_defs = Vec::new();
2529
2530        if self.eat(&TokenKind::LBrace) {
2531            // Explicit braces
2532            if !self.check(&TokenKind::RBrace) {
2533                self.parse_instance_body_item(&mut methods, &mut assoc_type_defs)?;
2534                while self.eat(&TokenKind::Semi) {
2535                    if self.check(&TokenKind::RBrace) {
2536                        break;
2537                    }
2538                    self.parse_instance_body_item(&mut methods, &mut assoc_type_defs)?;
2539                }
2540            }
2541            self.expect(&TokenKind::RBrace)?;
2542        } else if self.eat(&TokenKind::VirtualLBrace) {
2543            // Layout-based declarations
2544            if !self.check(&TokenKind::VirtualRBrace) {
2545                self.parse_instance_body_item(&mut methods, &mut assoc_type_defs)?;
2546                while self.eat(&TokenKind::VirtualSemi) {
2547                    if self.check(&TokenKind::VirtualRBrace) {
2548                        break;
2549                    }
2550                    self.parse_instance_body_item(&mut methods, &mut assoc_type_defs)?;
2551                }
2552            }
2553            self.eat(&TokenKind::VirtualRBrace);
2554        }
2555
2556        // Merge multi-clause functions
2557        methods = self.merge_function_clauses(methods);
2558
2559        Ok((methods, assoc_type_defs))
2560    }
2561
2562    /// Parse a single instance body item (either a method or an associated type definition).
2563    fn parse_instance_body_item(
2564        &mut self,
2565        methods: &mut Vec<Decl>,
2566        assoc_type_defs: &mut Vec<AssocTypeDef>,
2567    ) -> ParseResult<()> {
2568        // Skip doc comments
2569        self.skip_doc_comments();
2570        self.eat(&TokenKind::VirtualSemi);
2571
2572        // Check for associated type definition: `type Name args = rhs`
2573        if self.check(&TokenKind::Type) {
2574            let assoc_type_def = self.parse_assoc_type_def()?;
2575            assoc_type_defs.push(assoc_type_def);
2576        } else {
2577            let decl = self.parse_value_decl()?;
2578            methods.push(decl);
2579        }
2580        Ok(())
2581    }
2582
2583    /// Parse an associated type definition within an instance.
2584    /// Example: `type Elem [a] = a`
2585    fn parse_assoc_type_def(&mut self) -> ParseResult<AssocTypeDef> {
2586        let start = self.current_span();
2587        self.expect(&TokenKind::Type)?;
2588
2589        let name = self.parse_conid()?;
2590
2591        // Parse type arguments (the patterns for the associated type)
2592        let mut args = Vec::new();
2593        while !self.check(&TokenKind::Eq) && !self.at_eof() {
2594            // Stop if we see operators or other delimiters
2595            if let Some(
2596                TokenKind::Semi
2597                | TokenKind::VirtualSemi
2598                | TokenKind::RBrace
2599                | TokenKind::VirtualRBrace,
2600            ) = self.current_kind()
2601            {
2602                break;
2603            }
2604            let arg = self.parse_atype()?;
2605            args.push(arg);
2606        }
2607
2608        self.expect(&TokenKind::Eq)?;
2609
2610        let rhs = self.parse_type()?;
2611
2612        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
2613        Ok(AssocTypeDef {
2614            name,
2615            args,
2616            rhs,
2617            span,
2618        })
2619    }
2620
2621    /// Parse a foreign declaration.
2622    #[allow(dead_code)]
2623    fn parse_foreign_decl(&mut self) -> ParseResult<Decl> {
2624        self.parse_foreign_decl_with_doc(None)
2625    }
2626
2627    /// Parse a foreign declaration with optional documentation.
2628    ///
2629    /// Grammar:
2630    /// ```text
2631    /// foreign_decl ::= 'foreign' 'import' calling_conv [safety] [c_name] hs_name '::' type
2632    ///                | 'foreign' 'export' calling_conv [c_name] hs_name '::' type
2633    /// calling_conv ::= 'ccall' | 'capi' | 'stdcall' | 'javascript'
2634    /// safety       ::= 'safe' | 'unsafe' | 'interruptible'
2635    /// ```
2636    fn parse_foreign_decl_with_doc(&mut self, doc: Option<DocComment>) -> ParseResult<Decl> {
2637        let start = self.current_span();
2638        self.expect(&TokenKind::Foreign)?;
2639
2640        // Parse 'import' or 'export'
2641        // 'import' is a keyword token, 'export' is an identifier
2642        let kind = if self.check(&TokenKind::Import) {
2643            self.advance();
2644            ForeignKind::Import
2645        } else if let Some(tok) = self.current() {
2646            if let TokenKind::Ident(sym) = &tok.node.kind {
2647                if sym.as_str() == "export" {
2648                    self.advance();
2649                    ForeignKind::Export
2650                } else {
2651                    return Err(ParseError::Unexpected {
2652                        found: tok.node.kind.description().to_string(),
2653                        expected: "`import` or `export`".to_string(),
2654                        span: tok.span,
2655                    });
2656                }
2657            } else {
2658                return Err(ParseError::Unexpected {
2659                    found: tok.node.kind.description().to_string(),
2660                    expected: "`import` or `export`".to_string(),
2661                    span: tok.span,
2662                });
2663            }
2664        } else {
2665            return Err(ParseError::UnexpectedEof {
2666                expected: "`import` or `export`".to_string(),
2667            });
2668        };
2669
2670        // Parse calling convention: ccall, capi, stdcall, javascript
2671        let convention = if let Some(tok) = self.current() {
2672            if let TokenKind::Ident(sym) = &tok.node.kind {
2673                match sym.as_str() {
2674                    "ccall" | "capi" | "stdcall" | "javascript" => {
2675                        let conv = *sym;
2676                        self.advance();
2677                        conv
2678                    }
2679                    _ => {
2680                        // Default to ccall if no convention specified
2681                        Symbol::intern("ccall")
2682                    }
2683                }
2684            } else {
2685                Symbol::intern("ccall")
2686            }
2687        } else {
2688            return Err(ParseError::UnexpectedEof {
2689                expected: "calling convention".to_string(),
2690            });
2691        };
2692
2693        // Parse optional safety: safe, unsafe, interruptible
2694        let mut safety = ForeignSafety::Safe;
2695        if let Some(tok) = self.current() {
2696            if let TokenKind::Ident(sym) = &tok.node.kind {
2697                match sym.as_str() {
2698                    "safe" => {
2699                        safety = ForeignSafety::Safe;
2700                        self.advance();
2701                    }
2702                    "unsafe" => {
2703                        safety = ForeignSafety::Unsafe;
2704                        self.advance();
2705                    }
2706                    "interruptible" => {
2707                        safety = ForeignSafety::Interruptible;
2708                        self.advance();
2709                    }
2710                    _ => {}
2711                }
2712            }
2713        }
2714
2715        // Now we need to parse: [c_name_string] haskell_name :: type
2716        // If the next token is a string literal, it's the C name.
2717        // Otherwise, the Haskell name doubles as the C name.
2718        let mut external_name: Option<String> = None;
2719        if let Some(tok) = self.current() {
2720            if let TokenKind::StringLit(s) = &tok.node.kind {
2721                external_name = Some(s.clone());
2722                self.advance();
2723            }
2724        }
2725
2726        // Parse the Haskell name
2727        let name = self.parse_ident()?;
2728
2729        // Parse '::' and type
2730        self.expect(&TokenKind::DoubleColon)?;
2731        let ty = self.parse_type()?;
2732
2733        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
2734        Ok(Decl::Foreign(ForeignDecl {
2735            doc,
2736            kind,
2737            convention,
2738            safety,
2739            external_name,
2740            name,
2741            ty,
2742            span,
2743        }))
2744    }
2745
2746    /// Parse a fixity declaration.
2747    fn parse_fixity_decl(&mut self) -> ParseResult<Decl> {
2748        let start = self.current_span();
2749
2750        let fixity = match self.current().map(|t| &t.node.kind) {
2751            Some(TokenKind::Infix) => {
2752                self.advance();
2753                Fixity::None
2754            }
2755            Some(TokenKind::Infixl) => {
2756                self.advance();
2757                Fixity::Left
2758            }
2759            Some(TokenKind::Infixr) => {
2760                self.advance();
2761                Fixity::Right
2762            }
2763            _ => unreachable!(),
2764        };
2765
2766        // Parse precedence
2767        let prec = if let Some(tok) = self.current() {
2768            if let TokenKind::IntLit(ref lit) = &tok.node.kind {
2769                let p: u8 = lit.parse().map(|v| v as u8).unwrap_or(9);
2770                self.advance();
2771                p.min(9)
2772            } else {
2773                9
2774            }
2775        } else {
2776            9
2777        };
2778
2779        // Parse operators
2780        let mut ops = Vec::new();
2781        loop {
2782            let tok = self.current().ok_or(ParseError::UnexpectedEof {
2783                expected: "operator".to_string(),
2784            })?;
2785
2786            match &tok.node.kind {
2787                TokenKind::Operator(sym) => {
2788                    ops.push(Ident::new(*sym));
2789                    self.advance();
2790                }
2791                TokenKind::Backtick => {
2792                    self.advance();
2793                    ops.push(self.parse_ident()?);
2794                    self.expect(&TokenKind::Backtick)?;
2795                }
2796                _ => {
2797                    if ops.is_empty() {
2798                        return Err(ParseError::Unexpected {
2799                            found: tok.node.kind.description().to_string(),
2800                            expected: "operator".to_string(),
2801                            span: tok.span,
2802                        });
2803                    }
2804                    break;
2805                }
2806            }
2807
2808            if !self.eat(&TokenKind::Comma) {
2809                break;
2810            }
2811        }
2812
2813        let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
2814        Ok(Decl::Fixity(FixityDecl {
2815            fixity,
2816            prec,
2817            ops,
2818            span,
2819        }))
2820    }
2821
2822    /// Try to recover to the next declaration after an error.
2823    fn recover_to_next_decl(&mut self) {
2824        while !self.at_eof() {
2825            if let Some(tok) = self.current() {
2826                match &tok.node.kind {
2827                    TokenKind::Data
2828                    | TokenKind::Type
2829                    | TokenKind::Newtype
2830                    | TokenKind::Class
2831                    | TokenKind::Instance
2832                    | TokenKind::Foreign
2833                    | TokenKind::Infix
2834                    | TokenKind::Infixl
2835                    | TokenKind::Infixr => return,
2836                    TokenKind::Ident(_) => {
2837                        // Could be start of new binding
2838                        return;
2839                    }
2840                    _ => {
2841                        self.advance();
2842                    }
2843                }
2844            } else {
2845                break;
2846            }
2847        }
2848    }
2849}