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}