Skip to main content

graphcal_compiler/desugar/
mod.rs

1//! Generic desugaring pipeline.
2//!
3//! Transforms `File<Raw>` (parser output, with all surface sugar) into
4//! `File<Desugared>` (canonical form consumed by name resolution, IR lowering,
5//! TIR, and evaluation).
6//!
7//! # Architecture
8//!
9//! Each surface sugar implements [`DesugarSugar`] — a node-level transform
10//! that maps one raw sugar variant to its desugared equivalent. The generic
11//! walker in this module traverses the AST, dispatching `Sugar(_)` arms to
12//! the appropriate [`DesugarSugar`] impl while every other variant is
13//! rebuilt phase-by-phase with its children desugared recursively.
14//!
15//! ```text
16//! File<Raw> ──┬─► (walker) ──┬─► File<Desugared>
17//!             │               │
18//!             ├─ MultiDecl ───┘ via DesugarSugar
19//!             └─ TableLiteral ──► (desugar to MapLiteral)
20//! ```
21//!
22//! # Adding a new customer
23//!
24//! 1. Add a variant to [`crate::syntax::ast::RawDeclSugar`] or
25//!    [`crate::syntax::ast::RawExprSugar`].
26//! 2. Implement [`DesugarSugar`] for that variant in a submodule of this
27//!    module.
28//! 3. Wire it into the walker's `Sugar(_)` dispatch.
29//!
30//! No changes to downstream consumers are needed — they only see
31//! `File<Desugared>` and never observed the sugar in the first place.
32//!
33//! # Span fidelity
34//!
35//! Desugaring preserves source spans: every synthesized node carries the
36//! span of the surface construct it came from. Diagnostics emitted on
37//! desugared AST still point at the original source.
38
39pub mod convert;
40pub mod desugared_ast;
41
42/// Single-node desugaring step.
43///
44/// Implementors map one surface sugar form to its desugared equivalent.
45/// The output type is generic so different sugars can desugar to different
46/// shapes — e.g., `MultiDecl` desugars to `Vec<Declaration<Desugared>>`,
47/// while `TableLiteral` desugars to `ExprKind<Desugared>`.
48pub trait DesugarSugar {
49    /// The raw surface form being desugared.
50    type RawNode;
51    /// The shape produced by desugaring (often a single node, sometimes
52    /// a `Vec` for one-to-many expansions).
53    type DesugaredOut;
54
55    /// Perform the desugaring.
56    fn desugar_sugar(raw: Self::RawNode) -> Self::DesugaredOut;
57}