Skip to main content

zelkova_compiler/ir/
mod.rs

1//! The intermediate representation code generation reads.
2//!
3//! The typer produces it. It is the only phase that knows a node's type, and every node
4//! here carries one ([`DEC-18` decision
5//! 1](../../docs/decisions/dec-18.md#1--the-backend-reads-a-typed-ir-and-the-typer-is-what-produces-it)).
6//! [`Term`] is the untyped half — what the translation from the canonical AST builds —
7//! and [`TypedTerm`] is the same tree once inference has solved a type for each of its
8//! nodes. A [`Module`] holds the unions a module declares and one [`Declaration`] per
9//! value: everything about a module that only emission asks for.
10//!
11//! It is not the whole of what a backend is handed. `check_module` answers with a
12//! [`CheckedModule`](crate::CheckedModule), which is this beside the
13//! [`canonical::Module`] it was built from, and two of the things emission needs are
14//! still only on that half — a module's `exports`, which is what a JavaScript module has
15//! to export, and `canonical::Value::TypedValue`'s `marked_unsafe`, which
16//! `zelkova_js::emit` reads because an `unsafe`
17//! signature and an effectful one emit differently. Nothing here duplicates them.
18//!
19//! The type language itself is still [`typer::Type`](crate::typer::Type). It is
20//! the typer's own representation and unification is written against it, so it stays
21//! there; this module names it and adds nothing to it.
22//!
23//! # What this shape owes WebAssembly
24//!
25//! One IR serves both targets and JavaScript is written first ([`DEC-18` decision
26//! 2](../../docs/decisions/dec-18.md#2--one-ir-serves-both-targets-and-javascript-is-written-first)),
27//! so a reader arriving while only the JavaScript backend exists will find things
28//! JavaScript has no use for. None of them is spare:
29//!
30//! - **A type on every node, and what a constrained one asks of it.** JavaScript needs
31//!   almost none of them: the canonical AST already separates an `Int` literal from a
32//!   `Float` one, and arithmetic and equality are ordinary functions behind facades.
33//!   WebAssembly is statically typed, and a node's representation class — an `i64`, an
34//!   `f64`, a reference — is read off its type. Solved types are also what
35//!   monomorphisation consumes, which is the only way polymorphism reaches a target where
36//!   [a class dictionary is erased by specialisation and never
37//!   passed](../../docs/decisions/dec-2.md#7--dictionaries-are-erased-by-specialisation-not-passed).
38//!   A specialiser needs the other half of a constrained name too, and there are three
39//!   places it is written. A [reference](TypedTermKind::Identifier) to a name whose type
40//!   has a context carries that context as instantiated at the use, one [`Predicate`]
41//!   per constraint, with the final substitution applied like every other type on the
42//!   node: `eq` used at `Int` carries `Eq Int`. A [`Declaration`] carries its own
43//!   context, read off its solved type the same way. And a [`Module`] carries its
44//!   [`Instance`]s, each with its class, head, context and one checked body per member.
45//!   A [hole](TypedTermKind::Hole), a name that did not resolve, has a type too: the one
46//!   inference solved for its position, which is an unsolved variable when nothing
47//!   around it constrains it.
48//! - **A constructor's index within its declaration**, and not only its name. A union is
49//!   a WIT `variant` with one case per constructor and a tuple is a `tuple` ([A union
50//!   crosses as a tagged
51//!   value](../../docs/spec/interop.md#a-union-crosses-as-a-tagged-value)), so a
52//!   constructor is reached by its position there. JavaScript writes the name into the
53//!   `$` field and never asks for the index.
54//! - **Arity as a fact and saturation per call site.** A declaration emits as a plain
55//!   n-ary function on both targets ([`DEC-18` decision
56//!   3](../../docs/decisions/dec-18.md#3--a-function-emits-as-a-plain-n-ary-function-and-currying-is-a-runtime-helper)),
57//!   and a facade's [plain parameter
58//!   list](../../docs/spec/interop.md#the-javascript-companion) is the same call shape
59//!   either way. WebAssembly has no closure primitive, so how a partial application is
60//!   represented there is open — and an IR that made a call site's saturation something
61//!   to re-derive would make that question harder rather than leaving it open.
62//! - **A record's fields by label, and the order a positional target reads them in.** A
63//!   record crosses as a WIT `record`, which reaches a field by position ([Which types may
64//!   cross the boundary](../../docs/spec/interop.md#which-types-may-cross-the-boundary)),
65//!   and a record type is a set of fields with no order of its own ([a record type is a
66//!   set of fields](../../docs/spec/records.md#a-record-type-is-a-set-of-fields)), so
67//!   nothing in the IR numbers them: [`TypedTermKind::Access`], [`TypedTermKind::Accessor`],
68//!   [`TypedTermKind::Update`] and a record pattern's entries
69//!   ([`Step::Field`]) name a field by its label, and JavaScript reads it as the property
70//!   of that name. A positional target reads the order off the type, which is on the
71//!   access node already — the [`Type::Record`] of the `record` operand, of the
72//!   accessor's parameter, of the update's own type, of the value a pattern is matched
73//!   against. That order is **label order**: the labels sorted by their characters, each
74//!   compared by its code point, a label that another begins with first. It is the order
75//!   a `Type::Record`'s map iterates in, and the one two spellings of one type agree on —
76//!   `{ a : Int, b : Int }` and `{ b : Int, a : Int }` are one type and have one layout —
77//!   which is why [Records and
78//!   derivation](../../docs/spec/records.md#records-and-derivation) walks a record's
79//!   fields in it too: sorting is the only order available that does. The order a
80//!   record *expression*'s fields were written in is not a position. It is on the term
81//!   ([`TypedTermKind::Record`], [`TypedTermKind::Update`]) as an order of evaluation, and
82//!   a target evaluates in it and lays the value out in label order.
83//!
84//! [`GEN-15`](../../docs/tickets/gen-15.md) holds the questions a WebAssembly backend
85//! still has to answer — linear memory or WasmGC, how a partial application is
86//! represented, whether monomorphisation is whole-program — and is unscheduled. Nothing
87//! in this module is a JavaScript decision, and a change that makes one of the facts
88//! above unavailable is a change that closes that ticket's options.
89//!
90//! # What specialisation adds
91//!
92//! [`build`] knows one module and leaves each reference that carried obligations as the typer
93//! solved it. [`specialise`] reads every module of a build, resolves each of them to the
94//! instance's member or to a [`Specialisation`] of the module that uses it, and changes the
95//! modules in place: a [`ReferenceKind::InstanceMember`] or a [`ReferenceKind::Specialised`]
96//! replaces the name and its obligations, and [`Module::specialisations`] holds the copies. A
97//! constrained [`Declaration`] and the members of an instance that has a context stay as they
98//! were written: they are what is copied, and nothing emits them as they stand.
99//! [`initialisation_items`] is the order of the parameterless items once those are among
100//! them. The module doc comment of `specialise` is the account, and
101//! [`GEN-15`](../../docs/tickets/gen-15.md) needs the same pass for a reason of its own.
102//!
103//! # What is not here yet
104//!
105//! One ticket adds to this shape and is deliberately not written into it yet: a self tail
106//! call ([`GEN-6`](../../docs/tickets/gen-6.md)). [`Module`] holds its
107//! declarations in a `Vec` sorted by name, which is a deterministic order and not an
108//! evaluation order; [`Module::initialisation_order`] is the evaluation order, over the
109//! parameterless declarations alone, and [`initialisation_items`] extends it to the items
110//! specialisation adds; `zelkova_js::emit` emits them in it.
111//!
112//! A `case`'s branches keep [`TypedTermKind::Case`]'s own flat shape rather than
113//! growing a tree in place: the typer still wants a flat list, since every branch is
114//! checked against the same scrutinee type and order does not matter to it. The
115//! `decision` module is a second, additional view of the same branches — built from
116//! them on demand rather than stored alongside them — and [`Decision`] is the tree a
117//! backend walks instead of re-deriving, at emission time, which test distinguishes
118//! which branch (`GEN-5`). See that module's doc comment.
119
120use std::collections::HashMap;
121
122use super::canonical::{self, HeadName};
123use super::name::{Name, QualName};
124use super::typer::Type;
125use super::{ModuleName, PackageName};
126use zelkova_syntax::position::NodeSpan;
127use zelkova_syntax::tuple::Tuple;
128
129mod decision;
130pub use decision::{build as decision_tree, Binding, Decision, Occurrence, Outcome, Step};
131
132mod specialise;
133pub use specialise::{
134    initialisation_items, mentioned_by_copies, specialise, Error as SpecialiseError, Item,
135    ModuleErrors, SPECIALISATION_LIMIT,
136};
137
138// ── A module ──────────────────────────────────────────────────────────────────
139
140/// One checked module's emittable shape: what a backend reads that no earlier phase
141/// carried.
142///
143/// Not everything emission needs — `exports` and `marked_unsafe` stay on the
144/// [`canonical::Module`] this was built from, and a backend is handed both halves as a
145/// [`CheckedModule`](crate::CheckedModule). See this module's doc comment.
146#[derive(Debug)]
147pub struct Module {
148    pub name: ModuleName,
149    /// True when this module is a `module foreign` facade: every one of its
150    /// declarations is a signature with no body, and the code behind them is in the
151    /// companion beside it ([Foreign
152    /// interoperability](../../docs/spec/interop.md)).
153    pub foreign: bool,
154    /// The unions this module declares, sorted by name.
155    pub unions: Vec<Union>,
156    /// The declarations this module can emit, sorted by name.
157    ///
158    /// Sorted so that two runs of the compiler over one unchanged module produce the
159    /// same order — `canonical::Module::values` is a `HashMap` and yields none. It is
160    /// not an evaluation order: [`initialisation_order`](Self::initialisation_order) is
161    /// what works out which parameterless declaration has to be initialised before which.
162    ///
163    /// A declaration here may hold a [hole](TypedTermKind::Hole), with an error standing
164    /// behind it, and a backend refuses it.
165    pub declarations: Vec<Declaration>,
166    /// The declarations that have no IR, and therefore cannot be emitted.
167    ///
168    /// A backend handed only [`declarations`](Self::declarations) could not tell a module
169    /// it may emit whole from one that quietly lost a declaration on the way here, which
170    /// is the mistake [`DEC-18` decision
171    /// 1](../../docs/decisions/dec-18.md#1--the-backend-reads-a-typed-ir-and-the-typer-is-what-produces-it)
172    /// is about. Every value of the canonical module, in `values` or in `broken`, is in
173    /// exactly one of the two lists.
174    ///
175    /// Sorted by name, the same as [`declarations`](Self::declarations).
176    pub unchecked: Vec<Unchecked>,
177    /// The instances this module declares, in the order they were written, each with the
178    /// body it was checked with. An instance of another module that this one can use is
179    /// that module's, and is not repeated here.
180    ///
181    /// An instance that failed canonicalization is in no list: it never became a
182    /// [`canonical::Instance`], and the error behind it is canonicalization's.
183    pub instances: Vec<Instance>,
184    /// The names of [`declarations`](Self::declarations) that take no parameter, in the
185    /// order they must be initialised: each only after every parameterless declaration it
186    /// depends on, whether its own body mentions that declaration or reaches it through a
187    /// function it mentions
188    /// (`docs/spec/evaluation-semantics.md#a-binding-with-no-parameters-is-evaluated-once`).
189    /// Empty for a module whose declarations all take parameters, and for a `module
190    /// foreign` facade, whose constants are evaluated on whatever schedule the target
191    /// gives them (`docs/spec/interop.md#facade-constants`).
192    ///
193    /// Sorted so that two runs of the compiler over one unchanged module produce the same
194    /// order, same as [`declarations`](Self::declarations) above — including among
195    /// bindings with no path between them, where dependencies alone leave the order
196    /// unconstrained.
197    ///
198    /// `canonical::initialisation_order` computes it, from the same dependency graph
199    /// `canonical::canonicalize` reads to reject a cycle (`LANG-35`) rather than a second
200    /// one built from the same rule; see that function's doc comment for what it does with
201    /// a module whose cycle was rejected.
202    /// `zelkova_js::emit` is what emits declarations
203    /// in this order — this only computes it.
204    pub initialisation_order: Vec<Name>,
205    /// The copies of constrained declarations and of instance members with a context that
206    /// this module needs, each at one assignment of ground types to its constrained
207    /// variables, in the order [`specialise`] found them.
208    ///
209    /// Empty until [`specialise`] has run over the build: `build` knows one module and a
210    /// specialisation is a fact about the whole of them. A reference to one is
211    /// [`ReferenceKind::Specialised`], and its number is a place in this list.
212    pub specialisations: Vec<Specialisation>,
213}
214
215/// A union declaration: the type a constructor builds, and the constructors that build
216/// it.
217#[derive(Debug, Clone, PartialEq)]
218pub struct Union {
219    /// The union, named by the package and module that declared it.
220    pub name: QualName,
221    /// The type variables the declaration was written with, in order.
222    pub variables: Vec<Name>,
223    /// Its constructors, in declaration order — which is the order
224    /// [`Variant::index`] counts.
225    pub variants: Vec<Variant>,
226}
227
228/// One constructor of a [`Union`].
229#[derive(Debug, Clone, PartialEq, Eq)]
230pub struct Variant {
231    /// The constructor's own name, unqualified: the value of the `$` field on
232    /// JavaScript, and the WIT case name.
233    pub name: Name,
234    /// Its position in the `type` declaration, counted from zero.
235    pub index: usize,
236    /// How many arguments it takes.
237    pub arity: usize,
238}
239
240/// A class required of a type: `Eq Int`, `Comparable a`.
241///
242/// What a constrained name asks of its caller, once the variable its constraint was
243/// written on has been replaced by the type it was used at. A class is always over a
244/// complete type ([`DEC-2` decision
245/// 5](../../docs/decisions/dec-2.md#5--no-higher-kinded-variables)), so a predicate is a
246/// class and a type and never a partial application.
247#[derive(Debug, Clone, PartialEq, Eq, Hash)]
248pub struct Predicate {
249    /// The class, named by the package and module that declared it.
250    pub class: QualName,
251    /// The type it is required of.
252    pub tpe: Type,
253}
254
255/// One `instance` declaration of a module: which class, which type, what it needs of that
256/// type's arguments, and a checked body for each member.
257///
258/// A derived instance is one of these like any other. The bindings it was checked with are
259/// the ones its class's derivation stands for, generated by canonicalization, and nothing
260/// here says they were not written.
261///
262/// The types here and the types inside a member's [`Declaration`] are each their own
263/// inference's. The variables of [`head`](Self::head) are the ones the instance's
264/// [`context`](Self::context) is over; a member's declaration is solved on its own, so
265/// its type and its own context name variables of that solve, and the two are related by
266/// the member's signature at the head and not by sharing variable numbers.
267#[derive(Debug)]
268pub struct Instance {
269    /// The class, named by the package and module that declared it.
270    pub class: QualName,
271    /// The type the instance is for: a declared type applied to a distinct variable per
272    /// parameter, a tuple of distinct variables, or `()`
273    /// ([the head rule](../../docs/spec/type-classes.md#what-an-instance-is-declared-for)).
274    pub head: Type,
275    /// The name at the front of [`head`](Self::head), which with the class identifies the
276    /// instance: two instances of one class whose heads share it are one instance declared
277    /// twice, and a use of a member is answered by the one that matches.
278    pub head_name: HeadName,
279    /// What the instance needs of the head's variables, in the order written.
280    pub context: Vec<Predicate>,
281    /// The bindings that checked, one for each member of the class, sorted by name. Each
282    /// is a [`Declaration`] named for the member, whose [`context`](Declaration::context)
283    /// is the instance's own.
284    pub members: Vec<Declaration>,
285    /// The bindings that did not check, accounted for as [`Module::unchecked`] accounts
286    /// for a value, sorted by name.
287    pub unchecked: Vec<Unchecked>,
288    /// Whether the instance's own check failed: a superclass the instance cannot prove
289    /// at its head. An error stands behind it, and a backend refuses it.
290    pub rejected: bool,
291    /// Where the head line was written, `instance` through `where`.
292    pub span: NodeSpan,
293}
294
295/// One value of a module: what a backend emits as a named binding.
296#[derive(Debug)]
297pub struct Declaration {
298    pub name: Name,
299    /// How many arguments a call site has to supply for the call to be a direct call.
300    ///
301    /// For a declaration with a body this is the number of parameters it was written
302    /// with, which is [`Body::parameters`]'s length — *not* the number of arrows in its
303    /// type. `f : Int -> Int -> Int` written `f a = add a` has arity 1, and a call
304    /// supplying two arguments is one direct call followed by one partial application.
305    ///
306    /// For a facade signature, which has no body to count parameters off, it is the
307    /// number of arrows in the signature: the companion's export [takes a plain parameter
308    /// list](../../docs/spec/interop.md#the-javascript-companion) of exactly that
309    /// length, and a signature with no arrow at all is [a facade
310    /// constant](../../docs/spec/interop.md#facade-constants).
311    pub arity: usize,
312    /// The declaration's own type, as inference solved it — or, for a facade, as the
313    /// signature declares it.
314    pub tpe: Type,
315    /// What the declaration's annotation requires of its type variables, one
316    /// [`Predicate`] per constraint written, in the order written — empty for a
317    /// declaration whose annotation has no `=>`, for every declaration with no
318    /// annotation, and for a facade signature.
319    ///
320    /// Read off the declaration's solved type, as the types on its nodes are: each
321    /// predicate's type is the variable the annotation constrained. The annotation's
322    /// variables are rigid while the body is checked, so it is always a variable of
323    /// [`tpe`](Self::tpe).
324    ///
325    /// A superclass the context implies is not listed.
326    pub context: Vec<Predicate>,
327    /// The parameters and the expression they are in scope over, for a declaration that
328    /// has a body.
329    ///
330    /// `None` is a `module foreign` facade's signature. It is the whole reason this is an
331    /// `Option`: a facade declares what crosses the boundary and the code is in the
332    /// companion, so there is nothing here to emit and
333    /// `zelkova_js::emit` reads the signature
334    /// instead.
335    pub body: Option<Body>,
336    /// Where the declaration was written, annotation and body together.
337    pub span: NodeSpan,
338}
339
340/// A declaration's parameters and the expression they are in scope over.
341#[derive(Debug)]
342pub struct Body {
343    /// The declaration's parameters, outermost first, each with the type inference
344    /// solved for it.
345    pub parameters: Vec<TypeBinder>,
346    /// What the declaration evaluates to once its parameters are bound.
347    pub expression: TypedTerm,
348}
349
350/// A declaration the typer did not type, and which therefore has no IR.
351///
352/// Why is decided in [`build`]. Canonicalization recorded it as broken
353/// ([`canonical::Module::broken`]), or inference reported an error for it
354/// ([`Solved::Rejected`]), and that error is the user's to fix; or the typer walked past
355/// it: a construct the translation cannot represent
356/// ([`Solved::Untranslatable`]), a name the typer's environment does not hold
357/// ([`Solved::UnboundName`]), or a facade declaration with no signature to read. The
358/// second kind is not a mistake in the user's source and not an error, but a gap in
359/// today's typer — unless the declaration also holds a hole, whose error stands behind
360/// it. [`reported`](Self::reported) is the one distinction carried this far,
361/// so that `ERR-8`'s warning about a gap is not also given to a declaration the user has
362/// already been shown an error for.
363#[derive(Debug, Clone, PartialEq)]
364pub struct Unchecked {
365    pub name: Name,
366    /// Where the declaration was written.
367    pub span: NodeSpan,
368    /// Whether an error stands behind this entry: `true` for a declaration
369    /// canonicalization recorded as broken or inference rejected, and for one the typer
370    /// walked past whose body holds a hole (a name that did not resolve, with its error
371    /// reported or standing in the failure that made the scope incomplete); `false` for
372    /// one the typer walked past with no hole in it.
373    pub reported: bool,
374}
375
376// ── Specialisation ────────────────────────────────────────────────────────────
377
378/// A constrained declaration, or a member of an instance with a context, at one assignment
379/// of ground types to its constrained variables: an ordinary declaration of the module that
380/// uses it.
381///
382/// [`specialise`] makes these. The body is a copy of the declaring module's code with the
383/// assignment applied to every type in it, and with each reference that carried obligations
384/// resolved at the types they are now at, so nothing in it asks which instance is meant and
385/// nothing is passed at run time to say
386/// ([`DEC-2` decision 7](../../docs/decisions/dec-2.md#7--dictionaries-are-erased-by-specialisation-not-passed)).
387/// It is placed in the module that uses it and not in the module that declares the function,
388/// because the instance a copy calls may be declared by a module that imports the
389/// declaring one: emitted beside `min`, a copy that called the `compare` of an `App` that
390/// imports `Basics` would make `Basics` import `App`.
391///
392/// Two uses at one key in one module are one specialisation, and two modules that use
393/// one key each hold a copy. For a function that is code written twice and nothing a program
394/// can observe. For a binding with no parameters it is one evaluation for each module that
395/// uses it where [the chapter says
396/// "once"](../../docs/spec/evaluation-semantics.md#a-binding-with-no-parameters-is-evaluated-once),
397/// and a Zelkova value has no identity, so what differs is the work done and never an answer.
398#[derive(Debug)]
399pub struct Specialisation {
400    /// What this is a copy of.
401    pub of: Subject,
402    /// The ground type each constrained variable of the declaration is at, in the order
403    /// the variables first occur in its [`context`](Declaration::context).
404    ///
405    /// Only the variables a constraint is on are in it: nothing a JavaScript module emits
406    /// depends on any other, so a variable with no constraint needs no copy. A target whose
407    /// code does depend on one reads its type off the nodes of
408    /// [`declaration`](Self::declaration), where it is left a variable.
409    pub key: Vec<Type>,
410    /// The copy: the declaring declaration's name and parameters, its type and every type in
411    /// its body with the key applied, an empty [`context`](Declaration::context), and
412    /// [`Declaration::arity`] and [`Declaration::span`] as it was written.
413    pub declaration: Declaration,
414}
415
416/// What a [`Specialisation`] is a copy of.
417#[derive(Debug, Clone, PartialEq, Eq, Hash)]
418pub enum Subject {
419    /// A declaration whose annotation has a constraint, named in full.
420    Declaration(QualName),
421    /// A member of an instance that has a context, which is itself a constrained function:
422    /// what it asks of the head's variables is what the instance's context asks.
423    ///
424    /// An instance is identified by its class and the name at the front of its head
425    /// ([`HeadName`]), so those and the member are the whole of the identity.
426    InstanceMember {
427        class: QualName,
428        head: HeadName,
429        member: Name,
430    },
431}
432
433/// A member of an instance that has no context, which is an ordinary declaration of the
434/// module that declares the instance, emitted once.
435///
436/// A use of a class member at a type that has such an instance is a direct reference to
437/// this, and no other module needs a copy. The function's name is built from the three
438/// things that identify it and from nothing a source file spells: `zelkova_js` writes
439/// `$instance$…`.
440#[derive(Debug, Clone, PartialEq)]
441pub struct InstanceMember {
442    /// The module that declares the instance, which is where the function is.
443    pub module: ModuleName,
444    /// The class, named by the package and module that declared it.
445    pub class: QualName,
446    /// The name at the front of the instance's head.
447    pub head: HeadName,
448    /// The member's own name.
449    pub member: Name,
450    /// How many arguments a call has to supply to be a direct call: the number of
451    /// parameters the instance's binding was written with, as [`Declaration::arity`] counts
452    /// them.
453    pub arity: usize,
454}
455
456// ── Names ─────────────────────────────────────────────────────────────────────
457
458/// A reference to a name, and what kind of name it is.
459///
460/// The kind is the point. `canonical::ExpressionKind` distinguishes a local, a
461/// top-level, an imported name and a constructor, and those are four different things to
462/// emit — a parameter, a binding in this module's scope, a named import, an object with
463/// a `$` field. The spelling left behind once they are flattened to a string is
464/// qualified for some of them and not others, so the distinction cannot be recovered
465/// afterwards.
466#[derive(Debug, Clone, PartialEq)]
467pub struct Reference {
468    /// The spelling inference looks the name up by.
469    ///
470    /// The typer's environment is a `HashMap<String, Type>` keyed bare for a local and,
471    /// for everything else, by the declaration's package and qualified name —
472    /// `test-project:Test.echo` — so this is that key and not a display name. A backend
473    /// reads [`kind`](Self::kind), which says what the name *is*.
474    pub name: String,
475    pub kind: ReferenceKind,
476}
477
478impl Reference {
479    /// A reference to a name bound inside the declaration: a parameter, or a name a
480    /// pattern introduced.
481    pub fn local<S: Into<String>>(name: S) -> Reference {
482        Reference {
483            name: name.into(),
484            kind: ReferenceKind::Local,
485        }
486    }
487}
488
489/// Which of the things a [`Reference`] names: a name bound in the declaration, a
490/// declaration of this module, one of another, or a constructor — and, once [`specialise`]
491/// has run, a specialisation or an instance's member, which are what a name that
492/// asked for an instance becomes.
493#[derive(Debug, Clone, PartialEq)]
494pub enum ReferenceKind {
495    /// A parameter of the enclosing declaration, or a name one of its patterns bound.
496    /// It is in scope for that declaration alone.
497    Local,
498    /// A declaration of the module being compiled, named in full.
499    TopLevel(QualName),
500    /// A declaration of another module, named in full: a named import of whatever that
501    /// module emitted.
502    ///
503    /// The typer checks it against the type that module's interface declares. The
504    /// [`PackageName`] is the package that declares the module, which is where the
505    /// import is read from: a module's name says which file it is within its package,
506    /// and the package says which package's directory holds that file.
507    ///
508    /// The `usize` is the declaration's arity, read from the same interface
509    /// ([`Interface::arities`](crate::Interface::arities)): the count a call has
510    /// to supply to be a direct call, exactly as [`Declaration::arity`] is for a
511    /// [`TopLevel`](Self::TopLevel) name. A module exports each declaration as the
512    /// plain n-ary function it emitted, so an importer needs the arity to call it.
513    Foreign(QualName, PackageName, usize),
514    /// A union constructor: it builds a tagged value rather than reading a binding.
515    Constructor(Constructor),
516    /// A [`Specialisation`] of this module: a place in [`Module::specialisations`]. What
517    /// [`specialise`] makes of a reference to a constrained declaration, and of a class
518    /// member whose instance has a context.
519    Specialised(usize),
520    /// A member of an instance that has no context ([`InstanceMember`]). What
521    /// [`specialise`] makes of a class member used at a type that has one.
522    ///
523    /// Boxed: it names a class, a head and a module in full, and would make every other kind
524    /// of reference as large.
525    InstanceMember(Box<InstanceMember>),
526}
527
528/// A constructor, and its place in the declaration that declares it.
529///
530/// Both targets need all four: the name is the `$` field's value and the WIT case name,
531/// the index is the case's position in the `variant`, the arity says how many arguments
532/// a saturated application supplies, and the union is which declaration the case belongs
533/// to.
534#[derive(Debug, Clone, PartialEq, Eq)]
535pub struct Constructor {
536    /// The union this constructor builds, named by the package and module that
537    /// declared it.
538    pub union: QualName,
539    /// The constructor's own name, unqualified.
540    pub name: Name,
541    /// Its position in that union's declaration, counted from zero.
542    pub index: usize,
543    /// How many arguments it takes.
544    pub arity: usize,
545}
546
547/// Whether an application supplies every argument its callee takes.
548///
549/// A saturated application at a callee whose arity is known emits as a direct call;
550/// everything else goes through the runtime's `$curry` helper ([`DEC-18` decision
551/// 3](../../docs/decisions/dec-18.md#3--a-function-emits-as-a-plain-n-ary-function-and-currying-is-a-runtime-helper)).
552/// An [`Apply`](TermKind::Apply) node supplies one argument, so this is a property of a
553/// node within the application spine and not of the spine as a whole: `f a b` at a
554/// two-parameter `f` is [`Partial`](Saturation::Partial) on the inner node and
555/// [`Saturated`](Saturation::Saturated) on the outer one.
556#[derive(Debug, Clone, Copy, PartialEq, Eq)]
557pub enum Saturation {
558    /// This node supplies the last of the arguments the callee takes.
559    Saturated,
560    /// It does not — either because arguments are still missing, because the spine has
561    /// already run past the callee's arity, or because the callee has no arity at all. A
562    /// callee that is a parameter, or any other expression that is not a name, is a value
563    /// rather than a declaration and has no arity.
564    Partial,
565}
566
567// ── Terms ─────────────────────────────────────────────────────────────────────
568
569/// An untyped term, and where the expression it was translated from was written.
570///
571/// In zelkova that source is the canonical AST. The span is what every constraint
572/// generated from this term inherits, and therefore what a type error draws its
573/// caret under; [`NodeSpan::none`] — a term built by hand, in a test — costs nothing
574/// but the caret.
575#[derive(Debug, Clone)] // TODO Remove clone when not needed anymore
576pub struct Term {
577    pub span: NodeSpan,
578    pub kind: TermKind,
579}
580
581impl Term {
582    /// A term with no position: hand-built, never translated from source.
583    #[cfg(test)]
584    pub(crate) fn bare(kind: TermKind) -> Term {
585        Term {
586            span: NodeSpan::none(),
587            kind,
588        }
589    }
590}
591
592#[derive(Debug, Clone)] // TODO Remove clone when not needed anymore
593pub enum TermKind {
594    // literals
595    /// An integer literal, at the width [`Int` *is*](../../docs/spec/evaluation-semantics.md#numbers)
596    /// ([`DEC-16`](../../docs/decisions/dec-16.md)). Inference never reads the value
597    /// — every integer literal is an `Int` whatever its value — but code generation does.
598    Int(i64),
599    Char(char),
600    /// A string literal's value, its escape sequences already read.
601    String(String),
602    Float(f64),
603    Identifier(Reference), // VAR
604    Fun {
605        param: String,
606        body: Box<Term>,
607    },
608    Apply {
609        fun: Box<Term>,
610        arg: Box<Term>,
611        saturation: Saturation,
612    },
613    If {
614        cond: Box<Term>,
615        true_branch: Box<Term>,
616        false_branch: Box<Term>,
617    },
618    Let {
619        binding: String,
620        value: Box<Term>,
621        body: Box<Term>,
622    },
623    Tuple(Tuple<Term>),
624    /// The unit value, `()`.
625    Unit,
626    Case {
627        scrutinee: Box<Term>,
628        branches: Vec<(TermPattern, Box<Term>)>,
629        /// What the source wrote that this match was built from.
630        form: CaseForm,
631    },
632    /// A name that did not resolve, translated from `canonical::ExpressionKind::Hole`.
633    /// Inference gives it a fresh type variable and constrains nothing by it, so its type
634    /// is whatever the node around it requires ([`DEC-23` decision
635    /// 6](../../docs/decisions/dec-23.md#6--an-unresolved-name-inside-a-sound-body-is-a-typed-hole)).
636    Hole,
637    /// A [record](../../docs/spec/records.md#building-a-record), its fields in the order
638    /// they were written. Only its type is a set of fields; the term keeps the order,
639    /// since [fields are evaluated in it](../../docs/spec/evaluation-semantics.md#order-of-evaluation).
640    Record(Vec<Field<Term>>),
641    /// An [update](../../docs/spec/records.md#updating-a-record): the record updated, and
642    /// the fields replaced in it in the order they were written.
643    Update {
644        record: Box<Term>,
645        fields: Vec<Field<Term>>,
646    },
647    /// A [field access](../../docs/spec/records.md#reading-a-field), `record.label`.
648    Access {
649        record: Box<Term>,
650        label: Name,
651        /// Where the label alone was written.
652        label_span: NodeSpan,
653    },
654    /// An [accessor](../../docs/spec/records.md#the-accessor), `.label`: the function
655    /// reading that field of whichever record it is applied to.
656    Accessor {
657        label: Name,
658        /// Where the label alone was written; the term's own span covers the `.` too.
659        label_span: NodeSpan,
660    },
661}
662
663/// One field of a record or an update — [`TermKind::Record`], [`TermKind::Update`] and
664/// their [typed](TypedTermKind::Record) counterparts — over the term type `T` of the
665/// tree it is in; and, as a `Field<SubPattern>`, one entry of a
666/// [record pattern](TermPatternKind::Record).
667#[derive(Debug, Clone)]
668pub struct Field<T> {
669    pub label: Name,
670    /// Where the label alone was written; the value carries its own span. For a record
671    /// pattern's `{ label }` shorthand the two are the same text.
672    pub label_span: NodeSpan,
673    pub value: T,
674}
675
676/// What the source wrote that a `Case` term was built from.
677///
678/// A parameter written as a pattern — `first (x, _) = x` — is a match like any other,
679/// and it is translated as one: the parameter becomes a plain one named by
680/// `pattern_parameter`, and the declaration's body a single-branch `Case` on it. So a
681/// backend lowers a pattern in either position the same way, and the term language keeps
682/// one binding construct, [`TermKind::Fun`], that only ever binds a name.
683///
684/// This is what lets a diagnostic about the match speak about what the user wrote: a
685/// type error in a parameter's pattern names the parameter and not a `case`, one in the
686/// body under it names the declaration's body and not a `case` branch, and a
687/// backend refusing the match can say which of the two it is refusing.
688#[derive(Debug, Clone, Copy, PartialEq, Eq)]
689pub enum CaseForm {
690    /// A `case … of` expression.
691    Expression,
692    /// A parameter the declaration wrote as a pattern. The `Case` has exactly one
693    /// branch, and its scrutinee is the local reference `pattern_parameter` names.
694    Parameter,
695}
696
697/// The name a parameter written as a pattern is bound under: `$` and the parameter's
698/// position in the declaration, counted from zero — `$0`, `$1`, ….
699///
700/// It is the scrutinee of the [`CaseForm::Parameter`] match the parameter becomes, and
701/// nothing else refers to it. It cannot meet a name the source wrote, because a Zelkova
702/// identifier never contains a `$`, and it cannot meet another parameter's, because two
703/// parameters of one declaration never share a position. A declaration's parameters are
704/// the only names its body is in scope of besides the ones a pattern binds, which are
705/// source names, so that is every name it could meet.
706pub(crate) fn pattern_parameter(position: usize) -> String {
707    format!("${}", position)
708}
709
710/// Simplified pattern used inside a [`Term`], and where it was written.
711///
712/// Same shape as the parser and canonical ASTs — a span beside a kind — so a reader
713/// matches on `&p.kind`.
714#[derive(Debug, Clone)]
715pub struct TermPattern {
716    pub span: NodeSpan,
717    pub kind: TermPatternKind,
718}
719
720#[derive(Debug, Clone)]
721pub enum TermPatternKind {
722    /// Matches anything without binding.
723    Anything,
724    /// Binds the scrutinee type to this name.
725    Bind(String),
726    /// Matches one specific value; constrains the scrutinee to the type carried here
727    /// and, unlike the type alone, says which value of it.
728    ///
729    /// `tpe` is a [`Type::Literal`] for an `Int`, `Float`, `Char` or `String` pattern, and the
730    /// [`Type::Adt`] `typer::bool_type` builds for a `Basics.True`/`Basics.False` one —
731    /// `Bool` is the union `Basics` declares, not a literal type. Two patterns of that
732    /// same kind — two `Int`s, say — share that one type, so `value` is what tells `1`
733    /// from `2`, or `True` from `False`; [`decision_tree`] reads it to build the [`Outcome`] a
734    /// [`Decision::Test`] checks for.
735    Literal { tpe: Type, value: LiteralValue },
736    /// Matches an ADT constructor; carries the fresh ADT args and one sub-pattern per
737    /// argument.
738    Constructor {
739        /// Which constructor, and where it sits in its declaration. `ctor.union` is the
740        /// name the [`Type::Adt`] this pattern constrains the scrutinee to is built from.
741        ctor: Constructor,
742        adt_args: Vec<Type>,
743        /// One per argument the pattern writes, in order, so an argument's place in
744        /// this `Vec` is its position in the constructor.
745        args: Vec<SubPattern>,
746    },
747    /// Matches a tuple of two or three elements; carries one sub-pattern per element.
748    Tuple {
749        /// One per element, in order. The matched value's tuple type is built from
750        /// their types.
751        elements: Tuple<SubPattern>,
752    },
753    /// Matches the one value of the unit type: constrains the matched value to
754    /// [`Type::Unit`] and binds nothing. Since that
755    /// type has a single value, [`decision_tree`] builds no test for it.
756    Unit,
757    /// A constructor pattern whose constructor did not resolve, translated from
758    /// `canonical::PatternKind::Hole`; carries one sub-pattern per argument written after
759    /// it, each at a fresh type.
760    ///
761    /// It places no constraint on the matched value, since nothing says what type the
762    /// constructor would have built, and binds what its arguments bind, as a constructor's
763    /// do. [`decision_tree`] tests nothing for it, as for
764    /// [`Anything`](Self::Anything), and no backend emits a tree built from one.
765    Hole { args: Vec<SubPattern> },
766    /// A [record pattern](../../docs/spec/records.md#record-patterns): one entry per label
767    /// it writes, in the order written, each the label, where the label alone was written,
768    /// and the sub-pattern that field's value is matched against, at the field's type.
769    /// The `{ label }` shorthand arrives here as `label = label`.
770    ///
771    /// It names a **subset** of the record's fields, so no record type is built from
772    /// its entries: the type of the value it is matched against comes from elsewhere in
773    /// the declaration, and each entry is read against it once it is known
774    /// (`typer::FieldConstraint`). A record has one shape, so [`decision_tree`] tests
775    /// nothing for the pattern itself and goes on to each entry by a
776    /// [`Step::Field`]. It is refutable exactly when one of its entries is, and nothing
777    /// reads it as irrefutable for being a record.
778    Record { fields: Vec<Field<SubPattern>> },
779}
780
781/// A pattern written in a position inside another one — a constructor's argument, a
782/// tuple's element or a record pattern's entry — and the type of the value found there.
783///
784/// The position's type travels with the pattern because a sub-pattern has no scrutinee
785/// of its own to take one from: a variable written there binds a value of this type, and
786/// any other pattern written there constrains this type the way a `case` branch's
787/// pattern constrains the scrutinee's.
788///
789/// The pattern may be any [`TermPatternKind`], itself holding sub-patterns to any depth:
790/// `typer::translate_pattern` translates one written here as it does one at the top.
791#[derive(Debug, Clone)]
792pub struct SubPattern {
793    pub tpe: Type,
794    pub pattern: TermPattern,
795}
796
797impl TermPattern {
798    /// Every name this pattern binds, at any depth, in source order, with the type of
799    /// the value it binds. A variable written at the top is bound at `scrutinee`, the
800    /// type of the value the pattern is matched against.
801    pub(crate) fn bindings(&self, scrutinee: &Type) -> Vec<(String, Type)> {
802        let mut bindings = Vec::new();
803        self.collect_bindings(scrutinee, &mut bindings);
804        bindings
805    }
806
807    fn collect_bindings(&self, tpe: &Type, bindings: &mut Vec<(String, Type)>) {
808        match &self.kind {
809            TermPatternKind::Anything | TermPatternKind::Literal { .. } | TermPatternKind::Unit => {
810            }
811            TermPatternKind::Bind(name) => bindings.push((name.clone(), tpe.clone())),
812            TermPatternKind::Constructor { args, .. } | TermPatternKind::Hole { args } => {
813                for arg in args {
814                    arg.pattern.collect_bindings(&arg.tpe, bindings);
815                }
816            }
817            TermPatternKind::Tuple { elements } => {
818                for element in elements.iter() {
819                    element.pattern.collect_bindings(&element.tpe, bindings);
820                }
821            }
822            // At the field's type, which is the entry's own: a name bound here is not
823            // known to be of any type until the record type is, and is solved when the
824            // entry is read against it.
825            TermPatternKind::Record { fields } => {
826                for field in fields {
827                    field
828                        .value
829                        .pattern
830                        .collect_bindings(&field.value.tpe, bindings);
831                }
832            }
833        }
834    }
835}
836
837/// The concrete value a [`TermPatternKind::Literal`] pattern tests for.
838///
839/// The pattern's own `tpe` cannot tell `1` from `2`, or `'a'` from `'b'`: both share one
840/// type, and only this says which value the scrutinee has to equal. A `Float` is equal
841/// to a scrutinee as IEEE 754 compares them ([What structural equality
842/// computes](../../../docs/spec/evaluation-semantics.md#what-structural-equality-computes)),
843/// so `0.0` equals `-0.0`. The compiler accepts no negative pattern literal, so no
844/// pattern holds `-0.0`; no literal is `nan`, so a `nan` scrutinee equals none. A `Bool` is tested
845/// by its value too: `Basics`' own `True`/`False` constructors arrive here as a
846/// `Bool(..)`, never as a [`TermPatternKind::Constructor`] (`typer::translate_pattern`
847/// does the normalising).
848#[derive(Debug, Clone, PartialEq)]
849pub enum LiteralValue {
850    Bool(bool),
851    Int(i64),
852    Float(f64),
853    Char(char),
854    String(String),
855}
856
857#[derive(Debug, Clone)]
858/// Bind a name and a type together.
859/// Used in function and let expression
860pub struct TypeBinder {
861    pub name: String,
862    pub tpe: Type,
863}
864
865impl TypeBinder {
866    pub(crate) fn new(name: String, tpe: Type) -> TypeBinder {
867        TypeBinder { name, tpe }
868    }
869}
870
871/// Like a [Term] but with an associated [Type], and still with its position.
872/// Any term introducing a name will have a TypeBinder instead.
873///
874/// This is what [`typer::type_check`](crate::typer::type_check) hands back for
875/// a declaration it typed, and the types on it are the *solved* ones: `infer_annotated`
876/// applies `unify`'s final substitution to every node before returning. Between
877/// `annotate` and that point they are inference variables and mean nothing on their own.
878#[derive(Debug)]
879pub struct TypedTerm {
880    pub span: NodeSpan,
881    pub tpe: Type,
882    pub kind: TypedTermKind,
883}
884
885#[derive(Debug)]
886pub enum TypedTermKind {
887    /// See [`TermKind::Int`] for the width.
888    Int(i64),
889    Char(char),
890    /// See [`TermKind::String`].
891    String(String),
892    Float(f64),
893    /// A name, and — when its type has a context — what that context asks of the type
894    /// this use gave it.
895    Identifier {
896        reference: Reference,
897        /// One [`Predicate`] per constraint of the name's context, in the order its
898        /// annotation wrote them, with the final substitution applied. A class member's
899        /// context is its class: `eq` at `Int` carries `Eq Int`. Empty for a name whose
900        /// type has none, which is every local, every constructor and every value
901        /// declared without a constraint.
902        context: Vec<Predicate>,
903    },
904    Fun {
905        param: TypeBinder,
906        body: Box<TypedTerm>,
907    },
908    Apply {
909        fun: Box<TypedTerm>,
910        arg: Box<TypedTerm>,
911        saturation: Saturation,
912    },
913    If {
914        cond: Box<TypedTerm>,
915        true_branch: Box<TypedTerm>,
916        false_branch: Box<TypedTerm>,
917    },
918    Let {
919        binding: TypeBinder,
920        value: Box<TypedTerm>,
921        body: Box<TypedTerm>,
922    },
923    Tuple(Tuple<TypedTerm>),
924    /// The unit value, `()`. Its type is always [`Type::Unit`].
925    ///
926    /// `zelkova_js::emit` emits it as `undefined`
927    /// ([The unit value crosses as
928    /// `undefined`](../../docs/spec/interop.md#the-unit-value-crosses-as-undefined)).
929    Unit,
930    Case {
931        scrutinee: Box<TypedTerm>,
932        branches: Vec<(TermPattern, Box<TypedTerm>)>,
933        /// See [`TermKind::Case`].
934        form: CaseForm,
935    },
936    /// A name that did not resolve ([`TermKind::Hole`]). Its type is the one inference
937    /// solved for its position, and is an unsolved variable when nothing around it
938    /// constrains it.
939    ///
940    /// An error stands behind every hole, so a declaration holding one is never emitted:
941    /// `zelkova_js::emit` refuses it by name.
942    Hole,
943    /// A record ([`TermKind::Record`]), its fields in the order they were written. Its
944    /// type is the [`Type::Record`] of its fields' types, which has no order.
945    Record(Vec<Field<TypedTerm>>),
946    /// An update ([`TermKind::Update`]). Its type is the type of `record`.
947    Update {
948        record: Box<TypedTerm>,
949        fields: Vec<Field<TypedTerm>>,
950    },
951    /// A field access ([`TermKind::Access`]). Its type is the field's; the record's
952    /// type, a [`Type::Record`] holding `label`, is on `record`.
953    Access {
954        record: Box<TypedTerm>,
955        label: Name,
956        label_span: NodeSpan,
957    },
958    /// An accessor ([`TermKind::Accessor`]). Its type is a function from the record
959    /// type it reads to the field's type.
960    Accessor {
961        label: Name,
962        label_span: NodeSpan,
963    },
964}
965
966// ── What the typer answers with ───────────────────────────────────────────────
967
968/// What the typer has to say about one declaration.
969///
970/// A phase that answers with types has to answer for *every* declaration it was given,
971/// including the ones it could not type: a caller handed only the ones that worked
972/// cannot tell a declaration the typer verified from one it walked past, and emitting
973/// code for the second is a miscompile. So each way a declaration goes untyped gets a
974/// variant, and [`typer::type_check_recovering`](crate::typer::type_check_recovering)
975/// returns one entry per declaration either way.
976#[derive(Debug)]
977pub enum Solved {
978    /// The declaration's typed term, with the final substitution applied to every node
979    /// — the *zonk*. Its own `tpe` is the declaration's type; each node below it
980    /// carries the type inference solved for that sub-expression.
981    ///
982    /// Boxed because a term carries a whole [`QualName`] — package included — for every
983    /// union and constructor it names, and every other variant would otherwise pay for
984    /// its size.
985    ///
986    /// The term may hold a [hole](TypedTermKind::Hole), with an error standing behind it,
987    /// and a backend refuses it.
988    Typed {
989        term: Box<TypedTerm>,
990        /// What the declaration's annotation required of its type variables, with the
991        /// final substitution applied: [`Declaration::context`].
992        context: Vec<Predicate>,
993    },
994    /// A declaration of a `module foreign` facade, whose body is a synthetic
995    /// placeholder rather than anything the user wrote. Nothing about it is inferred.
996    ///
997    /// This variant carries nothing, so [`Solved::typed`] answers `None` for it: the
998    /// declaration's type is the signature the facade declares, and it stays where
999    /// canonicalization put it, on `canonical::Value::TypedValue`'s `tpe`. A consumer
1000    /// reading these entries is walking the same `canonical::Module` the map was
1001    /// solved from — `type_check` takes one and keys the map the way its `values`
1002    /// is keyed — so the signature is one lookup away, and repeating it here would be
1003    /// a second copy of it rather than something inference established. [`build`] is
1004    /// what reads it back out.
1005    NoBody,
1006    /// `value_to_term_and_annotation` could not translate the declaration into the
1007    /// typer's term language: a `VarKernel` reference, or a constructor naming a union
1008    /// the typer was given no declaration of.
1009    /// Nothing about the declaration was checked.
1010    ///
1011    /// Not an [`Error`](crate::typer::Error): it is a gap in the typer rather
1012    /// than a mistake in the source. What it wants is a warning, which the compiler does not have yet (`ERR-8`, see
1013    /// `docs/tickets/README.md`) — hence the span, so that the warning has a caret the
1014    /// day it exists. *Which* of the constructs tripped it is not carried:
1015    /// `value_to_term_and_annotation` answers `Option`, so the reason does not survive
1016    /// the return.
1017    Untranslatable {
1018        /// Where the declaration was written, annotation and body together — the only
1019        /// position available, since the construct that stopped the translation is not
1020        /// reported back.
1021        span: NodeSpan,
1022    },
1023    /// Inference reached a name the typer's environment does not hold, and nothing
1024    /// about the declaration was checked.
1025    ///
1026    /// That environment holds a declared type for every value in reach that has one: the
1027    /// values and constructors every imported interface exposes, and this module's own
1028    /// constructors and annotated declarations. A declaration of this module
1029    /// written without an annotation has no declared type, and a name reaching one
1030    /// lands here. That is not a mistake in the source, which is why this is not an
1031    /// [`Error`](crate::typer::Error) either. A name that genuinely does not
1032    /// exist is caught earlier, by canonicalization, as
1033    /// `canonical::Error::VariableNotFound`, with a caret under the name.
1034    UnboundName {
1035        /// The name as inference looked it up.
1036        name: String,
1037        /// Where it was written.
1038        span: NodeSpan,
1039    },
1040    /// Inference reported an error for this declaration.
1041    ///
1042    /// The error itself is in [`TypeCheck::errors`](crate::typer::TypeCheck::errors),
1043    /// beside the map this entry is in. The entry is what keeps the declaration from
1044    /// being merely absent, so a module with a type error still answers for every
1045    /// declaration it holds.
1046    Rejected,
1047}
1048
1049impl Solved {
1050    /// The typed term, for a declaration that has one.
1051    pub fn typed(&self) -> Option<&TypedTerm> {
1052        match self {
1053            Solved::Typed { term, .. } => Some(term.as_ref()),
1054            _ => None,
1055        }
1056    }
1057}
1058
1059/// What the typer has to say about one `instance` declaration: the type it is for, what
1060/// it needs, and an answer for each binding of its body.
1061#[derive(Debug)]
1062pub struct SolvedInstance {
1063    /// The type the instance is for, over variables of its own: [`Instance::head`].
1064    pub head: Type,
1065    /// What the instance needs of the head's variables: [`Instance::context`].
1066    pub context: Vec<Predicate>,
1067    /// An answer for every binding of the instance, by the member it defines, in the
1068    /// order the instance holds them.
1069    pub bindings: Vec<(Name, Solved)>,
1070    /// Whether the instance's own check failed: [`Instance::rejected`].
1071    pub rejected: bool,
1072}
1073
1074// ── Building a module ─────────────────────────────────────────────────────────
1075
1076/// Turn a checked module and what the typer solved for it into the IR a backend reads.
1077///
1078/// `solved` and `instances` are consumed rather than borrowed: a [`Declaration`] owns its
1079/// body, and the only other holder of these terms is the caller that just received them.
1080///
1081/// Every value of `module`, in [`values`](canonical::Module::values) or in
1082/// [`broken`](canonical::Module::broken), ends up in exactly one of
1083/// [`Module::declarations`] and [`Module::unchecked`] — see the second field for why
1084/// nothing may merely go missing. A broken one is always unchecked, with an error
1085/// reported behind it: canonicalization's, or the syntax error of a declaration chunk
1086/// that did not parse.
1087///
1088/// `instances` is one [`SolvedInstance`] for each of the module's
1089/// [`instances`](canonical::Module::instances), in the same order. Every binding of an
1090/// instance is accounted for the way a value is: in the instance's
1091/// [`members`](Instance::members) or in its [`unchecked`](Instance::unchecked).
1092pub fn build(
1093    module: &canonical::Module,
1094    solved: HashMap<Name, Solved>,
1095    instances: Vec<SolvedInstance>,
1096) -> Module {
1097    let mut unions: Vec<Union> = module
1098        .types
1099        .iter()
1100        .map(|(name, union)| Union {
1101            name: module.name.qualify_name(name),
1102            variables: union.variables.clone(),
1103            variants: variants_of(union),
1104        })
1105        .collect();
1106    unions.sort_by(|left, right| {
1107        left.name
1108            .to_name()
1109            .as_str()
1110            .cmp(right.name.to_name().as_str())
1111    });
1112
1113    // Type variables in a facade signature are numbered from here. Each signature is
1114    // translated on its own and is never unified with anything, so the numbering only
1115    // has to be consistent within one declaration.
1116    let mut counter = 0u32;
1117
1118    let mut solved = solved;
1119    let mut names: Vec<&Name> = module.values.keys().collect();
1120    names.sort_by(|left, right| left.as_str().cmp(right.as_str()));
1121
1122    let mut declarations = Vec::new();
1123    let mut unchecked = Vec::new();
1124
1125    for name in names {
1126        let value = &module.values[name];
1127
1128        match declare(module, name, value, solved.remove(name), &mut counter) {
1129            Ok(declaration) => declarations.push(declaration),
1130            Err(entry) => unchecked.push(entry),
1131        }
1132    }
1133
1134    // A broken declaration has no canonical form for the typer to have read, and the
1135    // error behind it — canonicalization's, or a syntax error — is the caller's to report.
1136    unchecked.extend(module.broken.iter().map(|broken| Unchecked {
1137        name: broken.name.clone(),
1138        span: broken.span,
1139        reported: true,
1140    }));
1141    unchecked.sort_by(|left, right| left.name.as_str().cmp(right.name.as_str()));
1142
1143    let mut solved_instances = instances.into_iter();
1144    let instances = module
1145        .instances
1146        .iter()
1147        .map(|instance| build_instance(module, instance, solved_instances.next(), &mut counter))
1148        .collect();
1149
1150    let initialisation_order = canonical::initialisation_order(module);
1151
1152    Module {
1153        name: module.name.clone(),
1154        foreign: module.binding_foreign,
1155        unions,
1156        declarations,
1157        unchecked,
1158        instances,
1159        initialisation_order,
1160        specialisations: Vec::new(),
1161    }
1162}
1163
1164/// One value of `module`, as the declaration a backend emits or the entry saying why it
1165/// has none. `entry` is what the typer answered for it.
1166fn declare(
1167    module: &canonical::Module,
1168    name: &Name,
1169    value: &canonical::Value,
1170    entry: Option<Solved>,
1171    counter: &mut u32,
1172) -> Result<Declaration, Unchecked> {
1173    let span = value.span();
1174    let unchecked = |reported| Unchecked {
1175        name: name.clone(),
1176        span,
1177        reported,
1178    };
1179
1180    match entry {
1181        Some(Solved::Typed { term, context }) => {
1182            let tpe = term.tpe.clone();
1183            let (parameters, expression) = peel(*term, value.arity());
1184
1185            Ok(Declaration {
1186                name: name.clone(),
1187                arity: parameters.len(),
1188                tpe,
1189                context,
1190                body: Some(Body {
1191                    parameters,
1192                    expression,
1193                }),
1194                span,
1195            })
1196        }
1197        // A facade signature: the type is the one canonicalization recorded, and the
1198        // arity is what the companion's parameter list has to be. A facade's signature
1199        // carries no constraint ([`canonical::Error::FacadeConstrained`]), so there is
1200        // no context.
1201        Some(Solved::NoBody) => match facade_signature(value, counter) {
1202            Some(tpe) => Ok(Declaration {
1203                name: name.clone(),
1204                arity: module.emitted_arity(value),
1205                tpe,
1206                context: Vec::new(),
1207                body: None,
1208                span,
1209            }),
1210            None => Err(unchecked(false)),
1211        },
1212        // The error inference reported for it is the caller's to report.
1213        Some(Solved::Rejected) => Err(unchecked(true)),
1214        // The typer walked past it. A name that did not resolve is a hole in the body,
1215        // and its error stands behind the declaration whatever else kept the typer from
1216        // typing it, so the entry is `reported` all the same
1217        // ([`DEC-23` decision 5](../../../docs/decisions/dec-23.md)).
1218        Some(Solved::Untranslatable { .. }) | Some(Solved::UnboundName { .. }) => {
1219            Err(unchecked(value.holds_hole()))
1220        }
1221        // Impossible today, since the typer answers for every value it was given.
1222        None => Err(unchecked(false)),
1223    }
1224}
1225
1226/// One instance of `module`, with the answer the typer gave for each of its bindings.
1227///
1228/// `solved` is `None` only for a caller that did not run the typer over the module, and
1229/// then every binding is unchecked and the instance's head is read off its declaration.
1230fn build_instance(
1231    module: &canonical::Module,
1232    instance: &canonical::Instance,
1233    solved: Option<SolvedInstance>,
1234    counter: &mut u32,
1235) -> Instance {
1236    let signature = &instance.signature;
1237
1238    let (head, context, bindings, rejected) = match solved {
1239        Some(solved) => (
1240            solved.head,
1241            solved.context,
1242            solved.bindings,
1243            solved.rejected,
1244        ),
1245        None => (
1246            crate::typer::instance_head_type(&signature.head, &mut HashMap::new(), counter),
1247            Vec::new(),
1248            Vec::new(),
1249            false,
1250        ),
1251    };
1252
1253    let mut answers: HashMap<Name, Solved> = bindings.into_iter().collect();
1254    let mut members = Vec::new();
1255    let mut unchecked = Vec::new();
1256
1257    for value in &instance.bindings {
1258        let name = value_name(value);
1259
1260        match declare(module, name, value, answers.remove(name), counter) {
1261            Ok(declaration) => members.push(declaration),
1262            Err(entry) => unchecked.push(entry),
1263        }
1264    }
1265
1266    members.sort_by(|left, right| left.name.as_str().cmp(right.name.as_str()));
1267    unchecked.sort_by(|left, right| left.name.as_str().cmp(right.name.as_str()));
1268
1269    Instance {
1270        class: signature.class.clone(),
1271        head,
1272        head_name: signature.head.name(),
1273        context,
1274        members,
1275        unchecked,
1276        rejected,
1277        span: signature.span,
1278    }
1279}
1280
1281/// The name a value declares.
1282fn value_name(value: &canonical::Value) -> &Name {
1283    match value {
1284        canonical::Value::Value { name, .. } | canonical::Value::TypedValue { name, .. } => name,
1285    }
1286}
1287
1288/// A union's constructors, each with the position and the argument count both targets
1289/// need.
1290pub(crate) fn variants_of(union: &canonical::UnionType) -> Vec<Variant> {
1291    union
1292        .variants
1293        .iter()
1294        .enumerate()
1295        .map(|(index, ctor)| Variant {
1296            name: ctor.name.clone(),
1297            index,
1298            arity: ctor.type_parameters.len(),
1299        })
1300        .collect()
1301}
1302
1303/// Split `arity` parameters off the front of a typed term.
1304///
1305/// `value_to_term_and_annotation` wraps a declaration's body in one `Fun` per parameter,
1306/// so the first `arity` nodes of the spine are exactly those parameters and nothing else
1307/// builds a `Fun` — the language has no lambda. Stopping early on anything that is not a
1308/// `Fun` keeps a term that somehow disagreed with its declaration from being read past
1309/// its end; the parameters handed back are the ones that were really there, which is why
1310/// [`Declaration::arity`] is their count.
1311fn peel(term: TypedTerm, arity: usize) -> (Vec<TypeBinder>, TypedTerm) {
1312    let mut parameters = Vec::with_capacity(arity);
1313    let mut term = term;
1314
1315    while parameters.len() < arity {
1316        let TypedTerm { span, tpe, kind } = term;
1317
1318        match kind {
1319            TypedTermKind::Fun { param, body } => {
1320                parameters.push(param);
1321                term = *body;
1322            }
1323            kind => {
1324                term = TypedTerm { span, tpe, kind };
1325                break;
1326            }
1327        }
1328    }
1329
1330    (parameters, term)
1331}
1332
1333/// The type of a facade's signature, when it has one to read.
1334///
1335/// Its arity is not read here: a facade declaration has no parameters to count — it is a
1336/// signature and a synthetic body — and [`canonical::Module::emitted_arity`] counts the
1337/// arrows of the type it declares instead, since the companion's export takes a parameter
1338/// list of that length and no arrow at all is [a facade
1339/// constant](../../docs/spec/interop.md#facade-constants). That is the count a module
1340/// importing the facade reads from its interface too.
1341///
1342/// `None` is a signature whose type the typer cannot read, which none is today:
1343/// `typer::canonical_type_to_typer_type` reads every canonical type, a record type
1344/// included. A declaration carrying no annotation also answers `None`, which nothing
1345/// produces today — a facade's declarations are signatures. `build` records either as an
1346/// [`Unchecked`] with `reported: false`, since no error stands behind it.
1347fn facade_signature(value: &canonical::Value, counter: &mut u32) -> Option<Type> {
1348    match value {
1349        canonical::Value::Value { .. } => None,
1350        canonical::Value::TypedValue { tpe, .. } => {
1351            let mut variables = HashMap::new();
1352            crate::typer::canonical_type_to_typer_type(tpe, &mut variables, counter)
1353        }
1354    }
1355}