zelkova_compiler/typer/mod.rs
1//! This module contains the type checker pass of the language
2//!
3//! It works with the source AST and will perform two jobs:
4//! - type checks the different declarations and expression
5//! - infer the types when not declared in the source
6//!
7//! I have no idea how that works; so bear with me while I explore
8//! the space, make mistake and (hopefully) learn something :)
9//!
10//! Some papers on type inference:
11//! - <http://steshaw.org/hm/hindley-milner.pdf>
12//! - <https://pdfs.semanticscholar.org/8983/233b3dff2c5b94efb31235f62bddc22dc899.pdf>
13//! - <http://gallium.inria.fr/~fpottier/publis/fpottier-elaboration.pdf>
14//! - <http://gallium.inria.fr/~fpottier/publis/emlti-final.pdf>
15//!
16//! A type inference problem consists of a type environment Γ , an expression t, and a type T of kind ?
17//!
18//! Constraint generation rules:
19//!
20//! - Equation 1: ⟦x : T⟧ = x ≼ T
21//! "x has type T if and only if T is an instance of the type scheme associated with x"
22//! Important part: There is no relation to the typing environment Γ, instead x appears free (and will be bound to Γ later)
23//!
24//! - Equation 2: ⟦λz.t : T⟧ = ∃X1X2.(let z : X1 in ⟦t : X2⟧ ∧ X1 → X2 ≤ T)
25//! "λz.t has type T if and only if, for some X1 and X2,
26//! (i) under the assumption that z has type X1, t has type X2, and
27//! (ii) T is a supertype of X1 → X2."
28//! z and t types must be fresh (can't generally guess them). They are _existentially_ bound because we are going to
29//! solve their values. Note that z is _not_ fresh in the condition (i).
30//!
31//! - Equation 3: ⟦t1 t2 : T⟧ = ∃X2.(⟦t1 : X2 → T⟧ ∧ ⟦t2 : X2⟧)
32//! "t1 t2 has type T if and only if, for some X2, t1 has type X2 → T and t2 has type X2"
33//!
34//! - Equation 4: ⟦let z = t1 in t2 : T⟧ = let z : ∀X[⟦t1 : X⟧].X in ⟦t2 : T⟧
35//! "let z = t1 in t2 has type T if and only if, under the assumption that z has every type X such that ⟦t1 : X⟧ holds, t2 has type T"
36//!
37//!
38use super::canonical;
39use super::canonical::Module;
40use super::scalars;
41use crate::ir::{
42 pattern_parameter, CaseForm, Constructor, Field, LiteralValue, Predicate, Reference,
43 ReferenceKind, Saturation, Solved, SolvedInstance, SubPattern, Term, TermKind, TermPattern,
44 TermPatternKind, TypeBinder, TypedTerm, TypedTermKind,
45};
46use crate::name::{Name, QualName};
47use crate::{Interface, ModuleName, PhaseError, SpanLabel};
48use log::debug;
49use std::collections::{BTreeMap, HashMap, HashSet};
50use zelkova_syntax::position::NodeSpan;
51use zelkova_syntax::tuple::Tuple;
52
53// ── Provenance ────────────────────────────────────────────────────────────────
54
55/// Why two types were required to match.
56///
57/// A constraint on its own is a pair of types, which is everything inference needs
58/// and nothing a reader can act on. The reason is what turns "cannot match `Bool`
59/// with `Int`" into something located: *this branch* has type `Bool`, and `Int` is
60/// what was expected *because of this annotation*. Elm calls this a `Reason`, rustc
61/// an `ObligationCause`.
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub enum Reason {
64 /// A declaration's type annotation, which its body has to satisfy.
65 Annotation,
66 /// A literal's own type: `'a'` is a `Char`.
67 Literal,
68 /// A function's type is its parameter's type arrow its body's type.
69 FunctionShape,
70 /// What is applied has to be a function from the argument's type.
71 Application,
72 /// The condition of an `if` has to be a `Bool`.
73 IfCondition,
74 /// Every branch of an `if` has the type of the whole `if`.
75 IfBranch,
76 /// Every branch of a `case` has the type of the whole `case`.
77 CaseBranch,
78 /// A pattern has to match the type of the expression being matched on.
79 CasePattern,
80 /// A parameter written as a pattern has to match the type of the argument it takes.
81 ParameterPattern,
82 /// The body of a declaration that wrote a parameter as a pattern has the type the
83 /// declaration returns. It is the one branch of the match that parameter became,
84 /// and is reported as what the source wrote: a body, not a `case` branch.
85 DeclarationBody,
86 /// A `let` binding has the type of the value bound to it.
87 LetBinding,
88 /// A `let` has the type of its body.
89 LetBody,
90 /// A tuple's type is the tuple of its elements' types.
91 TupleElements,
92 /// `()` is the unit type's one value.
93 Unit,
94 /// A record's type is the record type of its fields' types.
95 RecordFields,
96 /// An update has the type of the record it updates.
97 Update,
98 /// A field's new value in an update has the type the field already has. Carried by
99 /// the equation a `FieldConstraint` of an update becomes once its record type is
100 /// known, at the value's span.
101 UpdateField,
102 /// A field access has the type of the field it reads. Carried by the equation a
103 /// `FieldConstraint` of an access becomes, at the access's span.
104 Access,
105 /// An accessor's result has the type of the field it reads. Carried by the equation
106 /// a `FieldConstraint` of an accessor becomes, at the accessor's span.
107 Accessor,
108 /// A record pattern's entry matches a value of the type its field has. Carried by the
109 /// equation a `FieldConstraint` of a record pattern becomes, at the span of the
110 /// entry's own pattern — `Celsius` in `{ taken = Celsius }` — when that pattern binds
111 /// no name, so that nothing but the pattern decides the entry's type and a mismatch
112 /// is the pattern's.
113 RecordPatternEntry,
114 /// [`RecordPatternEntry`](Self::RecordPatternEntry) for an entry whose pattern is a
115 /// name, the binding in `{ taken }` or `{ taken = t }`. That name's type is constrained
116 /// by nothing but the body's uses of it, so when the equation fails the pattern is
117 /// not what disagrees with the field: a use is, and the note says so. The caret is
118 /// still under the binding ([`ERR-20`](../../docs/tickets/err-20.md)).
119 RecordPatternBinding,
120 /// [`RecordPatternEntry`](Self::RecordPatternEntry) for an entry whose pattern is
121 /// neither a name nor binding-free, `Box x` in `{ taken = Box x }`: either the pattern
122 /// or a use of a name it binds can be what disagrees with the field, and nothing here
123 /// tells which, so the note names both.
124 RecordPatternEntryWithBindings,
125 /// A use of a name whose type has a context. The context's constraints are
126 /// instantiated at the types the use gave its variables, and each requires an
127 /// instance of its class at that type. Carried by an `Obligation` and never by an
128 /// equation, at the span of the use.
129 InstanceRequired,
130 /// An instance a use requires has a context of its own, and each of its constraints
131 /// requires an instance in turn, at the type the instance was used at. Carried by an
132 /// `Obligation` at the span of the use that started the chain.
133 InstanceContext,
134 /// A class with a superclass requires an instance of the superclass at every type it
135 /// has an instance for. Carried by an `Obligation` at the span of the instance
136 /// declaration.
137 SuperclassInstance,
138 /// A binding of an instance has the type its class gave the member, at the type the
139 /// instance is for. It is the reason of the equation the member's signature stands in
140 /// for, at the span of the instance's head line, where an annotation would be.
141 InstanceMember,
142 /// A binding of a derivation has the type the chapter gives it over the member's
143 /// answer type. It is the reason of the equation that type stands in for, at the span
144 /// of `derived member`, where an annotation would be.
145 DerivationBinding,
146}
147
148impl Reason {
149 /// What goes under the caret when the constraint carrying this reason is the one
150 /// that failed: what the underlined text *is*, in the vocabulary of the source.
151 ///
152 /// It names no type, and that is not terseness. By the time a constraint fails,
153 /// `unify` has substituted solutions into both of its sides and may have
154 /// decomposed it into a component of the types the source actually mentions — so
155 /// neither side is reliably "the type of the text under this caret" any more.
156 /// The headline already prints both types; a label that named the wrong one
157 /// would be worse than a label that names none. The example that forced this:
158 /// `answer : Int` with body `'a'` fails on the literal's own constraint *after*
159 /// `Int` was substituted into it, and reading the type off that side produced
160 /// "this literal has type `Int`".
161 fn describes(&self) -> &'static str {
162 match self {
163 Reason::Annotation => "this type annotation",
164 Reason::Literal => "this literal",
165 Reason::FunctionShape => "this function",
166 Reason::Application => "the expression being applied",
167 Reason::IfCondition => "this condition",
168 Reason::IfBranch => "this branch of the `if`",
169 Reason::CaseBranch => "this branch of the `case`",
170 Reason::CasePattern => "this pattern",
171 Reason::ParameterPattern => "this pattern",
172 Reason::DeclarationBody => "the body of this declaration",
173 Reason::LetBinding => "the value bound here",
174 Reason::LetBody => "the body of this `let`",
175 Reason::TupleElements => "this tuple",
176 Reason::Unit => "this unit value",
177 Reason::RecordFields => "this record",
178 Reason::Update => "this update",
179 Reason::UpdateField => "this field's new value",
180 Reason::Access => "this field access",
181 Reason::Accessor => "this accessor",
182 Reason::RecordPatternEntry
183 | Reason::RecordPatternBinding
184 | Reason::RecordPatternEntryWithBindings => "this field's pattern",
185 Reason::InstanceRequired => "this use requires an instance",
186 Reason::InstanceContext => "this use requires an instance, through another's context",
187 Reason::SuperclassInstance => "this instance requires an instance of its superclass",
188 Reason::InstanceMember => "this instance",
189 Reason::DerivationBinding => "this derivation",
190 }
191 }
192
193 /// What goes under the caret when this reason is not the failure itself but the
194 /// explanation for one side of it — see [`Origin::explanation`].
195 ///
196 /// No type is interpolated here, deliberately. Provenance records which
197 /// constraint brought a type into another one; it does not prove that the type
198 /// printed in the failing constraint is still literally the one this constraint
199 /// carried, and a label is not the place to guess.
200 fn explains(&self) -> &'static str {
201 match self {
202 Reason::Annotation => "expected because of this type annotation",
203 Reason::Literal => "expected because of this literal",
204 Reason::FunctionShape => "expected because of this function",
205 Reason::Application => "expected because of this application",
206 Reason::IfCondition => "expected because this is an `if` condition",
207 Reason::IfBranch => "expected because of this branch",
208 Reason::CaseBranch => "expected because of this branch",
209 Reason::CasePattern => "expected because of this pattern",
210 Reason::ParameterPattern => "expected because of this pattern",
211 Reason::DeclarationBody => "expected because of this declaration's body",
212 Reason::LetBinding => "expected because of this value",
213 Reason::LetBody => "expected because of this `let` body",
214 Reason::TupleElements => "expected because of this tuple",
215 Reason::Unit => "expected because of this unit value",
216 Reason::RecordFields => "expected because of this record",
217 Reason::Update => "expected because of this update",
218 Reason::UpdateField => "expected because of this field's new value",
219 Reason::Access => "expected because of this field access",
220 Reason::Accessor => "expected because of this accessor",
221 Reason::RecordPatternEntry
222 | Reason::RecordPatternBinding
223 | Reason::RecordPatternEntryWithBindings => "expected because of this field's pattern",
224 Reason::InstanceRequired => "an instance is required because of this use",
225 Reason::InstanceContext => "an instance is required through another's context here",
226 Reason::SuperclassInstance => "an instance is required because of this superclass",
227 Reason::InstanceMember => "expected because this instance gives the member this type",
228 Reason::DerivationBinding => {
229 "expected because this derivation gives the binding this type"
230 }
231 }
232 }
233
234 /// The rule that was broken, when naming it says something the labels do not.
235 fn note(&self) -> Option<&'static str> {
236 match self {
237 Reason::Annotation => {
238 Some("a declaration's body must have the type its annotation declares")
239 }
240 Reason::IfCondition => Some("the condition of an `if` must be a `Bool`"),
241 Reason::IfBranch => Some("every branch of an `if` must have the same type"),
242 Reason::CaseBranch => Some("every branch of a `case` must have the same type"),
243 Reason::CasePattern => Some(
244 "every pattern of a `case` must match the type of the expression it matches on",
245 ),
246 Reason::ParameterPattern => {
247 Some("a parameter's pattern must match the type of the argument it takes")
248 }
249 Reason::Update => Some("an update has the type of the record it updates"),
250 Reason::UpdateField => {
251 Some("an update cannot change a field's type: each new value must have the type its field already has")
252 }
253 Reason::Access => Some("a field access has the type of the field it reads"),
254 Reason::Accessor => Some("an accessor returns the type of the field it reads"),
255 Reason::RecordPatternEntry => {
256 Some("each entry of a record pattern must match the type of the field it names")
257 }
258 Reason::RecordPatternBinding => Some(
259 "a name a record pattern binds has the type of the field it names, and the body uses this one at another type",
260 ),
261 Reason::RecordPatternEntryWithBindings => Some(
262 "either this entry does not match the type of the field it names, or the body uses a name it binds at another type than that field gives the name",
263 ),
264 Reason::InstanceMember => Some(
265 "an instance's binding must have the type its class gives the member, at the type the instance is for",
266 ),
267 Reason::DerivationBinding => Some(
268 "a derivation's binding has the type its role gives it over the type the member answers with",
269 ),
270 // The error that carries one of these says what is required and why, so a rule
271 // note beside it would say it twice.
272 Reason::InstanceRequired | Reason::InstanceContext | Reason::SuperclassInstance => {
273 None
274 }
275 _ => None,
276 }
277 }
278}
279
280/// One piece of source text, and why it required a type: the answer to "where did
281/// this type come from".
282///
283/// Deliberately flat — no chain. A cause names the constraint that *introduced* a
284/// type, never one that relayed it, and that is arranged when the cause is built
285/// rather than by walking a chain afterwards. See `Origin::cause_of`.
286// No `Eq`: `NodeSpan`'s `PartialEq` is deliberately blind (see its documentation), so
287// equality here is a claim about the reason and not about the position.
288#[derive(Debug, Clone, Copy, PartialEq)]
289pub struct Cause {
290 /// Why that constraint required the two types to match.
291 pub reason: Reason,
292 /// The source text it is about.
293 pub span: NodeSpan,
294}
295
296/// Which side of a constraint a type sits on.
297///
298/// Unification is symmetric and does not care; provenance does. Whether a solved
299/// type was read off the left or the right of the constraint that solved it is what
300/// decides whether that constraint is where the type came from, or merely where a
301/// substitution put it — see [`Origin::cause_of`].
302#[derive(Debug, Clone, Copy, PartialEq, Eq)]
303enum Side {
304 Left,
305 Right,
306}
307
308/// Where a constraint came from, and — once inference has moved types around — where
309/// each of its two types came from.
310#[derive(Debug, Clone, PartialEq)]
311pub struct Origin {
312 /// Why the two types were required to match.
313 pub reason: Reason,
314 /// The source text this constraint is about. A failure here draws its caret at
315 /// this span.
316 pub span: NodeSpan,
317 /// The constraint whose solution first rewrote the left type, if any.
318 ///
319 /// `unify` solves a constraint by substituting a type for a variable and then
320 /// applying that substitution to every constraint left. Once that has happened,
321 /// this side holds a type this constraint never mentioned: it came from wherever
322 /// the substitution did. That is the fact a reader needs — "`Int`, because of the
323 /// annotation two lines up" — and it is what the secondary label of a type error
324 /// renders.
325 ///
326 /// The *first* rewrite is kept and later ones are dropped: the first substitution
327 /// to reach a side is the one that brought a foreign type into it, and later ones
328 /// only rewrite what is already there.
329 left_from: Option<Cause>,
330 /// The same, for the right type.
331 right_from: Option<Cause>,
332}
333
334impl Origin {
335 fn new(reason: Reason, span: NodeSpan) -> Origin {
336 Origin {
337 reason,
338 span,
339 left_from: None,
340 right_from: None,
341 }
342 }
343
344 /// This constraint, as the explanation for a type it introduced itself.
345 fn own_cause(&self) -> Cause {
346 Cause {
347 reason: self.reason,
348 span: self.span,
349 }
350 }
351
352 /// Where the type on `side` came from: whatever rewrote that side, or — when
353 /// nothing did — this constraint itself.
354 ///
355 /// This is the whole of the provenance rule, and it is a rule about *sides*.
356 /// When `unify` solves `t := T` from a constraint, `T` was read off one side of
357 /// it. If that side is a type the constraint was written with, the constraint is
358 /// the answer. If a previous solution had rewritten that side, the constraint is
359 /// only relaying a type, and the answer is whatever rewrote it — which is already
360 /// flat, so the credit passes straight through and no chain is ever built.
361 ///
362 /// Crediting a constraint that merely relayed a type is how `result : Bool` /
363 /// `result = not 42` came to blame the annotation: the `Bool` that `42` fails
364 /// against is `not`'s parameter type, which the application constraint carries on
365 /// its *left*, while the annotation had only rewritten its right.
366 fn cause_of(&self, side: Side) -> Cause {
367 let rewritten = match side {
368 Side::Left => self.left_from,
369 Side::Right => self.right_from,
370 };
371
372 rewritten.unwrap_or_else(|| self.own_cause())
373 }
374
375 /// Record that a solution rewrote one side of this constraint, keeping whatever
376 /// was already recorded for that side. See [`Origin::left_from`].
377 fn rewritten(&mut self, side: Side, cause: Cause) {
378 let slot = match side {
379 Side::Left => &mut self.left_from,
380 Side::Right => &mut self.right_from,
381 };
382
383 if slot.is_none() {
384 *slot = Some(cause);
385 }
386 }
387
388 /// Where the type this constraint clashed on came from, when the constraint is
389 /// not itself where it came from.
390 ///
391 /// This is what a diagnostic's secondary label and its rule note are both read
392 /// off. The left side is preferred because that is the declared or expected side
393 /// by convention (see `Constraint`), so "expected because of …" reads about the
394 /// right one; the right side answers when only it was rewritten.
395 pub fn explanation(&self) -> Option<Cause> {
396 self.left_from.or(self.right_from)
397 }
398}
399
400/// What went wrong, and — for everything unification can raise — where.
401///
402/// Each variant carries the [`Origin`] of the constraint that failed, so a type
403/// error can put its caret under the sub-expression that disagrees instead of across
404/// the declaration containing it. The declaration is still named by [`Error`], one
405/// level up, which is the frame that knows it.
406#[derive(Debug)]
407pub enum ErrorKind {
408 /// Two types were required to match and do not.
409 ///
410 /// The two are written in the order the message reads them out — declared side
411 /// first where the source had one. Neither is reliably "the type of the text the
412 /// origin points at": by the time a constraint fails, unification has substituted
413 /// into both sides and may have decomposed the pair the source actually wrote.
414 // The origins and the types are boxed because an `ErrorKind` is the `Err` half of
415 // a `Result` threaded through the whole of `unify`, and every *successful* return
416 // pays for the size of the largest variant. `Origin` carries a `Cause` per side,
417 // and a `Type` carries a whole `QualName` for every union it names.
418 UnificationFailed {
419 left: Box<Type>,
420 right: Box<Type>,
421 origin: Box<Origin>,
422 },
423 /// A type variable the declaration is universally quantified over — one its annotation
424 /// wrote, or one of an instance's head or of the member signature an instance's
425 /// binding is held to — would have to be a type of its own, which a declaration cannot
426 /// ask of a variable that stands for every type a caller may choose
427 /// ([*An annotation is a promise*](../../docs/spec/types.md#an-annotation-is-a-promise)).
428 ///
429 /// Raised where `unify` meets a rigid variable and anything but that variable: a
430 /// concrete type, or another rigid variable of the same declaration.
431 RigidVariable {
432 /// The variable as the source wrote it, `a`.
433 variable: String,
434 /// What the variable was written in.
435 binder: Binder,
436 /// What the body would need it to be, written with the source's names for the
437 /// other rigid variables it holds. Boxed for the reason `UnificationFailed`'s
438 /// types are.
439 tpe: Box<Type>,
440 origin: Box<Origin>,
441 },
442 /// A type variable would have to occur inside its own solution.
443 CircularType {
444 /// The type the variable would have had to contain itself in. Boxed for the
445 /// reason above.
446 tpe: Box<Type>,
447 origin: Box<Origin>,
448 },
449 /// A name the typer's environment does not know. `type_check` turns this into a
450 /// [`Solved::UnboundName`] rather than an [`Error`]; that variant says why.
451 ///
452 /// `name` is `environment_key`'s `package:Module.name` lookup key, copied
453 /// verbatim from [`Reference::name`] — not a spelling. `message()`'s arm for this
454 /// variant renders it as-is, which would print the package if this variant were
455 /// ever surfaced as a rendered [`Error`]; today `type_check` never does that (see
456 /// above), so the leak has no path to a user yet. Whoever gives this variant a
457 /// live path — `ERR-8`'s planned warning is the likely first one — has to carry a
458 /// displayable name (the bare local name, or a `QualName` rendered the way
459 /// `Spellings` would) alongside this key rather than rendering it directly.
460 UnboundVariable {
461 name: String,
462 /// Where the name was written.
463 span: NodeSpan,
464 },
465 /// A field access, an update, an accessor or a record pattern whose record type
466 /// nothing else in the declaration supplied: once unification had run over the whole
467 /// declaration, the type it reads a field of was still a variable
468 /// ([A use does not decide a record's type](../../docs/spec/records.md#a-use-does-not-decide-a-records-type)).
469 ///
470 /// `span` is the whole form — `person.name`, `{ r | x = 1 }`, `.name`, `{ name }` —
471 /// since what is missing is a type for it, not a label in one.
472 RecordTypeUnknown {
473 label: Name,
474 form: RecordUse,
475 span: NodeSpan,
476 /// What could supply the record type, which is what the note says.
477 supplier: Supplier,
478 },
479 /// A field access, an update, an accessor or a record pattern naming a label the
480 /// record type it is read against does not have. An update naming one is the update
481 /// that would add a field ([Updating a record](../../docs/spec/records.md#updating-a-record)).
482 ///
483 /// `span` is the label for an access, an update's field and a record pattern's entry,
484 /// and the whole accessor for an accessor, whose label is all of it but the `.`.
485 MissingField {
486 /// The record type, as solved. Boxed for the reason `UnificationFailed`'s
487 /// types are.
488 record: Box<Type>,
489 label: Name,
490 form: RecordUse,
491 span: NodeSpan,
492 /// Where the record type came from — the annotation, typically — when something
493 /// brought it in; the secondary label goes under it.
494 because: Option<Cause>,
495 },
496 /// A field access, an update, an accessor or a record pattern whose record is not a
497 /// record at all: the type it reads a field of was solved to a type of another form.
498 ///
499 /// `span` is where [`MissingField`](Self::MissingField)'s would be, and `because` is
500 /// as there.
501 NotARecord {
502 tpe: Box<Type>,
503 label: Name,
504 form: RecordUse,
505 span: NodeSpan,
506 because: Option<Cause>,
507 },
508 /// A class is required of a type, and the type has no instance of it: a declared type,
509 /// a tuple or `()` that no instance in reach is declared for, or a function type,
510 /// which no instance can be.
511 ///
512 /// The type is the one the obligation had once unification was done, so it can be
513 /// the argument of an instance's context rather than the type the use was at:
514 /// [`needed_by`](Self::NoInstance::needed_by) is then the obligation the use raised,
515 /// which asked for this one through an instance of its own.
516 NoInstance {
517 class: QualName,
518 /// Boxed for the reason `UnificationFailed`'s types are.
519 tpe: Box<Type>,
520 needed_by: Option<Box<Predicate>>,
521 origin: Box<Origin>,
522 },
523 /// A class is required of a type variable the declaration's type holds, and the
524 /// constraints its annotation (or an instance's context) wrote do not provide it: the
525 /// constraint to add is the fix. The exception is a variable an instance binding's
526 /// member signature binds, which no context of the instance can constrain:
527 /// [`Written::MemberSignature`] says so.
528 MissingConstraint {
529 class: QualName,
530 /// The variable as the source wrote it, `a`.
531 variable: String,
532 /// What is missing the constraint.
533 written: Written,
534 origin: Box<Origin>,
535 },
536 /// A class is required of a type variable the type of a declaration with no
537 /// annotation holds. A constraint is never inferred
538 /// ([`DEC-24` decision 5](../../docs/decisions/dec-24.md#5--a-constraint-is-never-inferred)),
539 /// so the declaration has to state it.
540 ConstraintNeedsAnnotation {
541 class: QualName,
542 /// What the declaration has to state, constraints and type: `Eq a => a -> a ->
543 /// Bool`.
544 stated: String,
545 origin: Box<Origin>,
546 },
547 /// A class is required of a type variable that is not part of the declaration's type.
548 /// Nothing determines the type the class is needed at, and no annotation on this
549 /// declaration can.
550 UndeterminedConstraint {
551 class: QualName,
552 origin: Box<Origin>,
553 },
554}
555
556/// What a constraint would have to be written in, for [`ErrorKind::MissingConstraint`].
557#[derive(Debug, Clone, Copy, PartialEq, Eq)]
558pub enum Written {
559 /// A declaration's annotation.
560 Annotation,
561 /// An instance's context.
562 InstanceContext,
563 /// The signature of the class member an instance's binding defines: the variable is
564 /// one the member's signature binds and the instance's head does not, so no context
565 /// of the instance can constrain it.
566 MemberSignature,
567 /// A derivation's binding, which is given no context: none of its bindings mentions
568 /// the class variable, so they stand for every type that derives the class.
569 Derivation,
570}
571
572impl ErrorKind {
573 /// The provenance of the constraint that failed, when the failure came from
574 /// unification at all.
575 fn origin(&self) -> Option<&Origin> {
576 match self {
577 ErrorKind::UnificationFailed { origin, .. }
578 | ErrorKind::RigidVariable { origin, .. }
579 | ErrorKind::CircularType { origin, .. }
580 | ErrorKind::NoInstance { origin, .. }
581 | ErrorKind::MissingConstraint { origin, .. }
582 | ErrorKind::ConstraintNeedsAnnotation { origin, .. }
583 | ErrorKind::UndeterminedConstraint { origin, .. } => Some(origin.as_ref()),
584 ErrorKind::UnboundVariable { .. }
585 | ErrorKind::RecordTypeUnknown { .. }
586 | ErrorKind::MissingField { .. }
587 | ErrorKind::NotARecord { .. } => None,
588 }
589 }
590
591 /// The headline, naming each union the way `spellings` says the checked package
592 /// reaches it when the message has to qualify one at all — see [`AdtNames`].
593 fn message(&self, spellings: &Spellings) -> String {
594 match self {
595 ErrorKind::UnificationFailed { left, right, .. } => {
596 // Two modules may each declare a union of the same name, and the
597 // source spells both of them bare. Written that way the sentence
598 // uses one word for two declarations and says nothing; the module
599 // that declared each is what tells them apart, so both sides take
600 // it — both, because a sentence that qualifies one side and not the
601 // other reads as if only one of them had a module.
602 if AdtNames::collide([left.as_ref(), right.as_ref()]) {
603 format!(
604 "cannot match `{}` with `{}`",
605 Qualified(left, spellings),
606 Qualified(right, spellings)
607 )
608 } else {
609 format!("cannot match `{}` with `{}`", left, right)
610 }
611 }
612 ErrorKind::RigidVariable {
613 variable,
614 binder,
615 tpe,
616 ..
617 } => {
618 // An instance's head and the member signature its binding is held to each
619 // write their own variables, and may write one alike: then the message says
620 // whose each is, or `b` would have to be `b`.
621 let other = free_variables_in_order(tpe).into_iter().find_map(|found| {
622 let found_binder = found.binder()?;
623 (found.spelling() == *variable && found_binder != *binder)
624 .then_some(found_binder)
625 });
626
627 match other {
628 Some(other) => format!(
629 "`{}` of {} stands for any type, but here it would have to be `{}`, where `{}` is {}",
630 variable,
631 binder.of_phrase(),
632 Spelled(tpe, spellings),
633 variable,
634 other.possessive()
635 ),
636 None => format!(
637 "`{}` stands for any type, but here it would have to be `{}`",
638 variable,
639 Spelled(tpe, spellings)
640 ),
641 }
642 }
643 // One type, but it can hold the collision on its own: the variable's
644 // solution is built out of whatever it was unified against, which may
645 // be two same-named unions from two modules.
646 ErrorKind::CircularType { tpe, .. } => {
647 let qualified = Qualified(tpe, spellings);
648 let tpe: &dyn std::fmt::Display = if AdtNames::collide([tpe.as_ref()]) {
649 &qualified
650 } else {
651 &**tpe
652 };
653
654 format!(
655 "circular type: a type variable would have to contain itself in `{}`",
656 tpe
657 )
658 }
659 // `name` is the internal environment key, not a spelling — see the
660 // doc comment on `UnboundVariable` above. Unreachable today only because
661 // nothing renders this variant as an `Error`.
662 ErrorKind::UnboundVariable { name, .. } => {
663 format!("cannot find a value named `{}`", name)
664 }
665 ErrorKind::RecordTypeUnknown { label, form, .. } => match form {
666 RecordUse::Access => format!(
667 "cannot read the field `{}`: nothing in this declaration says which record type it is read from",
668 label.as_str()
669 ),
670 RecordUse::Accessor => format!(
671 "cannot type the accessor `.{}`: nothing in this declaration says which record type it reads",
672 label.as_str()
673 ),
674 RecordUse::Update => {
675 "cannot type this update: nothing in this declaration says which record type it updates"
676 .to_string()
677 }
678 RecordUse::Pattern => {
679 "cannot type this record pattern: nothing in this declaration says which record type it matches"
680 .to_string()
681 }
682 },
683 ErrorKind::MissingField { record, label, .. } => format!(
684 "the record type `{}` has no field `{}`",
685 Spelled(record, spellings),
686 label.as_str()
687 ),
688 ErrorKind::NotARecord { tpe, label, .. } => format!(
689 "`{}` is not a record type, so it has no field `{}`",
690 Spelled(tpe, spellings),
691 label.as_str()
692 ),
693 ErrorKind::NoInstance { class, tpe, .. } => format!(
694 "there is no instance of `{}` for `{}`",
695 class.unqualified_name(),
696 Spelled(tpe, spellings)
697 ),
698 ErrorKind::MissingConstraint {
699 class,
700 variable,
701 written,
702 ..
703 } => format!(
704 "`{} {}` is required here, and {} does not provide it",
705 class.unqualified_name(),
706 variable,
707 match written {
708 Written::Annotation => "the annotation",
709 Written::InstanceContext => "the instance's context",
710 Written::MemberSignature => "the member's signature",
711 Written::Derivation => "the derivation, which is given no context,",
712 }
713 ),
714 ErrorKind::ConstraintNeedsAnnotation { class, .. } => format!(
715 "a type annotation is needed: `{}` is required of a type this declaration leaves open",
716 class.unqualified_name()
717 ),
718 ErrorKind::UndeterminedConstraint { class, .. } => format!(
719 "`{}` is required of a type nothing in this declaration determines",
720 class.unqualified_name()
721 ),
722 }
723 }
724
725 /// Where the type `MissingField` and `NotARecord` read a field of came from, when
726 /// something brought it in: the secondary label of each, as a mismatch's is.
727 fn record_use_because(&self) -> Option<Cause> {
728 match self {
729 ErrorKind::MissingField { because, .. } | ErrorKind::NotARecord { because, .. } => {
730 *because
731 }
732 _ => None,
733 }
734 }
735
736 /// The caret of one of the three errors a `FieldConstraint` raises itself, which
737 /// carry a span and no [`Origin`]: each is about a form rather than about two types.
738 fn record_use_label(&self) -> Option<(NodeSpan, String)> {
739 match self {
740 ErrorKind::RecordTypeUnknown { span, .. } => {
741 Some((*span, "its record type is not known here".to_string()))
742 }
743 ErrorKind::MissingField { label, span, .. } => Some((
744 *span,
745 format!("the record has no field `{}`", label.as_str()),
746 )),
747 ErrorKind::NotARecord {
748 label,
749 form: RecordUse::Pattern,
750 span,
751 ..
752 } => Some((
753 *span,
754 format!(
755 "`{}` is matched against a type that is not a record",
756 label.as_str()
757 ),
758 )),
759 ErrorKind::NotARecord { label, span, .. } => Some((
760 *span,
761 format!(
762 "`{}` is read from a type that is not a record",
763 label.as_str()
764 ),
765 )),
766 _ => None,
767 }
768 }
769}
770
771/// A [`Type`] written the way a message about one type writes it: bare, unless two of
772/// the unions it names share a spelling, and then each by its module (see [`AdtNames`]).
773struct Spelled<'a>(&'a Type, &'a Spellings);
774
775impl std::fmt::Display for Spelled<'_> {
776 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
777 if AdtNames::collide([self.0]) {
778 self.0.write(f, AdtNames::Qualified(self.1), None)
779 } else {
780 self.0.write(f, AdtNames::Unqualified, None)
781 }
782 }
783}
784
785/// A type error: what went wrong, where, and in which declaration.
786///
787/// # Where the positions come from
788///
789/// The typer does not check the canonical AST directly — it translates it into its
790/// own [`Term`] language — but that translation now carries the canonical node's
791/// [`NodeSpan`] along, and each constraint keeps the span of the term that produced
792/// it. So a unification failure knows the sub-expression it is about, and
793/// [`labels`](PhaseError::labels) draws the caret there.
794///
795/// The declaration's own span is still kept as `span`, for the one case that has no
796/// finer answer: an error whose origin came from a hand-built term, or from a
797/// canonical node the parser never spanned. Then the label degrades to the whole
798/// declaration rather than disappearing.
799#[derive(Debug)]
800pub struct Error {
801 pub kind: ErrorKind,
802 /// Where the declaration the error was found in was written. Used only as the
803 /// fallback described above.
804 pub span: NodeSpan,
805 /// That declaration's name, which is what the note names: in a module of a
806 /// hundred declarations, a caret is not much use without it when the diagnostic
807 /// is rendered without a file (see `compile_package`).
808 pub declaration: Name,
809 /// What `declaration` is: a value, a binding of an instance, or an instance.
810 within: Within,
811 /// How the checked package spells each module in reach, which is what a union is
812 /// written by in [`message`](PhaseError::message) when it has to be qualified.
813 spellings: Spellings,
814}
815
816/// What an [`Error`]'s `declaration` names, which is what its first note says.
817#[derive(Debug, Clone, PartialEq)]
818enum Within {
819 /// A value of the module: `declaration` is its name.
820 Value,
821 /// A binding of an instance: `declaration` is the member it defines, and this is the
822 /// instance, written as its head line is.
823 Binding(String),
824 /// An instance, checked as a whole: `declaration` is the instance, written as its head
825 /// line is.
826 Instance,
827 /// A binding of a derivation in a class: `declaration` is the binding, and this is
828 /// the member the derivation is for.
829 Derivation(String),
830}
831
832/// Type errors are about types, and [`Type`]'s `Display` writes them the way the
833/// source does — so the message can name both sides of a mismatch instead of
834/// dumping the typer's internal representation.
835impl PhaseError for Error {
836 fn message(&self) -> String {
837 self.kind.message(&self.spellings)
838 }
839
840 fn notes(&self) -> Vec<String> {
841 let mut notes = vec![match &self.within {
842 Within::Value => format!("in the declaration of `{}`", self.declaration),
843 Within::Binding(instance) => format!(
844 "in the binding of `{}` in the instance `{}`",
845 self.declaration, instance
846 ),
847 Within::Instance => format!("in the instance `{}`", self.declaration),
848 Within::Derivation(member) => format!(
849 "in the binding `{}` of the derivation of `{}`",
850 self.declaration, member
851 ),
852 }];
853
854 // The rule that was broken, taken from the failing constraint and, if that
855 // one has nothing to add, from what explains it. `if`'s "every branch must
856 // have the same type" is on the branch constraint; "a body must have the
857 // type its annotation declares" is on the annotation, which is normally the
858 // explanation rather than the failure.
859 if let Some(origin) = self.kind.origin() {
860 let rule = origin
861 .reason
862 .note()
863 .or_else(|| origin.explanation().and_then(|c| c.reason.note()));
864
865 if let Some(rule) = rule {
866 notes.push(rule.to_owned());
867 }
868 }
869
870 match &self.kind {
871 ErrorKind::UnificationFailed { left, right, .. } => {
872 if let Some(difference) = label_difference(left, right) {
873 notes.push(difference);
874 }
875 }
876 ErrorKind::RigidVariable {
877 variable, binder, ..
878 } => notes.push(match binder {
879 Binder::InstanceHead => format!(
880 "a type variable of an instance stands for every type the instance may be used at, so its bindings cannot rely on `{}` being one particular type",
881 variable
882 ),
883 Binder::Annotation => format!(
884 "a type variable in an annotation stands for every type a caller may choose, so the body cannot rely on `{}` being one particular type",
885 variable
886 ),
887 Binder::MemberSignature => format!(
888 "a type variable of a member's signature stands for every type a caller of the member may choose, so a binding cannot rely on `{}` being one particular type",
889 variable
890 ),
891 }),
892 ErrorKind::RecordTypeUnknown { supplier, .. } => {
893 notes.push(
894 "a record's type is never worked out from the fields a declaration uses"
895 .to_string(),
896 );
897 notes.push(match supplier {
898 Supplier::Annotation => format!(
899 "a type annotation on `{}` would supply it",
900 self.declaration
901 ),
902 Supplier::AnnotationVariable => format!(
903 "the annotation on `{}` does not say which record type this is: it writes a type variable where the record type would be spelled out",
904 self.declaration
905 ),
906 Supplier::Body => format!(
907 "it is not part of `{}`'s type, so no annotation on `{}` could supply it",
908 self.declaration, self.declaration
909 ),
910 });
911 }
912 ErrorKind::MissingField {
913 form: RecordUse::Update,
914 ..
915 } => notes.push(
916 "an update cannot add a field: each label it names must already be a field of the record it updates"
917 .to_string(),
918 ),
919 ErrorKind::MissingField {
920 form: RecordUse::Pattern,
921 ..
922 } => notes.push(
923 "a record pattern names some of the fields of the record it matches, and each label it names must be one of them"
924 .to_string(),
925 ),
926 ErrorKind::NoInstance {
927 class,
928 tpe,
929 needed_by,
930 ..
931 } => {
932 let class = class.unqualified_name();
933
934 notes.push(match tpe.as_ref() {
935 Type::Fun { .. } => {
936 "a function type has no instances: no instance can be declared for one"
937 .to_string()
938 }
939 _ => format!(
940 "an instance of `{}` for this type is declared in the module that declares `{}` or in the module that declares the type, and none is in scope here",
941 class, class
942 ),
943 });
944
945 if let Some(required) = needed_by {
946 notes.push(format!(
947 "it is needed because `{}` is required here, and the instance of `{}` that answers that asks the same of this type",
948 predicate_text(required, &self.spellings),
949 required.class.unqualified_name()
950 ));
951 }
952 }
953 ErrorKind::MissingConstraint {
954 class,
955 variable,
956 written,
957 ..
958 } => notes.push(match written {
959 Written::Annotation => format!(
960 "add `{} {}` to the constraints of the annotation on `{}`",
961 class.unqualified_name(),
962 variable,
963 self.declaration
964 ),
965 Written::InstanceContext => format!(
966 "add `{} {}` to the context of the instance",
967 class.unqualified_name(),
968 variable
969 ),
970 Written::MemberSignature => format!(
971 "`{}` is bound by the signature of the member and not by the head of the instance, so no context of the instance can constrain it: the binding has to hold for every `{}`, and cannot need `{} {}`; change the binding, or the member's signature",
972 variable,
973 variable,
974 class.unqualified_name(),
975 variable
976 ),
977 Written::Derivation => format!(
978 "a derivation's bindings carry no context, so the binding has to hold for every `{}` and cannot need `{} {}`; change the binding, or the member's signature",
979 variable,
980 class.unqualified_name(),
981 variable
982 ),
983 }),
984 ErrorKind::ConstraintNeedsAnnotation { stated, .. } => {
985 notes.push(
986 "a constraint is never inferred: it is part of a type only where an annotation writes it"
987 .to_string(),
988 );
989 notes.push(format!(
990 "`{}` is what the declaration has to state: `{} : {}`",
991 self.declaration, self.declaration, stated
992 ));
993 }
994 ErrorKind::UndeterminedConstraint { .. } => notes.push(format!(
995 "the type is not part of `{}`'s type, so no annotation on `{}` could say which it is",
996 self.declaration, self.declaration
997 )),
998 _ => (),
999 }
1000
1001 notes
1002 }
1003
1004 /// A caret under the text that disagrees, and — when inference can say where the
1005 /// type it disagrees with came from — a second, secondary one under that.
1006 ///
1007 /// Falls back to underlining the whole declaration when the failing constraint
1008 /// has no position, which is what a term built by hand, or one translated from a
1009 /// canonical node with no span, produces.
1010 fn labels(&self) -> Vec<SpanLabel> {
1011 let mut labels = Vec::new();
1012
1013 match &self.kind {
1014 ErrorKind::UnboundVariable { span, .. } => {
1015 if let Some(span) = span.span() {
1016 labels.push(SpanLabel {
1017 span,
1018 message: "not found in this scope".to_owned(),
1019 primary: true,
1020 file: None,
1021 });
1022 }
1023 }
1024 kind @ (ErrorKind::RecordTypeUnknown { .. }
1025 | ErrorKind::MissingField { .. }
1026 | ErrorKind::NotARecord { .. }) => {
1027 if let Some((span, message)) = kind.record_use_label() {
1028 if let Some(span) = span.span() {
1029 labels.push(SpanLabel {
1030 span,
1031 message,
1032 primary: true,
1033 file: None,
1034 });
1035 }
1036 }
1037
1038 // As a mismatch's below, and for the same two reasons drawn only beside
1039 // a primary label on other text.
1040 if let (Some(primary), Some(because)) = (labels.first(), kind.record_use_because())
1041 {
1042 match because.span.span() {
1043 Some(span) if span != primary.span => labels.push(SpanLabel {
1044 span,
1045 message: because.reason.explains().to_owned(),
1046 primary: false,
1047 file: None,
1048 }),
1049 _ => (),
1050 }
1051 }
1052 }
1053 kind => {
1054 if let Some(origin) = kind.origin() {
1055 if let Some(span) = origin.span.span() {
1056 labels.push(SpanLabel {
1057 span,
1058 message: origin.reason.describes().to_owned(),
1059 primary: true,
1060 file: None,
1061 });
1062 }
1063
1064 // Only worth drawing once the primary one exists: on its own it
1065 // would be a caret under the annotation with nothing to contrast
1066 // it against. And not worth drawing at all when it lands on the
1067 // same text — a literal that is its own explanation renders as two
1068 // carets under one word saying the same thing twice.
1069 if let (Some(primary), Some(because)) = (labels.first(), origin.explanation()) {
1070 match because.span.span() {
1071 Some(span) if span != primary.span => labels.push(SpanLabel {
1072 span,
1073 message: because.reason.explains().to_owned(),
1074 primary: false,
1075 file: None,
1076 }),
1077 _ => (),
1078 }
1079 }
1080 }
1081 }
1082 }
1083
1084 if labels.is_empty() {
1085 if let Some(span) = self.span.span() {
1086 labels.push(SpanLabel {
1087 span,
1088 message: format!("in `{}`", self.declaration),
1089 primary: true,
1090 file: None,
1091 });
1092 }
1093 }
1094
1095 labels
1096 }
1097}
1098
1099/// The note for two record types that failed to unify because their label sets
1100/// differ, naming the labels each has that the other lacks; `None` for any other pair,
1101/// two record types of one label set included — they failed on a field's type, which
1102/// the headline names.
1103///
1104/// "First" and "second" are the headline's order, which is the constraint's.
1105fn label_difference(left: &Type, right: &Type) -> Option<String> {
1106 let (Type::Record(left), Type::Record(right)) = (left, right) else {
1107 return None;
1108 };
1109
1110 let only = |of: &BTreeMap<Name, Type>, other: &BTreeMap<Name, Type>| -> Vec<String> {
1111 of.keys()
1112 .filter(|label| !other.contains_key(*label))
1113 .map(|label| format!("`{}`", label.as_str()))
1114 .collect()
1115 };
1116 let only_left = only(left, right);
1117 let only_right = only(right, left);
1118
1119 let clause = |which: &str, labels: &[String], other: &str| {
1120 let fields = if labels.len() == 1 {
1121 "a field"
1122 } else {
1123 "fields"
1124 };
1125 format!(
1126 "the {} record type has {} {} that the {} does not",
1127 which,
1128 fields,
1129 labels.join(", "),
1130 other
1131 )
1132 };
1133
1134 match (only_left.is_empty(), only_right.is_empty()) {
1135 (true, true) => None,
1136 (false, true) => Some(clause("first", &only_left, "second")),
1137 (true, false) => Some(clause("second", &only_right, "first")),
1138 (false, false) => Some(format!(
1139 "{}, and the second has {} {} that the first does not",
1140 clause("first", &only_left, "second"),
1141 if only_right.len() == 1 {
1142 "a field"
1143 } else {
1144 "fields"
1145 },
1146 only_right.join(", ")
1147 )),
1148 }
1149}
1150
1151/// What [`type_check_recovering`] found in one module: an answer for every declaration,
1152/// and every error inference reported, side by side.
1153#[derive(Debug)]
1154pub struct TypeCheck {
1155 /// One [`Solved`] per declaration, keyed the way `module.values` is. A declaration
1156 /// inference reported an error for is here as [`Solved::Rejected`], and its error is
1157 /// in [`errors`](Self::errors).
1158 pub solved: HashMap<Name, Solved>,
1159 /// One entry per instance the module declares, in the order
1160 /// [`canonical::Module::instances`] holds them: what each is for and an answer for
1161 /// every binding of its body.
1162 pub instances: Vec<SolvedInstance>,
1163 /// The classes of this module with a derivation binding that was rejected, by name.
1164 /// The error is in [`errors`](Self::errors), at the class.
1165 pub rejected_derivations: Vec<Name>,
1166 /// Every error inference reported, one per rejected declaration, binding or instance.
1167 /// Empty means the module type checked.
1168 pub errors: Vec<Error>,
1169}
1170
1171/// [`type_check_recovering`], reduced to a module that either type checked or did not:
1172/// the solved map when no declaration failed, every error otherwise.
1173pub fn type_check(
1174 module: &Module,
1175 interfaces: &HashMap<Name, Interface>,
1176) -> Result<HashMap<Name, Solved>, Vec<Error>> {
1177 let TypeCheck { solved, errors, .. } = type_check_recovering(module, interfaces);
1178
1179 if errors.is_empty() {
1180 Ok(solved)
1181 } else {
1182 Err(errors)
1183 }
1184}
1185
1186/// Type check one canonical module and hand back what it solved, reporting every value
1187/// whose inference produced a reportable error rather than stopping at the first — the
1188/// shape `compile_package` is built to accumulate.
1189///
1190/// # What comes back
1191///
1192/// One [`Solved`] per declaration, keyed the way `module.values` is, whether or not
1193/// any declaration failed. A declaration the typer could not type is present and says
1194/// so; none is ever merely absent, because absent is indistinguishable from
1195/// checked-and-fine to whatever reads this next
1196/// ([`DEC-18` decision 1](../../docs/decisions/dec-18.md)). One that inference
1197/// reported an error for is [`Solved::Rejected`], with the error in
1198/// [`TypeCheck::errors`], so a module with a type error still has a typed term for
1199/// each of its other declarations
1200/// ([`DEC-23` decision 5](../../docs/decisions/dec-23.md)).
1201///
1202/// The term inside [`Solved::Typed`] is the one `annotate` built, with `unify`'s final
1203/// substitution applied to every node rather than to the declaration's own type alone.
1204/// That interior is the point — a backend needs the type of each sub-expression, not
1205/// just of the declaration containing it.
1206///
1207/// Every instance the module declares is answered for the same way, one
1208/// [`SolvedInstance`] each, with a [`Solved`] for each binding of its body: a binding is a
1209/// declaration whose annotation is the member's signature at the instance's type.
1210///
1211/// # Where an [`Error`] is built
1212///
1213/// Here, and only here: this is the last frame that holds the `canonical::Value`, so
1214/// it is the only one that knows the declaration's name and its span. What went
1215/// *wrong* and *where inside the declaration* comes up from inference on the
1216/// [`ErrorKind`]; see [`Error`].
1217///
1218/// # What a declaration is checked against
1219///
1220/// `interfaces` is the map `module` was canonicalized against. Every value and union
1221/// it exposes is put in the typer's environment beside this module's own, so a
1222/// declaration that forwards an imported value, builds an imported constructor or
1223/// matches on one is checked like any other. Each use of one of those names gets a
1224/// fresh instance of its declared type, so one declaration can use `Just` or
1225/// `Maybe.withDefault` at two types — see `Types`.
1226///
1227/// A name's entry is a context and a type (`Scheme`). A class member's is its
1228/// signature with its class's constraint in front, from the module's own classes and from
1229/// every imported interface's; a function's is its annotation's context and type. Each
1230/// use of one raises the obligations its context asks, which are answered once the
1231/// declaration's equations are solved — see the `classes` module.
1232pub fn type_check_recovering(module: &Module, interfaces: &HashMap<Name, Interface>) -> TypeCheck {
1233 // A `module foreign` facade uses synthetic placeholder bodies, so there is nothing
1234 // to infer — but every declaration still has to be accounted for, so each is
1235 // returned saying why it has no term.
1236 if module.binding_foreign {
1237 return TypeCheck {
1238 solved: module
1239 .values
1240 .keys()
1241 .map(|name| (name.clone(), Solved::NoBody))
1242 .collect(),
1243 instances: Vec::new(),
1244 rejected_derivations: Vec::new(),
1245 errors: Vec::new(),
1246 };
1247 }
1248
1249 // Start at a high offset to avoid collisions with the counter inside
1250 // Types::new() (which starts at 10) used during inference.
1251 let mut counter = 10_000u32;
1252
1253 // First pass: build global env from every declared type in reach — the values
1254 // each imported interface exposes, then this module's own annotated values, broken
1255 // ones included.
1256 let mut global: HashMap<String, Scheme> = HashMap::new();
1257
1258 // An imported value is keyed the way a `VarForeign` reference spells it: its name
1259 // qualified by the package and module that declared it ([`environment_key`]). That
1260 // is the only key, so it cannot collide with a local name or with a same-named value
1261 // of another module, in this package or another. An operator's backing function the
1262 // header did not expose by name is in `infix_functions` rather than `values`, and an
1263 // operator resolves to a `VarForeign` naming it all the same.
1264 for interface in interfaces.values() {
1265 for (name, signature) in interface.values.iter().chain(&interface.infix_functions) {
1266 if let Some(scheme) = scheme_of(&signature.tpe, &signature.context, &mut counter) {
1267 let qname = interface.module_name.qualify_name(name);
1268 global.insert(environment_key(&qname), scheme);
1269 }
1270 }
1271
1272 // A member is in no interface's `values`: it travels with its class, and is
1273 // declared here the way a value is, under the name a `VarForeign` spells.
1274 for (class_name, signature) in &interface.classes {
1275 insert_members(
1276 &mut global,
1277 &interface.module_name,
1278 class_name,
1279 signature,
1280 &mut counter,
1281 );
1282 }
1283 }
1284
1285 // This module's own classes' members, under the name a `VarTopLevel` spells.
1286 for (class_name, class) in &module.classes {
1287 insert_members(
1288 &mut global,
1289 &module.name,
1290 class_name,
1291 &class.signature,
1292 &mut counter,
1293 );
1294 }
1295
1296 // A declaration canonicalization recorded as broken is declared by its annotation,
1297 // when that canonicalized, exactly as an annotated one is: a caller is checked
1298 // against the type the declaration was written with, whatever is wrong with its body.
1299 let annotated = module
1300 .values
1301 .iter()
1302 .filter_map(|(name, value)| match value {
1303 canonical::Value::TypedValue { tpe, context, .. } => Some((name, tpe, context)),
1304 canonical::Value::Value { .. } => None,
1305 });
1306 let broken = module
1307 .broken
1308 .iter()
1309 .filter_map(|broken| Some((&broken.name, broken.tpe.as_ref()?, &broken.context)));
1310
1311 for (name, tpe, context) in annotated.chain(broken) {
1312 if let Some(scheme) = scheme_of(tpe, context, &mut counter) {
1313 // Add both qualified (e.g. "test-project:Test.not") and unqualified (e.g.
1314 // "not") names
1315 let qname = environment_key(&module.name.qualify_name(name));
1316 global.insert(qname, scheme.clone());
1317 global.insert(name.as_str().to_string(), scheme);
1318 }
1319 }
1320
1321 // What the canonical AST is read against: every union in reach, their
1322 // constructors and the arity of each of this module's declarations. See
1323 // [`Translation`].
1324 let translation = Translation::of(module, interfaces);
1325
1326 // Second pass: add constructor types to global from every union in reach, this
1327 // module's own and every imported interface's alike.
1328 for (type_name, union_type) in &translation.unions {
1329 // Fresh type vars for each ADT type parameter (e.g. "a" in Maybe a)
1330 let mut adt_var_map: HashMap<String, TypeVariable> = HashMap::new();
1331 for tv_name in &union_type.variables {
1332 counter += 1;
1333 adt_var_map.insert(
1334 tv_name.as_str().to_string(),
1335 TypeVariable::flexible(counter),
1336 );
1337 }
1338
1339 // Build result type: Adt(type_name, [TypeVar for each param])
1340 let result_args: Vec<Type> = union_type
1341 .variables
1342 .iter()
1343 .map(|v| Type::Variable(adt_var_map[v.as_str()].clone()))
1344 .collect();
1345 let result_type = Type::Adt(type_name.clone(), result_args);
1346
1347 for ctor in &union_type.variants {
1348 let ctor_type = if ctor.type_parameters.is_empty() {
1349 result_type.clone()
1350 } else {
1351 let mut translate_var_map = adt_var_map.clone();
1352 let params: Vec<Type> = ctor
1353 .type_parameters
1354 .iter()
1355 .filter_map(|t| {
1356 canonical_type_to_typer_type(t, &mut translate_var_map, &mut counter)
1357 })
1358 .collect();
1359 if params.len() != ctor.type_parameters.len() {
1360 continue; // untranslatable param type, skip this constructor
1361 }
1362 // Build Fun type: p1 -> p2 -> ... -> result_type
1363 params
1364 .into_iter()
1365 .rev()
1366 .fold(result_type.clone(), |acc, p| Type::Fun {
1367 param_tpe: Box::new(p),
1368 return_tpe: Box::new(acc),
1369 })
1370 };
1371
1372 // Registered under the qualified name a `VarConstructor` spells —
1373 // "zelkova-core:Maybe.Just", named by the package and module that declared
1374 // the union — and, for this module's own unions only, under the bare name
1375 // too. A union of another package's module of the same name is not this
1376 // module's own: its `QualName` differs in the package.
1377 let qname = type_name.sibling(&ctor.name);
1378 if module.name.qualify_name(&type_name.unqualified_name()) == *type_name {
1379 global.insert(
1380 ctor.name.as_str().to_string(),
1381 Scheme::unconstrained(ctor_type.clone()),
1382 );
1383 }
1384 global.insert(environment_key(&qname), Scheme::unconstrained(ctor_type));
1385 }
1386 }
1387
1388 // The constructor of `Basics.Position` builds the place of a constructor from an
1389 // `Int`. A module that declares `Position` has declared it above, and one that does
1390 // not still has a derived instance that builds one.
1391 let (position_name, _) = position_constructor();
1392 global
1393 .entry(environment_key(&position_name))
1394 .or_insert_with(|| {
1395 Scheme::unconstrained(Type::Fun {
1396 param_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
1397 return_tpe: Box::new(position_type()),
1398 })
1399 });
1400
1401 // Third pass: check each value. A value that fails is recorded and the pass
1402 // moves on, so one broken declaration cannot hide the others.
1403 //
1404 // In the order of their names, because each declaration's rigid variables are numbered
1405 // from `counter` and stay in the types that come back: an order that depended on the
1406 // hash map would number the same declaration differently from one run to the next.
1407 let spellings = Spellings::of(module, interfaces);
1408 let table = classes::ClassTable::of(module, interfaces);
1409 let mut errors: Vec<Error> = vec![];
1410 let mut solved: HashMap<Name, Solved> = HashMap::new();
1411 let mut values: Vec<(&Name, &canonical::Value)> = module.values.iter().collect();
1412 values.sort_by(|left, right| left.0.cmp(right.0));
1413 for (name, value) in values {
1414 let Some((term, annotation)) =
1415 value_to_term_and_annotation(value, &translation, &mut counter)
1416 else {
1417 // Unsupported construct: nothing was checked, and the entry says so
1418 // rather than the declaration going missing — see [`Solved`].
1419 solved.insert(name.clone(), Solved::Untranslatable { span: value.span() });
1420 continue;
1421 };
1422
1423 // The annotation is handed to inference rather than checked against its
1424 // result afterwards, which is what lets a mismatch *inside* the body know
1425 // that the type it failed against came from the annotation. Checking the two
1426 // whole types at the end could only ever say "this declaration is `Int` and
1427 // its body is something else", with the caret across the lot.
1428 let answer = match solve(term, annotation, &global, &table) {
1429 Ok(answer) => answer,
1430 // The declaration is answered for as well as reported, so the rest of the
1431 // module keeps the terms it solved.
1432 Err(kind) => {
1433 errors.push(Error {
1434 kind,
1435 span: value.span(),
1436 declaration: name.clone(),
1437 within: Within::Value,
1438 spellings: spellings.clone(),
1439 });
1440 Solved::Rejected
1441 }
1442 };
1443 solved.insert(name.clone(), answer);
1444 }
1445
1446 // Fourth pass: the derivations of this module's own classes. A derived instance carries
1447 // these bindings placed in its members, but a class that nothing derives has them
1448 // checked all the same, and an error in one is at the class, where it was written. It
1449 // runs before the instances so that an instance derived from a class whose derivation
1450 // is wrong does not report the same mistake again in the members it was given.
1451 let rejected_derivations = DerivationCheck {
1452 global: &global,
1453 table: &table,
1454 translation: &translation,
1455 spellings: &spellings,
1456 }
1457 .of(module, &mut counter, &mut errors);
1458 let rejected: HashSet<QualName> = rejected_derivations
1459 .iter()
1460 .map(|class| module.name.qualify_name(class))
1461 .collect();
1462
1463 // Fifth pass: every instance, which is checked as a declaration is — its bindings
1464 // are values whose annotation is the member's signature at the instance's type — and
1465 // as a whole, for the superclasses its class asks of it.
1466 let instances = module
1467 .instances
1468 .iter()
1469 .map(|instance| {
1470 let check = InstanceCheck {
1471 global: &global,
1472 table: &table,
1473 translation: &translation,
1474 spellings: &spellings,
1475 rejected: &rejected,
1476 };
1477 check.of(instance, &mut counter, &mut errors)
1478 })
1479 .collect();
1480
1481 TypeCheck {
1482 solved,
1483 instances,
1484 rejected_derivations,
1485 errors,
1486 }
1487}
1488
1489/// Infer one declaration, or one binding of an instance, to the [`Solved`] it ends up as:
1490/// its typed term, or the entry saying a name was out of the typer's reach. An error to
1491/// report is the `Err`.
1492fn solve(
1493 term: Term,
1494 annotation: Option<Annotation>,
1495 global: &HashMap<String, Scheme>,
1496 table: &classes::ClassTable,
1497) -> Result<Solved, ErrorKind> {
1498 match infer_annotated(term, global.clone(), annotation, table) {
1499 // An unbound variable here is a hole in the typer's environment, not a
1500 // mistake in the source — see [`Solved::UnboundName`].
1501 Err(ErrorKind::UnboundVariable { name, span }) => Ok(Solved::UnboundName { name, span }),
1502 Err(kind) => Err(kind),
1503 Ok((term, context)) => Ok(Solved::Typed {
1504 term: Box::new(term),
1505 context,
1506 }),
1507 }
1508}
1509
1510/// What an instance's bindings are checked under: the type the instance is for, where its
1511/// head line was written, and what its context gives of the head's variables.
1512struct InstanceScope<'a> {
1513 head: &'a Type,
1514 span: NodeSpan,
1515 given: &'a [(QualName, TypeVariable)],
1516 names: &'a [(TypeVariable, Name)],
1517}
1518
1519/// What checking an instance reads besides the instance itself.
1520struct InstanceCheck<'a> {
1521 global: &'a HashMap<String, Scheme>,
1522 table: &'a classes::ClassTable<'a>,
1523 translation: &'a Translation<'a>,
1524 spellings: &'a Spellings,
1525 /// The classes of this module whose derivations this pass rejected.
1526 rejected: &'a HashSet<QualName>,
1527}
1528
1529impl InstanceCheck<'_> {
1530 /// Check `instance`: each of its bindings against its member's signature at the
1531 /// instance's type, and the instance as a whole against the superclasses its class
1532 /// has. Errors are pushed onto `errors`.
1533 ///
1534 /// The instance's context is *given* in both, as an annotation's is inside a
1535 /// declaration: the variables the head binds are variables of the unification, a
1536 /// constraint of the context is on one of them, and an obligation on that same
1537 /// variable is answered by it.
1538 ///
1539 /// A derived instance is checked like any other. Canonicalization gave it the members
1540 /// its class's derivation stands for and the context its type's arguments need, so its
1541 /// superclasses are discharged against that context, and an error in a generated
1542 /// binding is on the span of the word `derived`. Where the class's derivations were
1543 /// rejected, in this module or the one that declares it, the class has the error and a
1544 /// derived instance's members, which are generated out of the derivation that failed,
1545 /// report none of their own.
1546 fn of(
1547 &self,
1548 instance: &canonical::Instance,
1549 counter: &mut u32,
1550 errors: &mut Vec<Error>,
1551 ) -> SolvedInstance {
1552 let signature = &instance.signature;
1553
1554 let mut variables: HashMap<String, TypeVariable> = HashMap::new();
1555 let head = instance_head_type(&signature.head, &mut variables, counter);
1556 let head = make_rigid(head, &mut variables, Binder::InstanceHead);
1557 let given: Vec<(QualName, TypeVariable)> = signature
1558 .context
1559 .iter()
1560 .filter_map(|constraint| {
1561 Some((
1562 constraint.class.clone(),
1563 variables.get(constraint.variable.as_str())?.clone(),
1564 ))
1565 })
1566 .collect();
1567 let context = given
1568 .iter()
1569 .map(|(class, variable)| Predicate {
1570 class: class.clone(),
1571 tpe: Type::Variable(variable.clone()),
1572 })
1573 .collect();
1574 let mut names: Vec<(TypeVariable, Name)> = variables
1575 .iter()
1576 .map(|(name, variable)| (variable.clone(), Name::new(name.clone())))
1577 .collect();
1578 names.sort_by(|left, right| left.1.cmp(&right.1));
1579
1580 let text = instance_text(signature, &head, &names);
1581 let class = self.table.class(&signature.class);
1582
1583 let mut rejected = false;
1584 let mut bindings = Vec::new();
1585
1586 // The members of an instance derived from a class whose derivations were rejected
1587 // restate the class's error, so an error in one is left to it.
1588 let restated = instance.derived
1589 && (self.rejected.contains(&signature.class)
1590 || class.is_some_and(|class| class.derivations_rejected));
1591
1592 if let Some(class) = class {
1593 let obligations = class
1594 .superclasses
1595 .iter()
1596 .map(|superclass| classes::Obligation {
1597 class: superclass.class.clone(),
1598 tpe: head.clone(),
1599 origin: Origin::new(Reason::SuperclassInstance, signature.span),
1600 })
1601 .collect();
1602
1603 let declared = classes::Declared {
1604 tpe: &head,
1605 annotated: true,
1606 given: &given,
1607 names: &names,
1608 member_variables: &[],
1609 written: Written::InstanceContext,
1610 };
1611
1612 if let Err(kind) =
1613 classes::discharge(self.table, obligations, &Substitution::empty(), &declared)
1614 {
1615 rejected = true;
1616 errors.push(Error {
1617 kind,
1618 span: signature.span,
1619 declaration: Name::new(text.clone()),
1620 within: Within::Instance,
1621 spellings: self.spellings.clone(),
1622 });
1623 }
1624 }
1625
1626 for value in &instance.bindings {
1627 let canonical::Value::Value { name, .. } = value else {
1628 continue;
1629 };
1630
1631 let scope = InstanceScope {
1632 head: &head,
1633 span: signature.span,
1634 given: &given,
1635 names: &names,
1636 };
1637
1638 let answer = match self.binding(value, class, &scope, counter) {
1639 Some(Ok(answer)) => answer,
1640 Some(Err(kind)) => {
1641 if !restated {
1642 errors.push(Error {
1643 kind,
1644 span: value.span(),
1645 declaration: name.clone(),
1646 within: Within::Binding(text.clone()),
1647 spellings: self.spellings.clone(),
1648 });
1649 }
1650 Solved::Rejected
1651 }
1652 None => Solved::Untranslatable { span: value.span() },
1653 };
1654 bindings.push((name.clone(), answer));
1655 }
1656
1657 SolvedInstance {
1658 head,
1659 context,
1660 bindings,
1661 rejected,
1662 }
1663 }
1664
1665 /// One binding of an instance's body, inferred against the signature of the member it
1666 /// defines, with the class variable replaced by the instance's head. `None` when it
1667 /// cannot be read: the binding does not translate, or its class has no member of that
1668 /// name in reach — which canonicalization has reported.
1669 fn binding(
1670 &self,
1671 value: &canonical::Value,
1672 class: Option<&canonical::ClassSignature>,
1673 scope: &InstanceScope,
1674 counter: &mut u32,
1675 ) -> Option<Result<Solved, ErrorKind>> {
1676 let canonical::Value::Value { name, .. } = value else {
1677 return None;
1678 };
1679 let class = class?;
1680 let member = class.members.iter().find(|member| &member.name == name)?;
1681
1682 let (term, _) = value_to_term_and_annotation(value, self.translation, counter)?;
1683
1684 // The member's signature has the class variable free in it. It is translated like
1685 // any annotation, and the variable it came out as is replaced by the head: every
1686 // other variable of the signature stays one of its own.
1687 let mut variables: HashMap<String, TypeVariable> = HashMap::new();
1688 let signature = canonical_type_to_typer_type(&member.tpe, &mut variables, counter)?;
1689 let signature = make_rigid(signature, &mut variables, Binder::MemberSignature);
1690 let class_variable = variables.get(class.variable.as_str())?;
1691 let tpe = Substitution::substitute(signature, class_variable, scope.head);
1692
1693 // What the signature binds besides the class variable is the member's own, and is
1694 // written the way the class wrote it.
1695 let mut names = scope.names.to_vec();
1696 let mut member_variables = Vec::new();
1697 for (written, variable) in &variables {
1698 if variable != class_variable {
1699 names.push((variable.clone(), Name::new(written.clone())));
1700 member_variables.push(variable.clone());
1701 }
1702 }
1703 names.sort_by(|left, right| left.1.cmp(&right.1));
1704
1705 // The head line stands where an annotation would: the span a mismatch with the
1706 // member's signature draws its second label under.
1707 let annotation = Annotation {
1708 tpe,
1709 span: scope.span,
1710 reason: Reason::InstanceMember,
1711 context: scope.given.to_vec(),
1712 names,
1713 member_variables,
1714 written: Written::InstanceContext,
1715 };
1716
1717 Some(solve(term, Some(annotation), self.global, self.table))
1718 }
1719}
1720
1721/// `Basics.Position`'s one constructor, and where it sits: the compiler knows it by
1722/// name, as it knows the scalars ([`scalars::POSITION`]).
1723fn position_constructor() -> (QualName, Constructor) {
1724 let union = scalars::POSITION.qual_name();
1725 let name = Name::new(scalars::POSITION.name);
1726
1727 (
1728 union.sibling(&name),
1729 Constructor {
1730 union,
1731 name,
1732 index: 0,
1733 arity: 1,
1734 },
1735 )
1736}
1737
1738/// The type `Basics.Position`: what `differed` and `atConstructor` are handed.
1739fn position_type() -> Type {
1740 Type::Adt(scalars::POSITION.qual_name(), Vec::new())
1741}
1742
1743/// What checking the derivations of a module's classes reads.
1744struct DerivationCheck<'a> {
1745 global: &'a HashMap<String, Scheme>,
1746 table: &'a classes::ClassTable<'a>,
1747 translation: &'a Translation<'a>,
1748 spellings: &'a Spellings,
1749}
1750
1751impl DerivationCheck<'_> {
1752 /// Check the bindings of every derivation of `module`'s classes, each as a declaration
1753 /// annotated with the type the chapter gives its role over the type the member
1754 /// answers with — `matched : R`, `differed : Position -> Position -> R`,
1755 /// `atConstructor : Position -> R` and `combine : R -> R -> R`. Errors are pushed onto
1756 /// `errors`, classes in the order of their names. The classes with a binding that did
1757 /// not check come back by name, in that order.
1758 ///
1759 /// No context is given to a binding: none of them mentions the class variable, so each
1760 /// stands for every type that derives the class, and what one needs of a type is an
1761 /// instance in scope or an error. A variable the answer type holds is the member
1762 /// signature's own, and is rigid. `Comparable`'s `differed i j = compare i j` needs
1763 /// `Comparable Position`.
1764 fn of(&self, module: &Module, counter: &mut u32, errors: &mut Vec<Error>) -> Vec<Name> {
1765 let mut classes: Vec<_> = module.classes.iter().collect();
1766 classes.sort_by(|left, right| left.0.cmp(right.0));
1767
1768 let mut rejected = Vec::new();
1769 for (name, class) in classes {
1770 let before = errors.len();
1771 for derivation in &class.signature.derivations {
1772 for (role, value) in derivation.bindings.roles() {
1773 self.binding(derivation, role, value, counter, errors);
1774 }
1775 }
1776 if errors.len() > before {
1777 rejected.push(name.clone());
1778 }
1779 }
1780 rejected
1781 }
1782
1783 fn binding(
1784 &self,
1785 derivation: &canonical::Derivation,
1786 role: canonical::DerivationRole,
1787 value: &canonical::Value,
1788 counter: &mut u32,
1789 errors: &mut Vec<Error>,
1790 ) {
1791 let canonical::Value::Value { name, .. } = value else {
1792 return;
1793 };
1794 let Some((term, _)) = value_to_term_and_annotation(value, self.translation, counter) else {
1795 return;
1796 };
1797
1798 let mut variables: HashMap<String, TypeVariable> = HashMap::new();
1799 let Some(answer) =
1800 canonical_type_to_typer_type(&derivation.result, &mut variables, counter)
1801 else {
1802 return;
1803 };
1804 // A variable of the answer type is one the member's signature binds beyond the
1805 // class's, which every caller of the member chooses for itself: a binding is held
1806 // to every type it may stand for.
1807 let answer = make_rigid(answer, &mut variables, Binder::MemberSignature);
1808 let function = |parameters: Vec<Type>, result: Type| {
1809 parameters
1810 .into_iter()
1811 .rev()
1812 .fold(result, |result, parameter| Type::Fun {
1813 param_tpe: Box::new(parameter),
1814 return_tpe: Box::new(result),
1815 })
1816 };
1817 let tpe = match role {
1818 canonical::DerivationRole::Matched => answer.clone(),
1819 canonical::DerivationRole::Differed => {
1820 function(vec![position_type(), position_type()], answer.clone())
1821 }
1822 canonical::DerivationRole::AtConstructor => {
1823 function(vec![position_type()], answer.clone())
1824 }
1825 canonical::DerivationRole::Combine => {
1826 function(vec![answer.clone(), answer.clone()], answer.clone())
1827 }
1828 };
1829
1830 let mut names: Vec<(TypeVariable, Name)> = variables
1831 .iter()
1832 .map(|(name, variable)| (variable.clone(), Name::new(name.clone())))
1833 .collect();
1834 names.sort_by(|left, right| left.1.cmp(&right.1));
1835
1836 let annotation = Annotation {
1837 tpe,
1838 span: derivation.span,
1839 reason: Reason::DerivationBinding,
1840 context: Vec::new(),
1841 names,
1842 member_variables: Vec::new(),
1843 written: Written::Derivation,
1844 };
1845
1846 if let Err(kind) = solve(term, Some(annotation), self.global, self.table) {
1847 errors.push(Error {
1848 kind,
1849 span: value.span(),
1850 declaration: name.clone(),
1851 within: Within::Derivation(derivation.member.to_string()),
1852 spellings: self.spellings.clone(),
1853 });
1854 }
1855 }
1856}
1857
1858/// `instance Eq a => Eq (Box a)`, minus the keyword: how a message names an instance.
1859fn instance_text(
1860 signature: &canonical::InstanceSignature,
1861 head: &Type,
1862 names: &[(TypeVariable, Name)],
1863) -> String {
1864 let names: VariableNames = names
1865 .iter()
1866 .map(|(variable, name)| (variable.clone(), name.to_string()))
1867 .collect();
1868 let text = WithNames(head, &names).to_string();
1869 let head = match head {
1870 Type::Adt(_, args) if !args.is_empty() => format!("({})", text),
1871 _ => text,
1872 };
1873 let constraints: Vec<String> = signature
1874 .context
1875 .iter()
1876 .map(|constraint| {
1877 format!(
1878 "{} {}",
1879 constraint.class.unqualified_name(),
1880 constraint.variable
1881 )
1882 })
1883 .collect();
1884 let context = match constraints.as_slice() {
1885 [] => String::new(),
1886 [one] => format!("{} => ", one),
1887 many => format!("({}) => ", many.join(", ")),
1888 };
1889
1890 format!("{}{} {}", context, signature.class.unqualified_name(), head)
1891}
1892
1893/// The scheme a declared type and the context written in front of it make: the type as
1894/// the typer reads it, and each constraint on the variable it was translated to.
1895fn scheme_of(
1896 tpe: &canonical::Type,
1897 context: &[canonical::Constraint],
1898 counter: &mut u32,
1899) -> Option<Scheme> {
1900 let mut variables = HashMap::new();
1901 let tpe = canonical_type_to_typer_type(tpe, &mut variables, counter)?;
1902 let context = context
1903 .iter()
1904 .filter_map(|constraint| {
1905 Some(Predicate {
1906 class: constraint.class.clone(),
1907 tpe: Type::Variable(variables.get(constraint.variable.as_str())?.clone()),
1908 })
1909 })
1910 .collect();
1911
1912 Some(Scheme { context, tpe })
1913}
1914
1915/// Declare the members of a class `module_name` declares, each under the name a
1916/// reference to it spells ([`environment_key`]): its signature, with the class's own
1917/// constraint in front.
1918fn insert_members(
1919 global: &mut HashMap<String, Scheme>,
1920 module_name: &ModuleName,
1921 class_name: &Name,
1922 class: &canonical::ClassSignature,
1923 counter: &mut u32,
1924) {
1925 let declared = module_name.qualify_name(class_name);
1926
1927 for member in &class.members {
1928 let mut variables = HashMap::new();
1929 let Some(tpe) = canonical_type_to_typer_type(&member.tpe, &mut variables, counter) else {
1930 continue;
1931 };
1932
1933 // Every member's signature mentions the class variable, so it is always found;
1934 // canonicalization rejects a class with a member that does not.
1935 let Some(variable) = variables.get(class.variable.as_str()) else {
1936 continue;
1937 };
1938 let context = vec![Predicate {
1939 class: declared.clone(),
1940 tpe: Type::Variable(variable.clone()),
1941 }];
1942
1943 global.insert(
1944 environment_key(&module_name.qualify_name(&member.name)),
1945 Scheme { context, tpe },
1946 );
1947 }
1948}
1949
1950// ── Translation helpers ───────────────────────────────────────────────────────
1951
1952/// The key the typer's environment holds a declaration's type under: the package that
1953/// declares it, a `:`, then its qualified name — `zelkova-core:Maybe.withDefault`.
1954///
1955/// The package is in the key for the reason it is in a [`QualName`]: two packages may
1956/// each hold a module `Size`, and `Size.foo` alone would give both declarations one
1957/// entry, owned by whichever was inserted last. Neither a package name nor a module name
1958/// can contain a `:`, so no two declarations share a key, and no key is a bare name a
1959/// local is looked up by.
1960fn environment_key(qname: &QualName) -> String {
1961 format!("{}:{}", qname.package(), qname.to_name())
1962}
1963
1964/// Union declarations, keyed by the qualified name of each declaration.
1965///
1966/// Keyed that way rather than by the spelling, so that a lookup answers "is this the
1967/// declaration that module named?" and not "is something spelled like that in reach?".
1968/// The two differ for every imported constructor whose type shares a name with a local
1969/// one, which is what `BUG-35` closed.
1970type Unions<'a> = HashMap<QualName, &'a canonical::UnionType>;
1971
1972/// Everything the translation from the canonical AST reads besides the expression in
1973/// front of it.
1974///
1975/// Each of them answers a question the canonical node cannot: which union a constructor
1976/// belongs to and where in it, and how many arguments a call has to supply before it is a
1977/// direct call. All of them are facts of the module and of what it imports, which is why
1978/// they are gathered once here — the declaration being translated is the only thing that
1979/// changes between calls.
1980struct Translation<'a> {
1981 /// Every union in reach — this module's own, and every one an imported
1982 /// [`Interface`] exposes — keyed by the qualified name that identifies each
1983 /// declaration rather than by the spelling the `type` line wrote. A constructor
1984 /// carries the qualified name of the type it builds, so this key is what finds the
1985 /// declaration a constructor in a pattern belongs to — see [`translate_pattern`].
1986 ///
1987 /// An interface's union is only as complete as its module exposed it: an opaque
1988 /// one crosses with no constructors, which is also why no canonical constructor
1989 /// can name one.
1990 unions: Unions<'a>,
1991 /// The constructors of every union in [`unions`](Self::unions), keyed the way a
1992 /// `VarConstructor` spells one, each with the place in its declaration both
1993 /// backends need.
1994 constructors: HashMap<QualName, Constructor>,
1995 /// How many parameters each of this module's declarations was written with.
1996 ///
1997 /// This is the callee's arity at a call site naming one of them, which is what
1998 /// decides an application's [`Saturation`]. The rule itself — parameter count, not
1999 /// arrow count — is [`canonical::Value::arity`], which `ir::build` reads too.
2000 arities: HashMap<Name, usize>,
2001 /// How many parameters each value an imported [`Interface`] exposes is emitted with
2002 /// ([`Interface::arities`]), keyed the way a `VarForeign` spells it: its name
2003 /// qualified by the package and module that declared it.
2004 ///
2005 /// It is the same fact as [`arities`](Self::arities), recorded by the module that
2006 /// declared the value, so a call to it is saturated at the count its emitted function
2007 /// takes. It is also what [`ReferenceKind::Foreign`] carries, since a backend using an
2008 /// imported function as a value needs its arity too.
2009 foreign_arities: HashMap<QualName, usize>,
2010}
2011
2012impl<'a> Translation<'a> {
2013 /// The translation for `module`, checked against `interfaces`.
2014 ///
2015 /// The interfaces' unions go in first and this module's own after them, so that if
2016 /// the map somehow held an interface of the module under check, the declarations
2017 /// in front of the typer are the ones that win.
2018 fn of(module: &'a Module, interfaces: &'a HashMap<Name, Interface>) -> Translation<'a> {
2019 let mut unions: Unions<'a> = HashMap::new();
2020 let mut foreign_arities = HashMap::new();
2021
2022 for interface in interfaces.values() {
2023 for (name, union_type) in &interface.unions {
2024 unions.insert(interface.module_name.qualify_name(name), union_type);
2025 }
2026
2027 // Every value the typer's environment registers for this interface, so that
2028 // every `VarForeign` it can type has an arity here. One the interface did not
2029 // record is read as a parameterless binding's: see `Interface::arities`.
2030 for name in interface
2031 .values
2032 .keys()
2033 .chain(interface.infix_functions.keys())
2034 {
2035 let arity = interface.arities.get(name).copied().unwrap_or(0);
2036 foreign_arities.insert(interface.module_name.qualify_name(name), arity);
2037 }
2038 }
2039
2040 for (name, union_type) in &module.types {
2041 unions.insert(module.name.qualify_name(name), union_type);
2042 }
2043
2044 let mut constructors = constructors_of(&unions);
2045 // `Basics.Position`'s constructor is known whether or not an interface in reach
2046 // carries it, since a derived instance builds one and no module exposes it.
2047 let (position_name, position) = position_constructor();
2048 constructors.entry(position_name).or_insert(position);
2049
2050 let arities = module
2051 .values
2052 .iter()
2053 .map(|(name, value)| (name.clone(), value.arity()))
2054 .collect();
2055
2056 Translation {
2057 unions,
2058 constructors,
2059 arities,
2060 foreign_arities,
2061 }
2062 }
2063
2064 /// A translation that knows these unions and nothing else: no arity is known, so
2065 /// every application it produces is [`Saturation::Partial`].
2066 #[cfg(test)]
2067 fn of_types(unions: Unions<'a>) -> Translation<'a> {
2068 let constructors = constructors_of(&unions);
2069
2070 Translation {
2071 unions,
2072 constructors,
2073 arities: HashMap::new(),
2074 foreign_arities: HashMap::new(),
2075 }
2076 }
2077
2078 /// How many arguments the callee of an application spine takes, when this module
2079 /// knows.
2080 ///
2081 /// A declaration of this module, one of another module and a constructor each have
2082 /// one. `None` is what makes an application [`Saturation::Partial`], and it is the
2083 /// honest answer twice over: a local is a value rather than a declaration and has no
2084 /// arity at all, and a callee that is itself an expression — the result of a `case`,
2085 /// say — is a value too. A backend that cannot prove a call saturated goes through
2086 /// `$curry`, which is correct for both.
2087 fn callee_arity(&self, callee: &canonical::Expression) -> Option<usize> {
2088 match &callee.kind {
2089 canonical::ExpressionKind::VarTopLevel(qname) => {
2090 self.arities.get(&qname.unqualified_name()).copied()
2091 }
2092 canonical::ExpressionKind::VarForeign(qname, _, _) => Some(self.foreign_arity(qname)),
2093 canonical::ExpressionKind::VarConstructor(qname, _) => {
2094 self.constructors.get(qname).map(|ctor| ctor.arity)
2095 }
2096 _ => None,
2097 }
2098 }
2099
2100 /// The arity of `qname`, a value another module declares, as its interface recorded
2101 /// it — 0 for one no interface in reach records, the arity of a parameterless binding.
2102 ///
2103 /// Every name canonicalization resolves to a `VarForeign` is one an interface in
2104 /// reach exposes, so the fallback is for a value its module recorded as broken, or for
2105 /// a hand-built interface map; see [`Interface::arities`].
2106 fn foreign_arity(&self, qname: &QualName) -> usize {
2107 self.foreign_arities.get(qname).copied().unwrap_or(0)
2108 }
2109}
2110
2111/// Every constructor of `unions`, keyed the way a `VarConstructor` spells one: the
2112/// constructor's name qualified by the package and module that declared the union it
2113/// builds.
2114fn constructors_of(unions: &Unions) -> HashMap<QualName, Constructor> {
2115 let mut constructors = HashMap::new();
2116
2117 for (union, union_type) in unions {
2118 for variant in crate::ir::variants_of(union_type) {
2119 // A union is named by its declaring package and module, so that is where
2120 // its constructors are named from too.
2121 let name = union.sibling(&variant.name);
2122
2123 constructors.insert(
2124 name,
2125 Constructor {
2126 union: union.clone(),
2127 name: variant.name,
2128 index: variant.index,
2129 arity: variant.arity,
2130 },
2131 );
2132 }
2133 }
2134
2135 constructors
2136}
2137
2138/// Convert a canonical type to the typer's simplified Type representation.
2139///
2140/// Every variant of [`canonical::Type`] converts, so this answers `None` for no type
2141/// today. The `Option` is what a type form the typer cannot read would answer, and the
2142/// callers keep their handling of it: a declaration whose annotation is `None` here is
2143/// left unchecked ([`value_to_term_and_annotation`]), and a value or a constructor whose
2144/// declared type is `None` is not in the environment inference reads, so a name reaching
2145/// one is [`Solved::UnboundName`].
2146///
2147/// `var_map` maps named type variables (e.g. "a") to consistent TypeVariable
2148/// ids, so that `a -> a` produces the same variable on both sides.
2149///
2150/// # How a name decides which type it becomes
2151///
2152/// A [`canonical::Type::Type`] names its declaration in full — `Widget.Size`, not
2153/// `Size` (`AST-4`) — and the whole of that name is what picks the arm. A nullary
2154/// type whose qualified name is [a scalar the compiler
2155/// knows](super::scalars) becomes the matching [`Type::Literal`]; everything else
2156/// becomes a [`Type::Adt`], carrying that name whole.
2157///
2158/// For a name that resolved, that is the declaring module's. For one that resolved to
2159/// nothing it is the module under check, applied to the whole *written* spelling, dots
2160/// and all, because `Type::from_parser_type` hands the undivided name to
2161/// `ModuleName::qualify_name` rather than splitting a module half off it — so an
2162/// unresolved `Missing.Thing` written in `Test` arrives here as `Test.Missing.Thing`
2163/// and does not collapse onto the local `Test.Thing`.
2164pub(crate) fn canonical_type_to_typer_type(
2165 tpe: &canonical::Type,
2166 var_map: &mut HashMap<String, TypeVariable>,
2167 counter: &mut u32,
2168) -> Option<Type> {
2169 match tpe {
2170 canonical::Type::Variable(name) => {
2171 let tv = var_map.entry(name.as_str().to_string()).or_insert_with(|| {
2172 *counter += 1;
2173 TypeVariable::flexible(*counter)
2174 });
2175 Some(Type::Variable(tv.clone()))
2176 }
2177 canonical::Type::Arrow(a, b) => {
2178 let a = canonical_type_to_typer_type(a, var_map, counter)?;
2179 let b = canonical_type_to_typer_type(b, var_map, counter)?;
2180 Some(Type::Fun {
2181 param_tpe: Box::new(a),
2182 return_tpe: Box::new(b),
2183 })
2184 }
2185 // `Tuple::try_map` keeps the arity attached to the value instead of
2186 // re-deriving it here, the same way the parser → canonical conversions
2187 // in `canonical/mod.rs` do.
2188 canonical::Type::Tuple(tuple) => {
2189 let elements = tuple
2190 .try_map(|elem| canonical_type_to_typer_type(elem, var_map, counter).ok_or(()))
2191 .ok()?;
2192 Some(Type::Tuple(elements))
2193 }
2194 canonical::Type::Unit => Some(Type::Unit),
2195 // Label for label: the canonical map is already the set the typer's is.
2196 canonical::Type::Record(fields) => {
2197 let fields = fields
2198 .iter()
2199 .map(|(label, field)| {
2200 let field = canonical_type_to_typer_type(field, var_map, counter)?;
2201 Some((label.clone(), field))
2202 })
2203 .collect::<Option<BTreeMap<_, _>>>()?;
2204 Some(Type::Record(fields))
2205 }
2206 canonical::Type::Type(name, args) => {
2207 if args.is_empty() {
2208 if let Some(literal) = scalar_literal(name) {
2209 return Some(Type::Literal(literal));
2210 }
2211 }
2212
2213 let converted: Option<Vec<Type>> = args
2214 .iter()
2215 .map(|a| canonical_type_to_typer_type(a, var_map, counter))
2216 .collect();
2217 Some(Type::Adt(name.clone(), converted?))
2218 }
2219 }
2220}
2221
2222/// `tpe`, with every variable `variables` names made rigid, and `variables` updated to
2223/// hold the rigid ones.
2224///
2225/// `tpe` and `variables` are what [`canonical_type_to_typer_type`] built for a type the
2226/// declaration being checked is quantified over: an annotation, an instance's head, the
2227/// member signature an instance's binding is held to. Each variable keeps its `id` and
2228/// takes the name it was written by and the `binder` it was written in, so a given built from
2229/// `variables` afterwards is on the variable the type holds, and `unify` will solve none of
2230/// them. A variable already rigid is left as it is.
2231fn make_rigid(tpe: Type, variables: &mut HashMap<String, TypeVariable>, binder: Binder) -> Type {
2232 let mut tpe = tpe;
2233 for (written, variable) in variables.iter_mut() {
2234 if variable.is_rigid() {
2235 continue;
2236 }
2237 let rigid = variable
2238 .clone()
2239 .into_rigid(Name::new(written.clone()), binder);
2240 tpe = Substitution::substitute(tpe, variable, &Type::Variable(rigid.clone()));
2241 *variable = rigid;
2242 }
2243 tpe
2244}
2245
2246/// The literal type the typer gives a [scalar](super::scalars), if `name` is the
2247/// qualified name of one it has a literal type for.
2248///
2249/// Four of the five appear here. [`scalars::BOOL`] does not: it is a scalar *and* an
2250/// ordinary union, so `Bool` in an annotation takes the [`Type::Adt`] path every other
2251/// declaration takes and meets `True` and `False` there. [`bool_type`] is the same type,
2252/// built for the three `Bool`s no source spells.
2253fn scalar_literal(name: &QualName) -> Option<TypeLiteral> {
2254 const LITERALS: &[(scalars::Scalar, TypeLiteral)] = &[
2255 (scalars::INT, TypeLiteral::Int),
2256 (scalars::FLOAT, TypeLiteral::Float),
2257 (scalars::CHAR, TypeLiteral::Char),
2258 (scalars::STRING, TypeLiteral::String),
2259 ];
2260
2261 LITERALS
2262 .iter()
2263 .find(|(scalar, _)| scalar.declares(name))
2264 .map(|(_, literal)| literal.clone())
2265}
2266
2267/// The type of a `Bool`: the union [`scalars::BOOL`] names, with no arguments.
2268///
2269/// `Bool` is [a scalar and an ordinary union at
2270/// once](../../docs/spec/types.md#scalar-types) — the compiler knows its
2271/// representation and nothing about its structure — so this is the very type
2272/// `canonical_type_to_typer_type` produces for an annotation naming `Basics.Bool`, and
2273/// the type `Basics` registers `True` and `False` at.
2274///
2275/// An [`if` condition](../../docs/spec/expressions.md#if--then--else) needs a `Bool`
2276/// the source did not spell, and `translate_pattern` gives a `Basics.True` or
2277/// `Basics.False` pattern this type when it turns it into a test on its value. It
2278/// names `Basics.Bool` and nothing else, so a module declaring its own `type Bool`
2279/// does not satisfy an `if` ([`DEC-15`](../../docs/decisions/dec-15.md) decisions 1
2280/// and 5).
2281pub(super) fn bool_type() -> Type {
2282 Type::Adt(scalars::BOOL.qual_name(), vec![])
2283}
2284
2285/// Convert a canonical expression to a Term, keeping the position it was written at.
2286///
2287/// Returns None for constructs the inference engine doesn't yet handle (a `VarKernel`
2288/// reference), and for a constructor of a union neither this module nor an interface in
2289/// [`Translation`] declares.
2290///
2291/// Every arm attaches `expr.span` to the term it builds. That is the whole of what
2292/// `ERR-4` needed from this function: a constraint can only point at a
2293/// sub-expression if the term that produced it remembers where it came from.
2294///
2295/// # What is recorded here and nowhere else
2296///
2297/// This is the only moment at which a reference's *kind* is known. A local, a
2298/// top-level, an imported value and a constructor are four different things to emit,
2299/// and the spelling each leaves behind is bare for one of them and qualified for the
2300/// rest — so a backend handed only the string could not tell them apart
2301/// ([`DEC-18` decision
2302/// 1](../../docs/decisions/dec-18.md#1--the-backend-reads-a-typed-ir-and-the-typer-is-what-produces-it)).
2303/// Each becomes a [`Reference`] carrying both the lookup key inference uses and what
2304/// the name is. An application spine records the same way whether it is
2305/// [saturated](Saturation), which is a question about the spine and not about any one
2306/// `Apply` node.
2307fn canonical_expr_to_term(
2308 expr: &canonical::Expression,
2309 translation: &Translation,
2310 counter: &mut u32,
2311) -> Option<Term> {
2312 let kind = match &expr.kind {
2313 // Carried at the canonical AST's own width: [`Int` is 64
2314 // bits](../../docs/spec/evaluation-semantics.md#numbers), and a term is what
2315 // code is generated from, so narrowing here would emit a different number than
2316 // the one that was written.
2317 canonical::ExpressionKind::Int(i) => TermKind::Int(*i),
2318 canonical::ExpressionKind::Char(c) => TermKind::Char(*c),
2319 canonical::ExpressionKind::String(s) => TermKind::String(s.clone()),
2320 canonical::ExpressionKind::Float(f) => TermKind::Float(*f),
2321 canonical::ExpressionKind::VarLocal(name) => {
2322 TermKind::Identifier(Reference::local(name.as_str()))
2323 }
2324 canonical::ExpressionKind::VarTopLevel(qname) => TermKind::Identifier(Reference {
2325 name: environment_key(qname),
2326 kind: ReferenceKind::TopLevel(qname.clone()),
2327 }),
2328 // A value another module declares. Its type is the one its module's interface
2329 // declared, which `type_check` registers under this same qualified name.
2330 canonical::ExpressionKind::VarForeign(qname, package, _) => {
2331 TermKind::Identifier(Reference {
2332 name: environment_key(qname),
2333 kind: ReferenceKind::Foreign(
2334 qname.clone(),
2335 package.clone(),
2336 translation.foreign_arity(qname),
2337 ),
2338 })
2339 }
2340 // A constructor builds a tagged value rather than reading a binding, so it
2341 // carries its place in its declaration. That place comes from the union,
2342 // which is in `translation.constructors` whether this module declared it or
2343 // an imported interface did. The type the canonical node carries is not read:
2344 // the one `type_check` registers is built from the union's own variables.
2345 canonical::ExpressionKind::VarConstructor(qname, _) => {
2346 let ctor = translation.constructors.get(qname)?;
2347
2348 TermKind::Identifier(Reference {
2349 name: environment_key(qname),
2350 kind: ReferenceKind::Constructor(ctor.clone()),
2351 })
2352 }
2353 // The spine is walked as a whole rather than one node at a time, because
2354 // whether a call is saturated is a fact about the callee and the number of
2355 // arguments reaching it. Each node keeps its own canonical span, so a type
2356 // error still points where it did.
2357 canonical::ExpressionKind::Apply(_, _) => {
2358 let (callee, applications) = spine(expr);
2359 let arity = translation.callee_arity(callee);
2360
2361 let mut term = canonical_expr_to_term(callee, translation, counter)?;
2362
2363 for (supplied, application) in applications.iter().enumerate() {
2364 // `spine` collects `Apply` nodes and nothing else.
2365 let canonical::ExpressionKind::Apply(_, argument) = &application.kind else {
2366 return None;
2367 };
2368
2369 let argument = canonical_expr_to_term(argument, translation, counter)?;
2370 // The node that consumes the callee's last argument is the direct
2371 // call; everything before it is a partial application and everything
2372 // after it applies whatever that call returned.
2373 let saturation = match arity {
2374 Some(arity) if arity == supplied + 1 => Saturation::Saturated,
2375 _ => Saturation::Partial,
2376 };
2377
2378 term = Term {
2379 span: application.span,
2380 kind: TermKind::Apply {
2381 fun: Box::new(term),
2382 arg: Box::new(argument),
2383 saturation,
2384 },
2385 };
2386 }
2387
2388 return Some(term);
2389 }
2390 canonical::ExpressionKind::If(cond, t, f) => {
2391 let cond = canonical_expr_to_term(cond, translation, counter)?;
2392 let t = canonical_expr_to_term(t, translation, counter)?;
2393 let f = canonical_expr_to_term(f, translation, counter)?;
2394 TermKind::If {
2395 cond: Box::new(cond),
2396 true_branch: Box::new(t),
2397 false_branch: Box::new(f),
2398 }
2399 }
2400 canonical::ExpressionKind::Tuple(tuple) => {
2401 let elements = tuple
2402 .try_map(|elem| canonical_expr_to_term(elem, translation, counter).ok_or(()))
2403 .ok()?;
2404 TermKind::Tuple(elements)
2405 }
2406 canonical::ExpressionKind::Unit => TermKind::Unit,
2407 canonical::ExpressionKind::Case(scrutinee_expr, branches) => {
2408 let scrutinee = canonical_expr_to_term(scrutinee_expr, translation, counter)?;
2409 let term_branches: Vec<(TermPattern, Box<Term>)> = branches
2410 .iter()
2411 .map(|cb| {
2412 let pattern = translate_pattern(&cb.pattern, translation, counter)?;
2413 let body = canonical_expr_to_term(&cb.expression, translation, counter)?;
2414 Some((pattern, Box::new(body)))
2415 })
2416 .collect::<Option<Vec<_>>>()?;
2417 TermKind::Case {
2418 scrutinee: Box::new(scrutinee),
2419 branches: term_branches,
2420 form: CaseForm::Expression,
2421 }
2422 }
2423 // A name that did not resolve. Its error is canonicalization's, and the term
2424 // stands where the name was written so the rest of the body is still checked.
2425 canonical::ExpressionKind::Hole => TermKind::Hole,
2426 // The fields stay in the order they were written: only the record's type is a
2427 // set, and that is built from them by `constraint::collect`.
2428 canonical::ExpressionKind::Record(fields) => {
2429 TermKind::Record(translate_fields(fields, translation, counter)?)
2430 }
2431 canonical::ExpressionKind::Update(record, fields) => TermKind::Update {
2432 record: Box::new(canonical_expr_to_term(record, translation, counter)?),
2433 fields: translate_fields(fields, translation, counter)?,
2434 },
2435 canonical::ExpressionKind::Access(record, label, label_span) => TermKind::Access {
2436 record: Box::new(canonical_expr_to_term(record, translation, counter)?),
2437 label: label.clone(),
2438 label_span: *label_span,
2439 },
2440 canonical::ExpressionKind::Accessor(label, label_span) => TermKind::Accessor {
2441 label: label.clone(),
2442 label_span: *label_span,
2443 },
2444 // Not yet supported: VarKernel
2445 _ => return None,
2446 };
2447
2448 Some(Term {
2449 span: expr.span,
2450 kind,
2451 })
2452}
2453
2454/// The fields of a record or an update, in the order they were written, each with the
2455/// span of its label.
2456fn translate_fields(
2457 fields: &[canonical::Field],
2458 translation: &Translation,
2459 counter: &mut u32,
2460) -> Option<Vec<Field<Term>>> {
2461 fields
2462 .iter()
2463 .map(|field| {
2464 Some(Field {
2465 label: field.label.clone(),
2466 label_span: field.label_span,
2467 value: canonical_expr_to_term(&field.value, translation, counter)?,
2468 })
2469 })
2470 .collect()
2471}
2472
2473/// An application spine: what is being applied, and the `Apply` nodes that apply it,
2474/// innermost first.
2475///
2476/// `f a b` is `Apply(Apply(f, a), b)` in the canonical AST, and one `Apply` node on its
2477/// own cannot say whether the call it is part of supplies everything `f` takes. This is
2478/// what turns the nesting back into a callee and a count. `applications[i]` supplies the
2479/// `i + 1`th argument, and the last of them is `expr` itself.
2480fn spine(expr: &canonical::Expression) -> (&canonical::Expression, Vec<&canonical::Expression>) {
2481 let mut applications = Vec::new();
2482 let mut callee = expr;
2483
2484 while let canonical::ExpressionKind::Apply(fun, _) = &callee.kind {
2485 applications.push(callee);
2486 callee = fun;
2487 }
2488
2489 applications.reverse();
2490
2491 (callee, applications)
2492}
2493
2494/// Translate a canonical pattern into a `TermPattern`. Returns `None` for a pattern the
2495/// term language does not model: a constructor that names no case of its declaration, or
2496/// a sub-pattern that is itself one of those.
2497///
2498/// The pattern keeps its own span, separate from the branch body's: a `case` branch
2499/// whose pattern does not match what is being matched on is about the pattern, and
2500/// the caret belongs there rather than under the expression in the `case … of` line.
2501fn translate_pattern(
2502 pattern: &canonical::Pattern,
2503 translation: &Translation,
2504 counter: &mut u32,
2505) -> Option<TermPattern> {
2506 let kind = match &pattern.kind {
2507 canonical::PatternKind::Anything => TermPatternKind::Anything,
2508 canonical::PatternKind::Variable(name) => {
2509 // The binding's actual type will be unified with the scrutinee type in annotate.
2510 TermPatternKind::Bind(name.as_str().to_string())
2511 }
2512 canonical::PatternKind::Int(value) => TermPatternKind::Literal {
2513 tpe: Type::Literal(TypeLiteral::Int),
2514 value: LiteralValue::Int(*value),
2515 },
2516 canonical::PatternKind::Char(value) => TermPatternKind::Literal {
2517 tpe: Type::Literal(TypeLiteral::Char),
2518 value: LiteralValue::Char(*value),
2519 },
2520 canonical::PatternKind::Float(value) => TermPatternKind::Literal {
2521 tpe: Type::Literal(TypeLiteral::Float),
2522 value: LiteralValue::Float(*value),
2523 },
2524 canonical::PatternKind::String(value) => TermPatternKind::Literal {
2525 tpe: Type::Literal(TypeLiteral::String),
2526 value: LiteralValue::String(value.clone()),
2527 },
2528 canonical::PatternKind::Unit => TermPatternKind::Unit,
2529 // `Basics`' own `True` and `False` are tested by value, as an `Int` or a
2530 // `Char` literal is, so a backend tests a `Bool` scrutinee by equality. The
2531 // type is the same one the constructor would have constrained the scrutinee
2532 // to. A module's own `type Bool = True | False` is not `Basics.Bool` and is
2533 // left alone.
2534 canonical::PatternKind::Constructor { ctor, args }
2535 if args.is_empty() && ctor.tpe == scalars::BOOL.qual_name() =>
2536 {
2537 let value = match ctor.name.as_str() {
2538 "True" => true,
2539 "False" => false,
2540 _ => return None,
2541 };
2542 TermPatternKind::Literal {
2543 tpe: bool_type(),
2544 value: LiteralValue::Bool(value),
2545 }
2546 }
2547 canonical::PatternKind::Constructor { ctor, args } => {
2548 // Look up the parent union to get its type variables. `ctor.tpe` names
2549 // the declaration the constructor builds, module included, and `unions`
2550 // is keyed the same way — so this finds the one declaration the
2551 // constructor belongs to, this module's or an imported one.
2552 let union_type = translation.unions.get(&ctor.tpe)?;
2553
2554 // Which case of that union this pattern matches. Unification needs only
2555 // the union; a decision tree and a WIT `variant` both need the case, and
2556 // the declaration is the only thing that can say where it sits.
2557 let index = union_type
2558 .variants
2559 .iter()
2560 .position(|variant| variant.name == ctor.name)?;
2561
2562 // Create fresh type vars for each ADT type parameter.
2563 let mut adt_var_map: HashMap<String, TypeVariable> = HashMap::new();
2564 for tv_name in &union_type.variables {
2565 *counter += 1;
2566 adt_var_map.insert(
2567 tv_name.as_str().to_string(),
2568 TypeVariable::flexible(*counter),
2569 );
2570 }
2571
2572 // Build the ADT result type args from the fresh vars.
2573 let adt_args: Vec<Type> = union_type
2574 .variables
2575 .iter()
2576 .map(|v| Type::Variable(adt_var_map[v.as_str()].clone()))
2577 .collect();
2578
2579 // Translate each constructor type parameter (reuses the same fresh vars).
2580 let param_types: Vec<Type> = ctor
2581 .type_parameters
2582 .iter()
2583 .filter_map(|t| canonical_type_to_typer_type(t, &mut adt_var_map, counter))
2584 .collect();
2585 if param_types.len() != ctor.type_parameters.len() {
2586 return None;
2587 }
2588
2589 // One sub-pattern per argument, so an argument's position is its place in
2590 // the list.
2591 let args = args
2592 .iter()
2593 .zip(param_types)
2594 .map(|(arg_pattern, param_type)| {
2595 translate_sub_pattern(arg_pattern, param_type, translation, counter)
2596 })
2597 .collect::<Option<Vec<_>>>()?;
2598
2599 TermPatternKind::Constructor {
2600 ctor: Constructor {
2601 union: ctor.tpe.clone(),
2602 name: ctor.name.clone(),
2603 index,
2604 arity: ctor.type_parameters.len(),
2605 },
2606 adt_args,
2607 args,
2608 }
2609 }
2610 // Each element gets a fresh type, and the matched value has to be the tuple of
2611 // them. An element is translated as a constructor's argument is (see
2612 // `translate_sub_pattern`).
2613 canonical::PatternKind::Tuple(elements) => {
2614 let elements = elements
2615 .try_map(|element| {
2616 *counter += 1;
2617 let tpe = Type::Variable(TypeVariable::flexible(*counter));
2618 translate_sub_pattern(element, tpe, translation, counter).ok_or(())
2619 })
2620 .ok()?;
2621
2622 TermPatternKind::Tuple { elements }
2623 }
2624 // A constructor that did not resolve: nothing says what type it builds or takes,
2625 // so each argument is at a fresh type, and translated as a resolved constructor's
2626 // argument is (see `translate_sub_pattern`).
2627 canonical::PatternKind::Hole(args) => {
2628 let args = args
2629 .iter()
2630 .map(|arg| {
2631 *counter += 1;
2632 let tpe = Type::Variable(TypeVariable::flexible(*counter));
2633 translate_sub_pattern(arg, tpe, translation, counter)
2634 })
2635 .collect::<Option<Vec<_>>>()?;
2636
2637 TermPatternKind::Hole { args }
2638 }
2639 // Each entry's field gets a fresh type, and its pattern is translated as a
2640 // constructor's argument is (see `translate_sub_pattern`). Nothing is built here
2641 // for the record itself: the pattern names a subset of its fields, so its record
2642 // type is whatever the matched value turns out to be, and each entry is read
2643 // against it once the declaration's equations are solved (`FieldConstraint`).
2644 canonical::PatternKind::Record(entries) => {
2645 let fields = entries
2646 .iter()
2647 .map(|entry| {
2648 *counter += 1;
2649 let tpe = Type::Variable(TypeVariable::flexible(*counter));
2650 Some(Field {
2651 label: entry.label.clone(),
2652 label_span: entry.label_span,
2653 value: translate_sub_pattern(&entry.pattern, tpe, translation, counter)?,
2654 })
2655 })
2656 .collect::<Option<Vec<_>>>()?;
2657
2658 TermPatternKind::Record { fields }
2659 }
2660 };
2661
2662 Some(TermPattern {
2663 span: pattern.span,
2664 kind,
2665 })
2666}
2667
2668/// A pattern written as a constructor's argument, a tuple's element or a record
2669/// pattern's entry, matched against a value of type `tpe`.
2670///
2671/// It is translated by [`translate_pattern`] like a pattern anywhere else, so any
2672/// pattern that translates at the top of a branch translates here too, at any depth, and
2673/// one that does not — a constructor of a union nobody declared, say — answers `None` here as it does there. A
2674/// refutable sub-pattern needs nothing of its own: `pattern_constraints` holds it to
2675/// `tpe` the way a branch's pattern is held to the scrutinee's type, and
2676/// `ir::decision_tree` tests it at its occurrence.
2677fn translate_sub_pattern(
2678 pattern: &canonical::Pattern,
2679 tpe: Type,
2680 translation: &Translation,
2681 counter: &mut u32,
2682) -> Option<SubPattern> {
2683 Some(SubPattern {
2684 tpe,
2685 pattern: translate_pattern(pattern, translation, counter)?,
2686 })
2687}
2688
2689/// A declaration's type annotation, and where it was written.
2690///
2691/// The span is the annotation's alone — `answer : Int`, not the declaration it
2692/// heads — because it is drawn as the secondary label of a mismatch in the body, and
2693/// a span covering the body too would underline the thing it is meant to contrast
2694/// with.
2695///
2696/// An instance's binding has no annotation of its own: the member's signature at the
2697/// instance's type stands in for one, and the head line of the instance for its span.
2698///
2699/// The variables of `tpe` are rigid ([`make_rigid`]) for a declaration's annotation, for an
2700/// instance's binding, head and member signature alike, and for a derivation's binding, whose
2701/// type is the chapter's role type over the derivation's answer type: the variables there
2702/// are the member signature's own.
2703struct Annotation {
2704 tpe: Type,
2705 span: NodeSpan,
2706 /// The reason of the equation the annotation's type is one side of.
2707 reason: Reason,
2708 /// What the annotation requires of its variables — the `=>` in front of it, or the
2709 /// context of the instance — each a class and the variable of `tpe` it is on. These
2710 /// are *given* inside the declaration.
2711 context: Vec<(QualName, TypeVariable)>,
2712 /// The name the source wrote for each variable of `tpe`, sorted by name: what a
2713 /// message about a constraint writes the variable by.
2714 names: Vec<(TypeVariable, Name)>,
2715 /// The variables of `tpe` that `context` cannot be on: the ones a class member's
2716 /// signature binds besides the class's own, when `tpe` is an instance binding's. Empty
2717 /// for an annotation.
2718 member_variables: Vec<TypeVariable>,
2719 /// What a constraint missing from `context` would have to be written in.
2720 written: Written,
2721}
2722
2723/// Convert a canonical Value into a (Term, optional annotation) pair.
2724/// The body is wrapped in nested Fun nodes for each parameter — see
2725/// [`wrap_with_patterns`].
2726/// Returns None if any part of the value cannot be translated, its annotation included:
2727/// a body checked without the annotation it was written with would be checked against
2728/// less than the source says, and pass where the annotation should have failed it. No
2729/// annotation fails to translate today — [`canonical_type_to_typer_type`] reads every
2730/// canonical type — so it is the body alone that can make this `None`; the annotation's
2731/// `?` is kept for the type form that would not.
2732///
2733/// The annotation's variables come back rigid ([`make_rigid`]), and its context is on them.
2734fn value_to_term_and_annotation(
2735 value: &canonical::Value,
2736 translation: &Translation,
2737 counter: &mut u32,
2738) -> Option<(Term, Option<Annotation>)> {
2739 match value {
2740 canonical::Value::Value { patterns, body, .. } => {
2741 let body_term = canonical_expr_to_term(body, translation, counter)?;
2742 let term = wrap_with_patterns(patterns.iter(), body_term, translation, counter)?;
2743 Some((term, None))
2744 }
2745 canonical::Value::TypedValue {
2746 patterns,
2747 body,
2748 tpe,
2749 context,
2750 annotation_span,
2751 ..
2752 } => {
2753 let body_term = canonical_expr_to_term(body, translation, counter)?;
2754 let pattern_iter = patterns.iter().map(|(p, _)| p);
2755 let term = wrap_with_patterns(pattern_iter, body_term, translation, counter)?;
2756 let mut var_map = HashMap::new();
2757 let tpe = canonical_type_to_typer_type(tpe, &mut var_map, counter)?;
2758 let tpe = make_rigid(tpe, &mut var_map, Binder::Annotation);
2759 let given = context
2760 .iter()
2761 .filter_map(|constraint| {
2762 Some((
2763 constraint.class.clone(),
2764 var_map.get(constraint.variable.as_str())?.clone(),
2765 ))
2766 })
2767 .collect();
2768 let mut names: Vec<(TypeVariable, Name)> = var_map
2769 .iter()
2770 .map(|(name, variable)| (variable.clone(), Name::new(name.clone())))
2771 .collect();
2772 names.sort_by(|left, right| left.1.cmp(&right.1));
2773
2774 let annotation = Annotation {
2775 tpe,
2776 span: *annotation_span,
2777 reason: Reason::Annotation,
2778 context: given,
2779 names,
2780 member_variables: Vec::new(),
2781 written: Written::Annotation,
2782 };
2783 Some((term, Some(annotation)))
2784 }
2785 }
2786}
2787
2788/// Wrap a body Term in nested Fun nodes for each parameter, outermost first.
2789///
2790/// A `Fun` binds one name, so a parameter written as a variable or `_` is bound as it
2791/// is. A parameter written as any other pattern is bound under the name
2792/// [`pattern_parameter`] gives its position, and matched by a single-branch
2793/// [`CaseForm::Parameter`] `Case` on that name: `first (x, _) = x` is translated as
2794/// `first $0 = case $0 of (x, _) -> x` would be. The pattern goes through
2795/// [`translate_pattern`], the same translation a `case` branch's gets, so a parameter
2796/// admits exactly the patterns a branch does. Returns `None` when it does not.
2797///
2798/// Every `Fun` is outside every `Case`. That keeps the first `arity` nodes of the term
2799/// the declaration's parameters and nothing else, which is what `ir::build` reads them
2800/// off by. The `Case`s nest in parameter order, the first outermost, so a name two
2801/// patterned parameters both bind is the later one's in the body — which is how
2802/// canonicalization resolved it. A pattern's names also shadow a same-named parameter
2803/// written as a variable, whichever comes first — and when the pattern comes first,
2804/// that is the opposite of canonicalization, which lets the later parameter win:
2805/// `f (x, _) x = x` reads the pattern's `x` here and the plain parameter's there. Both
2806/// are a name bound twice in one clause, which the language rejects and the compiler
2807/// does not yet (`LANG-18`).
2808///
2809/// Each `Fun` spans its parameter through the body it wraps, so a function whose
2810/// declared shape does not match its definition is underlined from the parameter
2811/// that starts it rather than across the annotation as well. A `Case` built here spans
2812/// its pattern alone: it is what the source wrote in place of a plain parameter.
2813fn wrap_with_patterns<'a>(
2814 patterns: impl Iterator<Item = &'a canonical::Pattern>,
2815 body: Term,
2816 translation: &Translation,
2817 counter: &mut u32,
2818) -> Option<Term> {
2819 let body_span = body.span;
2820 let mut params: Vec<(String, NodeSpan)> = vec![];
2821 let mut matched: Vec<(String, TermPattern)> = vec![];
2822
2823 for (position, pattern) in patterns.enumerate() {
2824 match &pattern.kind {
2825 canonical::PatternKind::Variable(name) => {
2826 params.push((name.as_str().to_string(), pattern.span))
2827 }
2828 canonical::PatternKind::Anything => params.push(("_".to_string(), pattern.span)),
2829 _ => {
2830 let name = pattern_parameter(position);
2831 let translated = translate_pattern(pattern, translation, counter)?;
2832 params.push((name.clone(), pattern.span));
2833 matched.push((name, translated));
2834 }
2835 }
2836 }
2837
2838 let body = matched
2839 .into_iter()
2840 .rev()
2841 .fold(body, |acc, (name, pattern)| {
2842 let span = pattern.span;
2843 Term {
2844 span,
2845 kind: TermKind::Case {
2846 scrutinee: Box::new(Term {
2847 span,
2848 kind: TermKind::Identifier(Reference::local(name)),
2849 }),
2850 branches: vec![(pattern, Box::new(acc))],
2851 form: CaseForm::Parameter,
2852 },
2853 }
2854 });
2855
2856 let term = params
2857 .into_iter()
2858 .rev()
2859 .fold(body, |acc, (param, span)| Term {
2860 span: span.merge(body_span),
2861 kind: TermKind::Fun {
2862 param,
2863 body: Box::new(acc),
2864 },
2865 });
2866
2867 Some(term)
2868}
2869
2870// The term language inference runs on is [`crate::ir`], and it is no longer
2871// only inference's. Every node carries the [`NodeSpan`] of the canonical node it was
2872// built from, so an error found down here can say where in the user's source it
2873// happened (`ERR-4`), and each carries what a backend reads off it — the kind of name a
2874// reference is, a call's saturation, a constructor's place in its declaration — because
2875// the translation below is the only place those are known. Inference reads none of
2876// them.
2877
2878mod annotate;
2879mod classes;
2880mod constraint;
2881mod unifier;
2882
2883pub(crate) use classes::{head_of, instance_head_type};
2884
2885/// A type variable: a placeholder `unify` may solve to a type, or a **rigid** one, which it
2886/// may not.
2887///
2888/// A *flexible* variable is the inference variable of an expression, and the variable of a
2889/// declared type a use instantiates. A *rigid* variable is one the declaration being
2890/// checked is universally quantified over: the variables its annotation wrote, or the
2891/// variables of an instance's head and of the member signature its bindings are held to
2892/// (`make_rigid` makes them). It stands for every type a caller may choose, so it is
2893/// equal to itself and to nothing else, and `unifier::unify` raises
2894/// [`ErrorKind::RigidVariable`] where a body would need it to be anything more specific.
2895///
2896/// A rigid variable is a flexible one's `id` with the name the source wrote it by, which is
2897/// what a message writes it as. The `id` is what tells two variables apart: two rigid
2898/// variables may be written alike, as an instance's head and the member signature its
2899/// binding is held to each write their own.
2900///
2901/// A rigid variable belongs to the declaration whose body is checked: the types of the term
2902/// that comes back hold it, and nothing the environment holds for another declaration does.
2903/// What the environment holds for a use, a `Scheme`, is over flexible variables, which each
2904/// use instantiates fresh.
2905// TODO Copy ?
2906#[derive(Clone, Hash, PartialEq, Eq)]
2907pub struct TypeVariable {
2908 id: u32,
2909 /// The name the source wrote this variable by and what it wrote it in, when it is rigid.
2910 rigid: Option<(Name, Binder)>,
2911}
2912
2913/// What a rigid variable was written in: the three kinds of declared type a body is held to.
2914#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
2915pub enum Binder {
2916 /// A declaration's annotation, or the answer type of a derivation's binding.
2917 Annotation,
2918 /// An instance's head.
2919 InstanceHead,
2920 /// The signature of a class member, for the variables it binds beyond the class's own:
2921 /// the signature an instance's binding is held to.
2922 MemberSignature,
2923}
2924
2925impl Binder {
2926 /// `of` this binder, as a message writes whose a variable is.
2927 fn of_phrase(self) -> &'static str {
2928 match self {
2929 Binder::Annotation => "the annotation",
2930 Binder::InstanceHead => "the instance head",
2931 Binder::MemberSignature => "the member's signature",
2932 }
2933 }
2934
2935 /// What a message calls this binder's variable when it says which of two alike it means.
2936 fn possessive(self) -> &'static str {
2937 match self {
2938 Binder::Annotation => "the annotation's",
2939 Binder::InstanceHead => "the instance head's",
2940 Binder::MemberSignature => "the member signature's",
2941 }
2942 }
2943}
2944
2945impl TypeVariable {
2946 /// The flexible variable numbered `id`.
2947 fn flexible(id: u32) -> TypeVariable {
2948 TypeVariable { id, rigid: None }
2949 }
2950
2951 /// This variable made rigid under `name`: same `id`, so it is the variable the
2952 /// annotation's type was translated with, now one `unify` will not solve.
2953 fn into_rigid(self, name: Name, binder: Binder) -> TypeVariable {
2954 TypeVariable {
2955 id: self.id,
2956 rigid: Some((name, binder)),
2957 }
2958 }
2959
2960 /// What this variable was written in, when it is rigid.
2961 fn binder(&self) -> Option<Binder> {
2962 self.rigid.as_ref().map(|(_, binder)| *binder)
2963 }
2964
2965 /// Whether `unify` may not solve this variable to another type.
2966 fn is_rigid(&self) -> bool {
2967 self.rigid.is_some()
2968 }
2969
2970 /// How a message writes this variable when no name has been given for it: the name the
2971 /// source wrote, for a rigid one, and `t3` for a flexible one, as [`Type`]'s
2972 /// `Display` does.
2973 fn spelling(&self) -> String {
2974 match &self.rigid {
2975 Some((name, _)) => name.to_string(),
2976 None => format!("t{}", self.id),
2977 }
2978 }
2979}
2980
2981impl std::fmt::Debug for TypeVariable {
2982 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2983 match &self.rigid {
2984 None => write!(f, "TypeVariable#{}", self.id),
2985 Some((name, _)) => write!(f, "TypeVariable#{}(rigid {})", self.id, name),
2986 }
2987 }
2988}
2989
2990/// The type of an [opaque scalar](../../docs/spec/types.md#scalar-types): a type
2991/// nothing in the language builds or inspects, whose values arrive as literals.
2992///
2993/// `Bool` is not one of them: it is a scalar *and* an ordinary union, so its
2994/// type is a [`Type::Adt`] like any other union's, built by this module's `bool_type`.
2995#[derive(Debug, Clone, Hash, PartialEq, Eq)]
2996pub enum TypeLiteral {
2997 Int,
2998 Char,
2999 Float,
3000 String,
3001}
3002
3003#[derive(Clone, Hash, PartialEq, Eq)]
3004pub enum Type {
3005 Literal(TypeLiteral),
3006 Variable(TypeVariable),
3007 Fun {
3008 param_tpe: Box<Type>,
3009 return_tpe: Box<Type>,
3010 },
3011 Tuple(Tuple<Type>),
3012 /// [The unit type](../../docs/spec/types.md#the-unit-type), `()`, whose one
3013 /// value is also written `()`.
3014 ///
3015 /// A variant of its own, the way [`Type::Tuple`] is, rather than a [`Type::Adt`]
3016 /// known by the qualified name of a declaration the way `Bool` is: nothing
3017 /// declares `()`, it is a form of type expression and never a name, so there is
3018 /// no declaration to name and no same-spelled type it has to be told apart from.
3019 /// See `canonical::Type::Unit`.
3020 Unit,
3021 /// A named algebraic data type, e.g. `Maybe Int` declared in `Maybe` →
3022 /// `Adt(Maybe.Maybe, [Literal(Int)])`.
3023 ///
3024 /// The name is the declaring package's and module's, in full, because that is the
3025 /// identity of the type: `Widget.Size` and `Gadget.Size` are two types and a value
3026 /// of one is never a value of the other, and so are the `Size.Size` of two
3027 /// packages. The unifier's equality on this name is the only thing keeping them
3028 /// apart, so narrowing it to the spelling — which is what the typer used to carry —
3029 /// made every same-named declaration one type (`BUG-35`).
3030 /// [`Display`](std::fmt::Display) still writes the unqualified half, since that is
3031 /// how a module's source spells its own types.
3032 Adt(QualName, Vec<Type>),
3033 /// A [record type](../../docs/spec/records.md#a-record-type-is-a-set-of-fields): each
3034 /// label, and the type of the field it names.
3035 ///
3036 /// A map, for the reason `canonical::Type::Record` is one: a record type is a set of
3037 /// fields, so `{ x : Int, y : Int }` and `{ y : Int, x : Int }` are one value here and
3038 /// nothing downstream can tell the two spellings apart. The map is ordered by label,
3039 /// which is the order [`Display`](std::fmt::Display) writes the fields in.
3040 ///
3041 /// # How two record types unify
3042 ///
3043 /// They unify when they carry **the same set of labels** and each label's two field
3044 /// types unify; see `unify_one_constraint`. There is no row variable, and nothing
3045 /// ever adds a field to a record type: [records are
3046 /// closed](../../docs/spec/records.md#records-are-closed), so a variable only ever
3047 /// stands for a whole type, a record type included. Two record types with different
3048 /// label sets are a plain [`ErrorKind::UnificationFailed`], and its diagnostic names
3049 /// the labels each side has that the other lacks (see [`Error`]'s `notes`).
3050 ///
3051 /// Every walk over a type — substitution, the occurs check, instantiation, the zonk,
3052 /// and both renderings — goes into each field's type as it goes into a tuple's
3053 /// elements, and nothing else about a record is special to any of them.
3054 ///
3055 /// What does *not* produce one is a use of a record: an access, an update or an
3056 /// accessor says of a type only that it has some label, and is read against a record
3057 /// type something else supplied — see `FieldConstraint`.
3058 Record(BTreeMap<Name, Type>),
3059}
3060
3061/// How the name of a [`Type::Adt`] is written out.
3062///
3063/// A type is normally quoted the way the source spells it, which for a union is its
3064/// bare name. That is ambiguous exactly when one message names two declarations that
3065/// share a spelling, and [`ErrorKind::message`] switches to the qualified form there.
3066#[derive(Debug, Clone, Copy)]
3067enum AdtNames<'a> {
3068 /// `Size`.
3069 Unqualified,
3070 /// `Widget.Size`, or `AcmeWidgets.Size.Size`: the union's module as the checked
3071 /// package spells it, then its own name — see [`Spellings`].
3072 Qualified(&'a Spellings),
3073}
3074
3075impl AdtNames<'_> {
3076 /// Whether the types a single message is about have to be written qualified for
3077 /// that message to distinguish the declarations it names.
3078 ///
3079 /// The question is not whether the *types* are spelled alike — `A.Size` against
3080 /// `Lib.Size A.Size` renders as `Size` against `Size Size`, which differs as
3081 /// text while still using one word for three declarations. It is whether any two
3082 /// of the unions named anywhere in those types are different declarations with
3083 /// the same bare name; if so every union in the sentence is qualified, since
3084 /// qualifying only the colliding pair would read as if the rest had no module.
3085 /// Two declarations may share their module's name too, when two packages each
3086 /// hold one, and they are still two: a [`QualName`] carries its package.
3087 fn collide<'t>(types: impl IntoIterator<Item = &'t Type>) -> bool {
3088 let mut names: Vec<&QualName> = Vec::new();
3089
3090 for tpe in types {
3091 tpe.collect_adt_names(&mut names);
3092 }
3093
3094 names.iter().enumerate().any(|(i, name)| {
3095 names[i + 1..]
3096 .iter()
3097 .any(|other| *other != *name && other.unqualified_name() == name.unqualified_name())
3098 })
3099 }
3100}
3101
3102/// How the package being checked spells each module in reach: the key `compile_package`
3103/// stores that module's [`Interface`] under in the map it hands [`type_check`], and the
3104/// module under check's own name.
3105///
3106/// A qualified message writes a union by this spelling rather than by its declaring
3107/// module's own name, because the two differ for a wrapped dependency — and they have to
3108/// differ in the message whenever two packages each hold a module of the same name.
3109/// `AcmeWidgets.Size.Size` against `Size.Size` tells the two unions apart, and is what
3110/// the checked package's own source writes; `Size.Size` against `Size.Size` would not,
3111/// and the package name — `acme-widgets` — is a spelling no Zelkova source contains.
3112#[derive(Debug, Clone, Default)]
3113struct Spellings(HashMap<ModuleName, Name>);
3114
3115impl Spellings {
3116 /// The spellings of every module `interfaces` holds, plus `module`'s own.
3117 ///
3118 /// A module reachable by two spellings is written by the first in alphabetical
3119 /// order, so the message does not change between runs.
3120 fn of(module: &Module, interfaces: &HashMap<Name, Interface>) -> Spellings {
3121 let mut spellings: HashMap<ModuleName, Name> = HashMap::new();
3122
3123 for (spelling, interface) in interfaces {
3124 spellings
3125 .entry(interface.module_name.clone())
3126 .and_modify(|kept| {
3127 if spelling.as_str() < kept.as_str() {
3128 *kept = spelling.clone();
3129 }
3130 })
3131 .or_insert_with(|| spelling.clone());
3132 }
3133
3134 spellings.insert(module.name.clone(), module.name.name().clone());
3135
3136 Spellings(spellings)
3137 }
3138
3139 /// `name` as the checked package writes it: its module's spelling, then its own
3140 /// name. A module with no spelling here — one the checked package cannot import,
3141 /// whose union reached it through another module's signature — is written by its
3142 /// own name.
3143 fn spell(&self, name: &QualName) -> String {
3144 let module = ModuleName::new(name.package().clone(), name.module_name());
3145
3146 match self.0.get(&module) {
3147 Some(spelling) => format!("{}.{}", spelling, name.unqualified_name()),
3148 None => name.to_name().to_string(),
3149 }
3150 }
3151}
3152
3153/// A [`Type`] written with every union named by its module, as the checked package
3154/// spells it.
3155///
3156/// The counterpart of `Type`'s own [`Display`](std::fmt::Display), which writes the
3157/// unqualified half.
3158struct Qualified<'a>(&'a Type, &'a Spellings);
3159
3160impl std::fmt::Display for Qualified<'_> {
3161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3162 self.0.write(f, AdtNames::Qualified(self.1), None)
3163 }
3164}
3165
3166impl std::fmt::Debug for Type {
3167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3168 match self {
3169 Type::Literal(lit) => write!(f, "Lit({:?})", lit),
3170 Type::Variable(TypeVariable { id, rigid: None }) => write!(f, "Var(#{})", id),
3171 Type::Variable(TypeVariable {
3172 id,
3173 rigid: Some((name, _)),
3174 }) => write!(f, "Rigid({}#{})", name, id),
3175 Type::Fun {
3176 param_tpe,
3177 return_tpe,
3178 } => write!(f, "Fun({:?} -> {:?})", param_tpe, return_tpe),
3179 Type::Tuple(Tuple::Two(a, b)) => write!(f, "({:?}, {:?})", a, b),
3180 Type::Tuple(Tuple::Three(a, b, c)) => write!(f, "({:?}, {:?}, {:?})", a, b, c),
3181 Type::Unit => write!(f, "()"),
3182 Type::Adt(name, args) if args.is_empty() => write!(f, "{}", name.to_name()),
3183 Type::Adt(name, args) => write!(f, "{}({:?})", name.to_name(), args),
3184 Type::Record(fields) => {
3185 let fields: Vec<String> = fields
3186 .iter()
3187 .map(|(label, tpe)| format!("{}: {:?}", label.as_str(), tpe))
3188 .collect();
3189 write!(f, "{{{}}}", fields.join(", "))
3190 }
3191 }
3192 }
3193}
3194
3195/// Writes a type the way the source would spell it, so diagnostics can quote it.
3196///
3197/// This is deliberately not `Debug`: `Debug` prints the typer's own vocabulary
3198/// (`Lit(Int)`, `Var(#3)`), which is what you want at a breakpoint and never what
3199/// you want in a message the user reads. Inference variables have no source syntax
3200/// at all, so they are written `t3` — Elm's convention for an unsolved variable.
3201impl std::fmt::Display for Type {
3202 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3203 self.write(f, AdtNames::Unqualified, None)
3204 }
3205}
3206
3207impl Type {
3208 /// The type as a message writes one that has variables of no source's naming: each
3209 /// variable is a letter, `a` to `z` and on, in the order it first appears, where
3210 /// [`Display`](std::fmt::Display) writes the inference variable (`t10122`) that no
3211 /// source mentions. A type with no variable reads the same either way.
3212 pub(crate) fn written_with_letters(&self) -> String {
3213 let names: VariableNames = free_variables_in_order(self)
3214 .into_iter()
3215 .enumerate()
3216 .map(|(position, variable)| (variable, classes::letter(position)))
3217 .collect();
3218 WithNames(self, &names).to_string()
3219 }
3220
3221 /// Every union named anywhere in this type, outermost first, appended to `out`.
3222 ///
3223 /// A union's arguments are types in their own right and may name unions of their
3224 /// own, so this recurses rather than reading the head alone. [`AdtNames::collide`]
3225 /// is what it exists for: deciding how to write a type means looking at every
3226 /// name the rendering will contain, not only the one at the top.
3227 fn collect_adt_names<'a>(&'a self, out: &mut Vec<&'a QualName>) {
3228 match self {
3229 Type::Literal(_) | Type::Variable(_) | Type::Unit => {}
3230 Type::Fun {
3231 param_tpe,
3232 return_tpe,
3233 } => {
3234 param_tpe.collect_adt_names(out);
3235 return_tpe.collect_adt_names(out);
3236 }
3237 Type::Tuple(Tuple::Two(a, b)) => {
3238 a.collect_adt_names(out);
3239 b.collect_adt_names(out);
3240 }
3241 Type::Tuple(Tuple::Three(a, b, c)) => {
3242 a.collect_adt_names(out);
3243 b.collect_adt_names(out);
3244 c.collect_adt_names(out);
3245 }
3246 Type::Adt(name, args) => {
3247 out.push(name);
3248 for arg in args {
3249 arg.collect_adt_names(out);
3250 }
3251 }
3252 Type::Record(fields) => {
3253 for tpe in fields.values() {
3254 tpe.collect_adt_names(out);
3255 }
3256 }
3257 }
3258 }
3259
3260 /// The body of every rendering: the same text each time, except for how a union is
3261 /// named and how a variable is. See [`AdtNames`], and [`Display`](std::fmt::Display)
3262 /// for why unions are normally written bare.
3263 ///
3264 /// A variable is `t3` unless `variables` has a name for it, which is how a message
3265 /// writes the variables of an annotation the way the source did.
3266 fn write(
3267 &self,
3268 f: &mut std::fmt::Formatter<'_>,
3269 names: AdtNames,
3270 variables: Option<&VariableNames>,
3271 ) -> std::fmt::Result {
3272 /// The same, wrapped in parentheses.
3273 fn parenthesised(
3274 tpe: &Type,
3275 f: &mut std::fmt::Formatter<'_>,
3276 names: AdtNames,
3277 variables: Option<&VariableNames>,
3278 ) -> std::fmt::Result {
3279 write!(f, "(")?;
3280 tpe.write(f, names, variables)?;
3281 write!(f, ")")
3282 }
3283
3284 match self {
3285 Type::Literal(TypeLiteral::Int) => write!(f, "Int"),
3286 Type::Literal(TypeLiteral::Char) => write!(f, "Char"),
3287 Type::Literal(TypeLiteral::Float) => write!(f, "Float"),
3288 Type::Literal(TypeLiteral::String) => write!(f, "String"),
3289 Type::Variable(variable) => match variables.and_then(|names| names.get(variable)) {
3290 Some(name) => write!(f, "{}", name),
3291 None => write!(f, "{}", variable.spelling()),
3292 },
3293 // The parameter of a function type is parenthesised when it is itself a
3294 // function, because `->` is right-associative: `(a -> b) -> c` and
3295 // `a -> b -> c` are different types.
3296 Type::Fun {
3297 param_tpe,
3298 return_tpe,
3299 } => {
3300 match **param_tpe {
3301 Type::Fun { .. } => parenthesised(param_tpe, f, names, variables)?,
3302 _ => param_tpe.write(f, names, variables)?,
3303 }
3304 write!(f, " -> ")?;
3305 return_tpe.write(f, names, variables)
3306 }
3307 Type::Tuple(Tuple::Two(a, b)) => {
3308 write!(f, "( ")?;
3309 a.write(f, names, variables)?;
3310 write!(f, ", ")?;
3311 b.write(f, names, variables)?;
3312 write!(f, " )")
3313 }
3314 Type::Tuple(Tuple::Three(a, b, c)) => {
3315 write!(f, "( ")?;
3316 a.write(f, names, variables)?;
3317 write!(f, ", ")?;
3318 b.write(f, names, variables)?;
3319 write!(f, ", ")?;
3320 c.write(f, names, variables)?;
3321 write!(f, " )")
3322 }
3323 Type::Unit => write!(f, "()"),
3324 Type::Adt(name, args) => {
3325 match names {
3326 AdtNames::Unqualified => write!(f, "{}", name.unqualified_name())?,
3327 AdtNames::Qualified(spellings) => write!(f, "{}", spellings.spell(name))?,
3328 }
3329 for arg in args {
3330 // Same reason as above: an argument that is itself applied or a
3331 // function needs parentheses to stay the same type when re-read.
3332 write!(f, " ")?;
3333 match arg {
3334 Type::Adt(_, inner) if !inner.is_empty() => {
3335 parenthesised(arg, f, names, variables)?
3336 }
3337 Type::Fun { .. } => parenthesised(arg, f, names, variables)?,
3338 _ => arg.write(f, names, variables)?,
3339 }
3340 }
3341 Ok(())
3342 }
3343 // The spelling [Records](../../docs/spec/records.md#the-type) uses, the
3344 // fields in label order. The braces delimit it, so no position needs it
3345 // parenthesised, and a field's type is written as it is anywhere else.
3346 Type::Record(fields) => {
3347 write!(f, "{{ ")?;
3348 for (position, (label, tpe)) in fields.iter().enumerate() {
3349 if position > 0 {
3350 write!(f, ", ")?;
3351 }
3352 write!(f, "{} : ", label.as_str())?;
3353 tpe.write(f, names, variables)?;
3354 }
3355 write!(f, " }}")
3356 }
3357 }
3358 }
3359}
3360
3361/// Two types that have to match, and why.
3362///
3363/// # What the two sides mean
3364///
3365/// Unification treats them symmetrically; the order is a rendering convention, and
3366/// the only thing that reads it is the headline — *cannot match `left` with `right`*.
3367/// `collect` therefore writes the declared or expected side first where the source
3368/// has one (an annotation's type, a pattern's type) and the inferred side second, so
3369/// the sentence comes out in the order a reader expects.
3370///
3371/// What the sides are emphatically *not* is a way to tell which type belongs to the
3372/// text at `origin.span`. By the time a constraint fails, `unify` has substituted
3373/// other constraints' solutions into both sides, and may have decomposed it into a
3374/// component of the types the source mentioned. That is why the labels name the
3375/// [`Reason`] and leave the types to the headline — see [`Reason::describes`].
3376///
3377/// # Why these are held in a `Vec` and not a `HashSet`
3378///
3379/// They used to be a `HashSet<Constraint>`, back when a constraint was a bare pair of
3380/// types. An origin makes that collection wrong twice over. Deduplication now
3381/// discards *provenance*: two constraints with equal types but different origins are
3382/// one entry, and which origin survives is whichever was inserted first. And the
3383/// order a `HashSet` yields is unspecified, so which constraint `unify` reaches first
3384/// — and therefore which one is reported when several are unsatisfiable — would vary
3385/// between runs of the same compiler on the same file.
3386///
3387/// A `Vec` fixes both, and buys a third thing: source order. The annotation is
3388/// pushed first, so its type is substituted into the body's constraints before they
3389/// are solved, which is what lets a mismatch deep in the body say that `Int` came
3390/// from the annotation. The cost is that duplicate constraints are no longer
3391/// collapsed, which is a few more `unify` steps on terms that repeat a type.
3392#[derive(Debug, Clone, PartialEq)]
3393struct Constraint {
3394 left: Type,
3395 right: Type,
3396 origin: Origin,
3397}
3398
3399impl Constraint {
3400 fn new(left: Type, right: Type, reason: Reason, span: NodeSpan) -> Constraint {
3401 Constraint {
3402 left,
3403 right,
3404 origin: Origin::new(reason, span),
3405 }
3406 }
3407
3408 /// A constraint between two components of this one — the parameters of two
3409 /// function types being matched, say — which is about the same source text and
3410 /// was required for the same reason.
3411 ///
3412 /// The origin is inherited whole, side provenance included: if a substitution
3413 /// rewrote the left type, it rewrote whatever the left type decomposes into. That
3414 /// is an over-approximation — a substitution that reached only the return half of
3415 /// an arrow is credited with the parameter half too — but it errs towards naming
3416 /// a constraint that did carry a type in, which is the direction that keeps a
3417 /// caret on the source rather than on the compiler's working.
3418 fn component(&self, left: Type, right: Type) -> Constraint {
3419 Constraint {
3420 left,
3421 right,
3422 origin: self.origin.clone(),
3423 }
3424 }
3425}
3426
3427/// Which use of a record wrote a `FieldConstraint`. It decides what the constraint's
3428/// errors say and which text their carets are under; nothing about how the constraint
3429/// is solved depends on it.
3430#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3431pub enum RecordUse {
3432 /// `record.label`.
3433 Access,
3434 /// `.label`, applied or not.
3435 Accessor,
3436 /// One field of `{ record | label = value }`.
3437 Update,
3438 /// One entry of a record pattern, `{ label = pattern }` or `{ label }`.
3439 Pattern,
3440}
3441
3442/// What could supply the record type an [`ErrorKind::RecordTypeUnknown`] is missing —
3443/// which is what its note tells the reader to do about it. `unifier::unknown` decides it.
3444///
3445/// "Part of the declaration's type" means a variable of the declaration's solved type
3446/// — a parameter's, the result's, or inside either — or the field type of another use
3447/// whose record type is one: an annotation, unified with that type, would solve the
3448/// variable, and reading the use would solve the next.
3449#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3450pub enum Supplier {
3451 /// The declaration has no annotation, and the record type is part of its type: an
3452 /// annotation writing a record type there would supply it.
3453 Annotation,
3454 /// The record type is part of the declaration's type, and the declaration's
3455 /// annotation writes a type variable there — `f : a -> Int` with body `r.x` — or
3456 /// around it.
3457 AnnotationVariable,
3458 /// The record type is not part of the declaration's type — `.x` passed where any
3459 /// value is taken, as in `first n .x` — so no annotation on the declaration could
3460 /// supply it, and only its body can.
3461 Body,
3462}
3463
3464/// A type said to be a record holding `label`, with that field at `field`: what a field
3465/// access, an update, an accessor and each entry of a record pattern say about the record
3466/// they use.
3467///
3468/// # Why it is not a [`Constraint`]
3469///
3470/// `person.name` says of `person`'s type only that it has a `name`. That is not an
3471/// equation between two types this unifier can write: a record type names every field it
3472/// has ([records are closed](../../docs/spec/records.md#records-are-closed)), and there is
3473/// no row variable to stand for the fields `person.name` does not mention. Solving it
3474/// would mean inventing a record type out of the labels the declaration happens to touch,
3475/// which is exactly what [the language rules
3476/// out](../../docs/spec/records.md#a-use-does-not-decide-a-records-type): `nameOf person =
3477/// person.name` would take a record with one field. So a field constraint is never an
3478/// equation while its record type is unknown, and **nothing here ever solves a variable
3479/// standing for a record type**. The type has to come from somewhere else in the
3480/// declaration — its annotation, a record expression, a function of known type, a
3481/// constructor's argument — and the constraint only reads it.
3482///
3483/// # When it is read
3484///
3485/// After [`unifier::unify`] has solved every ordinary constraint of the declaration, by
3486/// `unifier::read_fields`. What supplies the record type may be written after the form
3487/// as well as before it, so a field constraint cannot be decided at the point
3488/// `constraint::collect` meets it; with the whole declaration solved, it can. Then, with
3489/// the substitution applied to `record`:
3490///
3491/// - **A record type holding `label`**: the constraint becomes the ordinary equation
3492/// between that field's type and `field`, solved at once and merged into the
3493/// substitution. A mismatch there is an [`ErrorKind::UnificationFailed`] with the
3494/// caret at `field_span` and the constraint's own `reason`.
3495/// - **A record type without it**: [`ErrorKind::MissingField`], at `label_span`. For an
3496/// update that is the update that would add a field.
3497/// - **Another type that is not a variable**: [`ErrorKind::NotARecord`], at
3498/// `label_span`. Each of these two carries what brought the record type in — the
3499/// probe's origin's cause for its left side — for a secondary label, as a mismatch's
3500/// explanation is.
3501/// - **Still a variable**: not decided yet. Reading another field constraint may solve
3502/// it: in `r.a.b` the record type of `.b` is the field type `.a` reads, and in `(.a
3503/// r).b` it is the accessor's result. So the constraints are read in passes, in the
3504/// order they were collected — which is the order their labels were written — each
3505/// pass seeing what the ones before it solved. A pass that decides none of the
3506/// constraints left is the end: nothing will ever supply their record types, and one
3507/// of them is [`ErrorKind::RecordTypeUnknown`], with the caret on the whole form —
3508/// unless a name that did not resolve, a hole, explains every one of them, its own
3509/// error standing already. `unifier::unknown` says which one and when a hole explains
3510/// it. Every pass decides at least one constraint or is the last, so the passes stop.
3511///
3512/// A record type only becomes *more* known as the passes go, never less, so whether a
3513/// declaration's field constraints are all satisfied does not depend on the order they
3514/// are read in. Which of several unknown ones is reported does not depend on it either
3515/// as long as one is the root the others wait on — `r.a` in an unannotated `r.a.b` or
3516/// `.b r.a` — and otherwise the order picks it, the same on every run. Only that one is
3517/// reported, as only a declaration's first failed equation is.
3518///
3519/// # Why there is nothing to generalise past
3520///
3521/// A declaration is put in the environment other declarations are checked against by
3522/// its annotation alone, and one with no annotation is not put there at all
3523/// ([`Solved::UnboundName`]). So a field constraint is always read inside the one
3524/// declaration that wrote it, and a use of that declaration from another one never
3525/// supplies its record type — which is the rule as
3526/// [Records](../../docs/spec/records.md#a-use-does-not-decide-a-records-type) states it.
3527/// A type variable an annotation writes, `get : { x : a } -> a`, is a variable inside a
3528/// record type and not a record type's variable, so `r.x` reads it; one written for the
3529/// record itself, `f : a -> Int` with body `r.x`, supplies no record type and is
3530/// [`ErrorKind::RecordTypeUnknown`].
3531///
3532/// That rests on there being no generalisation step. One that generalised a type still
3533/// carrying a waiting field constraint — a `let`-bound `get r = r.x` used as `get { x =
3534/// 1 }`, once [`LANG-33`](../../docs/tickets/lang-33.md) brings `let` — would copy the
3535/// constraint's variable at each use, and the constraint, waiting on the original, would
3536/// never be decided: it would fail safe, as a `RecordTypeUnknown`, but not by the rule.
3537/// So a generalisation step must read the field constraints first, or refuse to
3538/// generalise over a variable one of them is still waiting on.
3539///
3540/// # A record pattern
3541///
3542/// A record pattern names a subset of a record's fields and says of the type it is matched
3543/// against what an accessor says of its argument's, once per entry: it is the fourth
3544/// [`RecordUse`], one field constraint per entry, whose `record` is the type the pattern
3545/// is matched against — a `case`'s scrutinee, a parameter's, or the type of the position
3546/// it is written in inside another pattern — and whose `field` is the entry's own type,
3547/// the one its sub-pattern is held to and a name it binds is bound at. `form_span` is the
3548/// whole pattern, `label_span` the entry's label and `field_span` the entry's own pattern,
3549/// so a mismatch between that pattern and the field's declared type is blamed on the
3550/// sub-pattern. `constraint::pattern_constraints` writes them in the order the labels were
3551/// written at any depth: each entry just before the entries of a record pattern nested in
3552/// it, and those before the next entry, so `{ a = { b }, d }` gives `a`, `b`, `d`. The
3553/// field types of a pattern nested in an entry, `{ centre = { x } }`, are therefore read
3554/// in turn as `r.a.b`'s are.
3555///
3556/// That is the mechanism unchanged, but not quite nothing more than a variant:
3557/// `constraint::pattern_constraints`, which `constraint::collect` reaches through `walk`,
3558/// pushes onto the field list as well as onto the equations, the equation a decided entry
3559/// becomes carries a [`Reason`] of its own — one of three, by whether the entry's pattern
3560/// is a name, binds none or binds some, since that decides what a failure of it can mean
3561/// and so what its note says — and the argument types of a constructor pattern that did
3562/// not resolve count as holes, since that constructor's real type is what would have
3563/// supplied a record pattern written as one of its arguments.
3564///
3565/// The read comes after every equation, the branch body's included, so a name a record
3566/// pattern binds is solved by the body's use of it before the entry is read. A body that
3567/// uses `name` at another type than its field's is therefore reported at the entry, as a
3568/// mismatch of the field's type with the use's, and not at the body, as it would be under
3569/// a tuple pattern, whose equation comes first ([`ERR-20`](../../docs/tickets/err-20.md)).
3570/// Only the note, [`Reason::RecordPatternBinding`]'s, says that a use is what failed.
3571///
3572/// # What else is read late
3573///
3574/// A class obligation is the other kind of constraint the solver can only answer once
3575/// unification has run: a third list beside this one in `constraint::Constraints`, read
3576/// by `classes::discharge` after `unifier::read_fields` in `infer_annotated` — after,
3577/// because reading a field can solve the variable an instance is looked up by. Reading an
3578/// obligation adds nothing to the substitution: an instance's context is more obligations
3579/// and never an equation, so no obligation can decide a field constraint, and the order of
3580/// the two reads has one direction only.
3581#[derive(Debug, Clone)]
3582struct FieldConstraint {
3583 /// The type said to be a record. Usually still a variable when collected.
3584 record: Type,
3585 label: Name,
3586 /// The type the field is used at: the access's own type, an update's new value's, an
3587 /// accessor's result, or a record pattern's entry's.
3588 field: Type,
3589 form: RecordUse,
3590 /// The reason the equation this constraint becomes carries, once its record type is
3591 /// known: [`Reason::Access`], [`Reason::Accessor`] or [`Reason::UpdateField`] for the
3592 /// first three forms, and for a record pattern's entry one of the three record
3593 /// pattern reasons, chosen by what the entry's own pattern binds.
3594 reason: Reason,
3595 /// The whole form — the caret of [`ErrorKind::RecordTypeUnknown`].
3596 form_span: NodeSpan,
3597 /// The label for an access, an update and a record pattern's entry, and the whole
3598 /// accessor for an accessor — the caret of [`ErrorKind::MissingField`] and
3599 /// [`ErrorKind::NotARecord`].
3600 label_span: NodeSpan,
3601 /// The text whose type is `field` — the access, the new value, the accessor, the
3602 /// entry's own pattern — and the caret of a mismatch between it and the field's
3603 /// declared type.
3604 field_span: NodeSpan,
3605}
3606
3607impl FieldConstraint {
3608 /// This constraint read against everything solved so far: the equation it has
3609 /// become, `None` while its record type is still a variable, or the error it is.
3610 ///
3611 /// The equation is written declared-first, as `Constraint` asks: the field's type in
3612 /// the record, then the type it is used at. Its origin is the one
3613 /// [`Substitution::apply`] gives a constraint between `record` and `field`, so the
3614 /// declared side is explained by whatever brought the record type in — the
3615 /// annotation, typically — and a mismatch can say so.
3616 fn read(&self, substitution: &Substitution) -> Result<Option<Constraint>, ErrorKind> {
3617 let probe = substitution.apply(&Constraint::new(
3618 self.record.clone(),
3619 self.field.clone(),
3620 self.reason,
3621 self.field_span,
3622 ));
3623
3624 match &probe.left {
3625 Type::Variable(_) => Ok(None),
3626 Type::Record(fields) => match fields.get(&self.label) {
3627 Some(declared) => Ok(Some(Constraint {
3628 left: declared.clone(),
3629 right: probe.right,
3630 origin: probe.origin,
3631 })),
3632 None => Err(ErrorKind::MissingField {
3633 record: Box::new(probe.left.clone()),
3634 label: self.label.clone(),
3635 form: self.form,
3636 span: self.label_span,
3637 because: probe.origin.left_from,
3638 }),
3639 },
3640 other => Err(ErrorKind::NotARecord {
3641 tpe: Box::new(other.clone()),
3642 label: self.label.clone(),
3643 form: self.form,
3644 span: self.label_span,
3645 because: probe.origin.left_from,
3646 }),
3647 }
3648 }
3649
3650 /// The error this constraint is when nothing ever supplied its record type.
3651 fn unknown(&self, supplier: Supplier) -> ErrorKind {
3652 ErrorKind::RecordTypeUnknown {
3653 label: self.label.clone(),
3654 form: self.form,
3655 span: self.form_span,
3656 supplier,
3657 }
3658 }
3659}
3660
3661/// What one type variable was solved to, and where that type came from.
3662///
3663/// The cause is not used by inference at all. It is carried so that when this
3664/// solution is substituted into another constraint and *that* constraint then fails,
3665/// the failure can say where the type it failed against came from — see
3666/// [`Origin::left_from`].
3667///
3668/// It is a [`Cause`] and not an `Origin` because the question it answers is already
3669/// settled: [`Origin::cause_of`] resolved, at the moment the variable was solved,
3670/// whether the solving constraint introduced this type or was handed it. Nothing
3671/// downstream has to walk anything.
3672// No `Eq`: a `Cause` holds a `NodeSpan`, whose `PartialEq` is deliberately blind
3673// (see its documentation), so equality here is a claim about the types and the
3674// reasons, not about the positions.
3675#[derive(Debug, PartialEq, Clone)]
3676struct Solution {
3677 tpe: Type,
3678 cause: Cause,
3679}
3680
3681#[derive(Debug, PartialEq)]
3682struct Substitution {
3683 solutions: HashMap<TypeVariable, Solution>,
3684}
3685
3686impl Substitution {
3687 // constructors
3688
3689 fn empty() -> Substitution {
3690 Substitution {
3691 solutions: HashMap::new(),
3692 }
3693 }
3694
3695 fn one(tvar: TypeVariable, tpe: Type, cause: Cause) -> Substitution {
3696 let mut sub = Substitution::empty();
3697
3698 sub.solutions.insert(tvar, Solution { tpe, cause });
3699
3700 sub
3701 }
3702
3703 // methods
3704
3705 /// Rewrite a constraint with everything solved so far, recording for each side
3706 /// which solution first reached it.
3707 ///
3708 /// The two sides are tracked apart, because that is what tells a relayed type
3709 /// from an introduced one later on — see [`Origin::cause_of`]. A solution that
3710 /// rewrites only the right side has said nothing about the left, and treating it
3711 /// as though it had is what made a type error blame an annotation that was not
3712 /// load-bearing.
3713 ///
3714 /// The solutions are visited in type-variable order rather than in `HashMap`
3715 /// order: "first" has to mean the same thing on every run, or the secondary label
3716 /// of a diagnostic would move between compilations of an unchanged file. Ids are
3717 /// handed out as inference walks the term, so that order is roughly the order the
3718 /// user wrote things in.
3719 fn apply(&self, c: &Constraint) -> Constraint {
3720 let mut origin = c.origin.clone();
3721
3722 let mut solutions: Vec<_> = self.solutions.iter().collect();
3723 solutions.sort_by_key(|(tvar, _)| tvar.id);
3724
3725 for (tvar, solution) in solutions {
3726 // A solution that does not mention a variable a side uses rewrites
3727 // nothing there, and explains nothing about it either.
3728 if occurs(tvar, &c.left) {
3729 origin.rewritten(Side::Left, solution.cause);
3730 }
3731 if occurs(tvar, &c.right) {
3732 origin.rewritten(Side::Right, solution.cause);
3733 }
3734 }
3735
3736 Constraint {
3737 left: self.apply_type(&c.left),
3738 right: self.apply_type(&c.right),
3739 origin,
3740 }
3741 }
3742
3743 fn apply_type(&self, tpe: &Type) -> Type {
3744 self.solutions
3745 .iter()
3746 .fold(tpe.clone(), |tpe, (tvar, solution)| {
3747 Substitution::substitute(tpe, tvar, &solution.tpe)
3748 })
3749 }
3750
3751 /// Rewrite **every** type in a typed term with everything solved — the *zonk*.
3752 ///
3753 /// `annotate` gives each node a fresh inference variable and unification solves
3754 /// those variables somewhere else entirely, so until this runs a node's `tpe` is a
3755 /// `t17` that means nothing on its own. Applying the substitution to the root's
3756 /// type alone is enough to answer "what type is this declaration", which is all
3757 /// inference ever needed; it leaves every node below still holding a variable,
3758 /// which is not enough to generate code from
3759 /// ([`DEC-18` decision 1](../../docs/decisions/dec-18.md)).
3760 ///
3761 /// The types a pattern carries are rewritten too: a constructor pattern's
3762 /// arguments and the bindings it introduces are the types the branch body's
3763 /// variables were bound at.
3764 fn apply_term(&self, term: TypedTerm) -> TypedTerm {
3765 let kind = match term.kind {
3766 kind @ (TypedTermKind::Int(_)
3767 | TypedTermKind::Char(_)
3768 | TypedTermKind::String(_)
3769 | TypedTermKind::Float(_)
3770 | TypedTermKind::Unit
3771 | TypedTermKind::Hole) => kind,
3772 TypedTermKind::Identifier { reference, context } => TypedTermKind::Identifier {
3773 reference,
3774 context: self.apply_predicates(context),
3775 },
3776 TypedTermKind::Fun { param, body } => TypedTermKind::Fun {
3777 param: self.apply_binder(param),
3778 body: Box::new(self.apply_term(*body)),
3779 },
3780 TypedTermKind::Apply {
3781 fun,
3782 arg,
3783 saturation,
3784 } => TypedTermKind::Apply {
3785 fun: Box::new(self.apply_term(*fun)),
3786 arg: Box::new(self.apply_term(*arg)),
3787 saturation,
3788 },
3789 TypedTermKind::If {
3790 cond,
3791 true_branch,
3792 false_branch,
3793 } => TypedTermKind::If {
3794 cond: Box::new(self.apply_term(*cond)),
3795 true_branch: Box::new(self.apply_term(*true_branch)),
3796 false_branch: Box::new(self.apply_term(*false_branch)),
3797 },
3798 TypedTermKind::Let {
3799 binding,
3800 value,
3801 body,
3802 } => TypedTermKind::Let {
3803 binding: self.apply_binder(binding),
3804 value: Box::new(self.apply_term(*value)),
3805 body: Box::new(self.apply_term(*body)),
3806 },
3807 TypedTermKind::Tuple(Tuple::Two(a, b)) => {
3808 TypedTermKind::Tuple(Tuple::two(self.apply_term(*a), self.apply_term(*b)))
3809 }
3810 TypedTermKind::Tuple(Tuple::Three(a, b, c)) => TypedTermKind::Tuple(Tuple::three(
3811 self.apply_term(*a),
3812 self.apply_term(*b),
3813 self.apply_term(*c),
3814 )),
3815 TypedTermKind::Case {
3816 scrutinee,
3817 branches,
3818 form,
3819 } => TypedTermKind::Case {
3820 scrutinee: Box::new(self.apply_term(*scrutinee)),
3821 branches: branches
3822 .into_iter()
3823 .map(|(pattern, body)| {
3824 (
3825 self.apply_pattern(pattern),
3826 Box::new(self.apply_term(*body)),
3827 )
3828 })
3829 .collect(),
3830 form,
3831 },
3832 TypedTermKind::Record(fields) => TypedTermKind::Record(self.apply_fields(fields)),
3833 TypedTermKind::Update { record, fields } => TypedTermKind::Update {
3834 record: Box::new(self.apply_term(*record)),
3835 fields: self.apply_fields(fields),
3836 },
3837 TypedTermKind::Access {
3838 record,
3839 label,
3840 label_span,
3841 } => TypedTermKind::Access {
3842 record: Box::new(self.apply_term(*record)),
3843 label,
3844 label_span,
3845 },
3846 kind @ TypedTermKind::Accessor { .. } => kind,
3847 };
3848
3849 TypedTerm {
3850 span: term.span,
3851 tpe: self.apply_type(&term.tpe),
3852 kind,
3853 }
3854 }
3855
3856 /// Rewrite the type of each predicate: the context of a use, or a declaration's own,
3857 /// as it stands once everything is solved.
3858 fn apply_predicates(&self, predicates: Vec<Predicate>) -> Vec<Predicate> {
3859 predicates
3860 .into_iter()
3861 .map(|predicate| Predicate {
3862 class: predicate.class,
3863 tpe: self.apply_type(&predicate.tpe),
3864 })
3865 .collect()
3866 }
3867
3868 fn apply_fields(&self, fields: Vec<Field<TypedTerm>>) -> Vec<Field<TypedTerm>> {
3869 fields
3870 .into_iter()
3871 .map(|field| Field {
3872 label: field.label,
3873 label_span: field.label_span,
3874 value: self.apply_term(field.value),
3875 })
3876 .collect()
3877 }
3878
3879 fn apply_binder(&self, binder: TypeBinder) -> TypeBinder {
3880 TypeBinder {
3881 tpe: self.apply_type(&binder.tpe),
3882 name: binder.name,
3883 }
3884 }
3885
3886 fn apply_pattern(&self, pattern: TermPattern) -> TermPattern {
3887 let kind = match pattern.kind {
3888 kind @ (TermPatternKind::Anything
3889 | TermPatternKind::Bind(_)
3890 | TermPatternKind::Unit) => kind,
3891 TermPatternKind::Literal { tpe, value } => TermPatternKind::Literal {
3892 tpe: self.apply_type(&tpe),
3893 value,
3894 },
3895 TermPatternKind::Constructor {
3896 ctor,
3897 adt_args,
3898 args,
3899 } => TermPatternKind::Constructor {
3900 ctor,
3901 adt_args: adt_args.iter().map(|a| self.apply_type(a)).collect(),
3902 args: args
3903 .into_iter()
3904 .map(|arg| self.apply_sub_pattern(arg))
3905 .collect(),
3906 },
3907 TermPatternKind::Tuple { elements } => TermPatternKind::Tuple {
3908 elements: elements.map(|element| self.apply_sub_pattern(element.clone())),
3909 },
3910 TermPatternKind::Hole { args } => TermPatternKind::Hole {
3911 args: args
3912 .into_iter()
3913 .map(|arg| self.apply_sub_pattern(arg))
3914 .collect(),
3915 },
3916 TermPatternKind::Record { fields } => TermPatternKind::Record {
3917 fields: fields
3918 .into_iter()
3919 .map(|field| Field {
3920 label: field.label,
3921 label_span: field.label_span,
3922 value: self.apply_sub_pattern(field.value),
3923 })
3924 .collect(),
3925 },
3926 };
3927
3928 TermPattern {
3929 span: pattern.span,
3930 kind,
3931 }
3932 }
3933
3934 fn apply_sub_pattern(&self, sub: SubPattern) -> SubPattern {
3935 SubPattern {
3936 tpe: self.apply_type(&sub.tpe),
3937 pattern: self.apply_pattern(sub.pattern),
3938 }
3939 }
3940
3941 fn substitute(tpe: Type, tvar: &TypeVariable, replacement: &Type) -> Type {
3942 match tpe {
3943 Type::Literal(_) | Type::Unit => tpe,
3944 Type::Fun {
3945 param_tpe,
3946 return_tpe,
3947 } => Type::Fun {
3948 param_tpe: Box::new(Substitution::substitute(*param_tpe, tvar, replacement)),
3949 return_tpe: Box::new(Substitution::substitute(*return_tpe, tvar, replacement)),
3950 },
3951 Type::Tuple(Tuple::Two(a, b)) => Type::Tuple(Tuple::two(
3952 Substitution::substitute(*a, tvar, replacement),
3953 Substitution::substitute(*b, tvar, replacement),
3954 )),
3955 Type::Tuple(Tuple::Three(a, b, c)) => Type::Tuple(Tuple::three(
3956 Substitution::substitute(*a, tvar, replacement),
3957 Substitution::substitute(*b, tvar, replacement),
3958 Substitution::substitute(*c, tvar, replacement),
3959 )),
3960 Type::Adt(name, args) => Type::Adt(
3961 name,
3962 args.into_iter()
3963 .map(|a| Substitution::substitute(a, tvar, replacement))
3964 .collect(),
3965 ),
3966 Type::Record(fields) => Type::Record(
3967 fields
3968 .into_iter()
3969 .map(|(label, tpe)| (label, Substitution::substitute(tpe, tvar, replacement)))
3970 .collect(),
3971 ),
3972 Type::Variable(tvar2) if tvar == &tvar2 => replacement.clone(),
3973 tpe @ Type::Variable(_) => tpe,
3974 }
3975 }
3976
3977 fn merge(&self, other: Substitution) -> Substitution {
3978 // This merge means we should try sub_tail first, and then sub_head
3979 // Merging other in self means we apply `other` substitution to `self` solutions
3980 // When merging, we want `other` solutions to take precedences over `self` solutions
3981
3982 let self_solutions = self.solutions.iter().map(|(k, v)| {
3983 (
3984 k.clone(),
3985 Solution {
3986 tpe: other.apply_type(&v.tpe),
3987 // The cause says where this variable's type came from, which
3988 // rewriting the type does not change.
3989 cause: v.cause,
3990 },
3991 )
3992 });
3993
3994 let mut sub = Substitution::empty();
3995
3996 sub.solutions.extend(self_solutions);
3997 sub.solutions.extend(other.solutions);
3998
3999 sub
4000 }
4001}
4002
4003/// Does `tvar` appear anywhere inside `tpe`?
4004///
4005/// Two callers, for two different reasons: `unify_variable` uses it as the occurs
4006/// check that keeps it from building an infinite type, and `Substitution::apply` uses
4007/// it to tell whether a solution actually rewrites a given constraint — which is what
4008/// decides whether that solution explains one of the constraint's types.
4009fn occurs(tvar: &TypeVariable, tpe: &Type) -> bool {
4010 match tpe {
4011 Type::Fun {
4012 param_tpe,
4013 return_tpe,
4014 } => occurs(tvar, param_tpe) || occurs(tvar, return_tpe),
4015 Type::Tuple(tuple) => tuple.iter().any(|t| occurs(tvar, t)),
4016 Type::Adt(_, args) => args.iter().any(|a| occurs(tvar, a)),
4017 Type::Record(fields) => fields.values().any(|t| occurs(tvar, t)),
4018 Type::Variable(tvar2) => tvar == tvar2,
4019 _ => false,
4020 }
4021}
4022
4023/// Every variable of `tpe`, each once, in the order it first appears.
4024fn free_variables_in_order(tpe: &Type) -> Vec<TypeVariable> {
4025 fn walk(tpe: &Type, into: &mut Vec<TypeVariable>) {
4026 match tpe {
4027 Type::Literal(_) | Type::Unit => (),
4028 Type::Variable(tvar) => {
4029 if !into.contains(tvar) {
4030 into.push(tvar.clone());
4031 }
4032 }
4033 Type::Fun {
4034 param_tpe,
4035 return_tpe,
4036 } => {
4037 walk(param_tpe, into);
4038 walk(return_tpe, into);
4039 }
4040 Type::Tuple(tuple) => tuple.iter().for_each(|t| walk(t, into)),
4041 Type::Adt(_, args) => args.iter().for_each(|t| walk(t, into)),
4042 Type::Record(fields) => fields.values().for_each(|t| walk(t, into)),
4043 }
4044 }
4045
4046 let mut variables = Vec::new();
4047 walk(tpe, &mut variables);
4048 variables
4049}
4050
4051/// A [`Type`] written with its variables named, the way an annotation wrote them, and
4052/// every union bare.
4053struct WithNames<'a>(&'a Type, &'a VariableNames);
4054
4055impl std::fmt::Display for WithNames<'_> {
4056 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4057 self.0.write(f, AdtNames::Unqualified, Some(self.1))
4058 }
4059}
4060
4061/// A predicate written as the source writes a constraint's use: the class, then the type,
4062/// in parentheses when it is itself applied.
4063fn predicate_text(predicate: &Predicate, spellings: &Spellings) -> String {
4064 let applied = match &predicate.tpe {
4065 Type::Fun { .. } => true,
4066 Type::Adt(_, args) => !args.is_empty(),
4067 _ => false,
4068 };
4069 let tpe = Spelled(&predicate.tpe, spellings);
4070
4071 if applied {
4072 format!("{} ({})", predicate.class.unqualified_name(), tpe)
4073 } else {
4074 format!("{} {}", predicate.class.unqualified_name(), tpe)
4075 }
4076}
4077
4078/// The names in scope while one declaration is annotated, and the counter its fresh
4079/// type variables come from.
4080///
4081/// Two kinds of name, looked up differently:
4082///
4083/// - A **binder** — a parameter, a `case` binding — is introduced by the term being
4084/// annotated. Its type is one type: every use of it shares its variables, which is
4085/// what lets inference learn a parameter's type from how the body uses it.
4086/// - A **global** — a declaration of this module or of an imported one, or a
4087/// constructor — comes from `type_check`'s environment. Its type is read as quantified
4088/// over every variable in it, and [`by_name`](Self::by_name) hands each use a copy
4089/// with those variables replaced by fresh ones. That is what lets one declaration use
4090/// `Just` at `Maybe Int` and `Nothing` at `Maybe Char`, or `identity` at two types.
4091///
4092/// Reading every variable of a global as quantified is only right because each one was
4093/// translated from a declared type — an annotation or a union — on its own, so none of
4094/// its variables is shared with anything else in the environment. A binder shadows a
4095/// global of the same name.
4096struct Types {
4097 counter: u32,
4098 env: HashMap<String, Type>,
4099 globals: HashMap<String, Scheme>,
4100}
4101
4102/// What the typer's environment holds for a global: a type, and the context its
4103/// constraints wrote in front of it.
4104///
4105/// Both are read as quantified over every variable in the type, and
4106/// [`Types::by_name`] instantiates them together — the same variable by the same fresh
4107/// one in the context as in the type — so that a use of `min : Comparable a => a -> a ->
4108/// a` at `Int` is one use of `a`. Each constraint of the context is on one of the type's
4109/// variables, since an annotation's constraint has to be: `canonical::Error::
4110/// ConstraintVariableNotInType`.
4111#[derive(Debug, Clone)]
4112struct Scheme {
4113 /// The constraints, in the order written, each a class and the variable of `tpe`
4114 /// it is required of.
4115 context: Vec<Predicate>,
4116 tpe: Type,
4117}
4118
4119impl Scheme {
4120 /// A scheme with no constraint.
4121 fn unconstrained(tpe: Type) -> Scheme {
4122 Scheme {
4123 context: Vec::new(),
4124 tpe,
4125 }
4126 }
4127}
4128
4129/// Names for type variables, for the messages that write a type the way an annotation
4130/// did.
4131type VariableNames = HashMap<TypeVariable, String>;
4132
4133impl Types {
4134 fn new() -> Types {
4135 let counter = 10;
4136 let env = HashMap::new();
4137 let globals = HashMap::new();
4138
4139 Types {
4140 counter,
4141 env,
4142 globals,
4143 }
4144 }
4145
4146 /// Put the declarations of an outer scope in reach, as globals.
4147 fn extends_with(&mut self, global: HashMap<String, Scheme>) {
4148 self.globals.extend(global)
4149 }
4150
4151 fn fresh_var(&mut self) -> Type {
4152 self.counter += 1;
4153
4154 Type::Variable(TypeVariable::flexible(self.counter))
4155 }
4156
4157 fn add_binder(&mut self, binding: TypeBinder) {
4158 self.env.insert(binding.name, binding.tpe);
4159 }
4160
4161 fn remove_binder(&mut self, name: &str) {
4162 self.env.remove(name);
4163 }
4164
4165 /// The type of one use of `name` — a binder's own type, or a fresh instance of a
4166 /// global's — and the constraints of that use: the global's context, instantiated
4167 /// with the same fresh variables as its type. A binder has none.
4168 ///
4169 /// Each constraint is an obligation of the use, which `constraint::collect` turns
4170 /// into one and `discharge` answers once unification is done.
4171 fn by_name(&mut self, name: &String) -> Option<(Type, Vec<Predicate>)> {
4172 if let Some(tpe) = self.env.get(name) {
4173 return Some((tpe.clone(), Vec::new()));
4174 }
4175
4176 let scheme = self.globals.get(name)?.clone();
4177 let mut fresh = HashMap::new();
4178 let tpe = self.instantiate(scheme.tpe, &mut fresh);
4179 let context = scheme
4180 .context
4181 .into_iter()
4182 .map(|predicate| Predicate {
4183 class: predicate.class,
4184 tpe: self.instantiate(predicate.tpe, &mut fresh),
4185 })
4186 .collect();
4187
4188 Some((tpe, context))
4189 }
4190
4191 /// `tpe` with each of its variables replaced by a fresh one, the same variable by
4192 /// the same fresh one throughout.
4193 fn instantiate(&mut self, tpe: Type, fresh: &mut HashMap<TypeVariable, Type>) -> Type {
4194 match tpe {
4195 Type::Literal(_) | Type::Unit => tpe,
4196 Type::Variable(tvar) => {
4197 if let Some(replacement) = fresh.get(&tvar) {
4198 return replacement.clone();
4199 }
4200 let replacement = self.fresh_var();
4201 fresh.insert(tvar, replacement.clone());
4202 replacement
4203 }
4204 Type::Fun {
4205 param_tpe,
4206 return_tpe,
4207 } => Type::Fun {
4208 param_tpe: Box::new(self.instantiate(*param_tpe, fresh)),
4209 return_tpe: Box::new(self.instantiate(*return_tpe, fresh)),
4210 },
4211 Type::Tuple(Tuple::Two(a, b)) => Type::Tuple(Tuple::two(
4212 self.instantiate(*a, fresh),
4213 self.instantiate(*b, fresh),
4214 )),
4215 Type::Tuple(Tuple::Three(a, b, c)) => Type::Tuple(Tuple::three(
4216 self.instantiate(*a, fresh),
4217 self.instantiate(*b, fresh),
4218 self.instantiate(*c, fresh),
4219 )),
4220 Type::Adt(name, args) => Type::Adt(
4221 name,
4222 args.into_iter()
4223 .map(|arg| self.instantiate(arg, fresh))
4224 .collect(),
4225 ),
4226 Type::Record(fields) => Type::Record(
4227 fields
4228 .into_iter()
4229 .map(|(label, tpe)| (label, self.instantiate(tpe, fresh)))
4230 .collect(),
4231 ),
4232 }
4233 }
4234}
4235
4236/// infer the type of the given term given known function defined in the outer scopes.
4237/// This is a translation of the algorithm demonstrated by
4238/// [Ionut Gan at I T.A.K.E Unconference 2015](https://www.youtube.com/watch?v=oPVTNxiMcSU)
4239pub fn infer(term: Term, global: HashMap<String, Type>) -> Result<Type, ErrorKind> {
4240 let global = global
4241 .into_iter()
4242 .map(|(name, tpe)| (name, Scheme::unconstrained(tpe)))
4243 .collect();
4244
4245 infer_annotated(term, global, None, &classes::ClassTable::empty()).map(|(term, _)| term.tpe)
4246}
4247
4248/// [`infer`], with the declaration's type annotation as a constraint of its own, and
4249/// answering with the whole solved term rather than only its type.
4250///
4251/// The annotation is put *first*, before the constraints the body generates, and that
4252/// ordering is the point of the function. `unify` solves constraints in order, so the
4253/// annotated type is substituted into the body's constraints before any of them are
4254/// solved; when one of them then fails, its [`Origin::explanation`] names the annotation,
4255/// and the diagnostic can say `Int` was expected *because of the annotation* rather
4256/// than merely that the declaration as a whole does not check.
4257///
4258/// The annotation's variables are rigid when it arrives (see [`TypeVariable`]), so `unify`
4259/// raises [`ErrorKind::RigidVariable`] where the body needs one of them to be a type of its
4260/// own, and a given of the annotation's context can only answer an obligation on the very
4261/// variable it is on.
4262///
4263/// The term handed back is zonked — see [`Substitution::apply_term`] — so every node
4264/// carries the type inference solved for it and not the variable `annotate` gave it.
4265/// Beside it comes the context the annotation required of its variables, each on the
4266/// rigid variable it was given on.
4267///
4268/// # The order of the steps
4269///
4270/// Equations first, then field constraints, then obligations. A field constraint can
4271/// solve the variable an instance is looked up by, so an obligation is read only once
4272/// both have run. Whether reading an instance's context can in turn decide a field
4273/// constraint does not arise: an obligation only reads the solution and adds nothing to
4274/// it.
4275fn infer_annotated(
4276 term: Term,
4277 global: HashMap<String, Scheme>,
4278 annotation: Option<Annotation>,
4279 table: &classes::ClassTable,
4280) -> Result<(TypedTerm, Vec<Predicate>), ErrorKind> {
4281 let mut env = Types::new();
4282 env.extends_with(global);
4283
4284 let typed_term = annotate::annotate(term, &mut env)?;
4285 debug!("typed term: {:#?}", typed_term);
4286
4287 let mut constraints = Vec::new();
4288 let annotated = annotation.is_some();
4289 let mut given = Vec::new();
4290 let mut names = Vec::new();
4291 let mut member_variables = Vec::new();
4292 let mut written = Written::Annotation;
4293
4294 if let Some(annotation) = annotation {
4295 given = annotation.context;
4296 names = annotation.names;
4297 member_variables = annotation.member_variables;
4298 written = annotation.written;
4299
4300 // Left is the annotation's type, because left is the type of the text the
4301 // span points at — see `Constraint`.
4302 constraints.push(Constraint::new(
4303 annotation.tpe,
4304 typed_term.tpe.clone(),
4305 annotation.reason,
4306 annotation.span,
4307 ));
4308 }
4309
4310 let constraint::Constraints {
4311 equations,
4312 fields,
4313 holes,
4314 obligations,
4315 } = constraint::collect(&typed_term);
4316 constraints.extend(equations);
4317 debug!("Constraints: {:#?}", constraints);
4318
4319 let substitution = unifier::unify(constraints)?;
4320 // Read only now, with every equation of the declaration solved: see
4321 // `FieldConstraint`.
4322 let declaration = unifier::Declaration {
4323 holes: &holes,
4324 declared: &typed_term.tpe,
4325 annotated,
4326 };
4327 let substitution = unifier::read_fields(substitution, fields, &declaration)?;
4328
4329 // Read last, against the final substitution: see the `classes` module.
4330 classes::discharge(
4331 table,
4332 obligations,
4333 &substitution,
4334 &classes::Declared {
4335 tpe: &typed_term.tpe,
4336 annotated,
4337 given: &given,
4338 names: &names,
4339 member_variables: &member_variables,
4340 written,
4341 },
4342 )?;
4343
4344 let context = given
4345 .iter()
4346 .map(|(class, variable)| Predicate {
4347 class: class.clone(),
4348 tpe: Type::Variable(variable.clone()),
4349 })
4350 .collect();
4351
4352 Ok((substitution.apply_term(typed_term), context))
4353}
4354
4355// TODO Once we have changed the Term to the zelkova primitives, rewrite the tests
4356// to use actual source code instead of AST. It's a pain to write them but it's even
4357// more of a pain to read them :)
4358// TODO Also write some assertions on the type instead of just printing XD
4359// TODO Import remaining tests. Plus the one for the modules above.
4360#[cfg(test)]
4361mod tests {
4362 use super::*;
4363
4364 // These terms are written by hand rather than translated from source, so they
4365 // have no position — `Term::bare`. What they pin is inference, which does not
4366 // read spans; the tests that pin what a *diagnostic* points at go through real
4367 // source, in `crates/zelkova-compiler/tests/typer.rs`.
4368 fn int(i: i64) -> Term {
4369 Term::bare(TermKind::Int(i))
4370 }
4371 fn var(n: &str) -> Term {
4372 Term::bare(TermKind::Identifier(Reference::local(n)))
4373 }
4374 fn fun(arg: &str, body: Term) -> Term {
4375 Term::bare(TermKind::Fun {
4376 param: arg.to_owned(),
4377 body: Box::new(body),
4378 })
4379 }
4380 fn if_(cond: Term, true_branch: Term, false_branch: Term) -> Term {
4381 Term::bare(TermKind::If {
4382 cond: Box::new(cond),
4383 true_branch: Box::new(true_branch),
4384 false_branch: Box::new(false_branch),
4385 })
4386 }
4387 fn apply(fun: Term, arg: Term) -> Term {
4388 Term::bare(TermKind::Apply {
4389 fun: Box::new(fun),
4390 arg: Box::new(arg),
4391 saturation: Saturation::Partial,
4392 })
4393 }
4394 fn let_(binding: &str, value: Term, body: Term) -> Term {
4395 Term::bare(TermKind::Let {
4396 binding: binding.to_owned(),
4397 value: Box::new(value),
4398 body: Box::new(body),
4399 })
4400 }
4401
4402 #[derive(Default)]
4403 struct Signature {
4404 counter: u8, // max 255 letters
4405 known: HashMap<u32, String>,
4406 }
4407
4408 impl Signature {
4409 // Helper function to reduce boilerplate
4410 fn of_type(tpe: Type) -> String {
4411 let mut sig: Signature = Default::default();
4412 sig.type_signature(tpe)
4413 }
4414
4415 fn type_signature(&mut self, tpe: Type) -> String {
4416 match tpe {
4417 Type::Literal(TypeLiteral::Int) => "Int".to_owned(),
4418 Type::Literal(TypeLiteral::Char) => "Char".to_owned(),
4419 Type::Literal(TypeLiteral::Float) => "Float".to_owned(),
4420 Type::Literal(TypeLiteral::String) => "String".to_owned(),
4421 Type::Unit => "()".to_owned(),
4422 Type::Variable(TypeVariable { id, .. }) => {
4423 if let Some(name) = self.known.get(&id) {
4424 name.clone()
4425 } else {
4426 let name = self.counter_as_letter();
4427 self.counter += 1;
4428
4429 self.known.insert(id, name.clone());
4430
4431 name
4432 }
4433 }
4434 Type::Fun {
4435 param_tpe,
4436 return_tpe,
4437 } => {
4438 let is_param_fun = matches!(param_tpe.as_ref(), Type::Fun { .. });
4439 let param = self.type_signature(*param_tpe);
4440 let retur = self.type_signature(*return_tpe);
4441
4442 if is_param_fun {
4443 format!("({}) -> {}", param, retur)
4444 } else {
4445 format!("{} -> {}", param, retur)
4446 }
4447 }
4448 Type::Tuple(Tuple::Two(a, b)) => {
4449 format!("({}, {})", self.type_signature(*a), self.type_signature(*b))
4450 }
4451 Type::Tuple(Tuple::Three(a, b, c)) => {
4452 format!(
4453 "({}, {}, {})",
4454 self.type_signature(*a),
4455 self.type_signature(*b),
4456 self.type_signature(*c)
4457 )
4458 }
4459 Type::Adt(name, args) if args.is_empty() => name.unqualified_name().to_string(),
4460 Type::Adt(name, args) => {
4461 let arg_strs: Vec<String> =
4462 args.into_iter().map(|a| self.type_signature(a)).collect();
4463 format!("{} {}", name.unqualified_name(), arg_strs.join(" "))
4464 }
4465 Type::Record(fields) => {
4466 let fields: Vec<String> = fields
4467 .into_iter()
4468 .map(|(label, tpe)| {
4469 format!("{} : {}", label.as_str(), self.type_signature(tpe))
4470 })
4471 .collect();
4472 format!("{{ {} }}", fields.join(", "))
4473 }
4474 }
4475 }
4476
4477 fn counter_as_letter(&self) -> String {
4478 let m = self.counter % 26;
4479 let d = self.counter / 26;
4480
4481 let m_char = (97 + m) as char; // 97 is 'a'
4482 let d_char = (96 + d) as char; // -1 because we start at 1
4483
4484 if d > 0 {
4485 format!("{}{}", d_char, m_char)
4486 } else {
4487 format!("{}", m_char)
4488 }
4489 }
4490 }
4491
4492 #[test]
4493 fn infer_identity_function() {
4494 let global = HashMap::new();
4495 let term = fun("a", var("a"));
4496 let infered = infer(term, global).unwrap();
4497
4498 assert_eq!(Signature::of_type(infered), "a -> a".to_owned());
4499 }
4500
4501 #[test]
4502 fn infer_const_function() {
4503 let global = HashMap::new();
4504 let term = fun("a", fun("b", var("a")));
4505 let infered = infer(term, global).unwrap();
4506
4507 assert_eq!(Signature::of_type(infered), "a -> b -> a".to_owned());
4508 }
4509
4510 #[test]
4511 fn infer_compose_function() {
4512 let global = HashMap::new();
4513 // \f -> \g -> \x -> f ( g x )
4514 let term = fun(
4515 "f",
4516 fun("g", fun("x", apply(var("f"), apply(var("g"), var("x"))))),
4517 );
4518 let infered = infer(term, global).unwrap();
4519
4520 assert_eq!(
4521 Signature::of_type(infered),
4522 "(a -> b) -> (c -> a) -> c -> b".to_owned()
4523 );
4524 }
4525
4526 #[test]
4527 fn infer_pred_function() {
4528 let global = HashMap::new();
4529 let term = fun("pred", if_(apply(var("pred"), int(1)), int(2), int(3)));
4530 let infered = infer(term, global).unwrap();
4531
4532 // Integer literals infer as `Int`
4533 assert_eq!(
4534 Signature::of_type(infered),
4535 "(Int -> Bool) -> Int".to_owned()
4536 );
4537 }
4538
4539 #[test]
4540 fn infer_increment_function() {
4541 let mut global = HashMap::new();
4542 // "+" -> Type.FUN(Type.INT, Type.FUN(Type.INT, Type.INT)),
4543 global.insert(
4544 "+".to_owned(),
4545 Type::Fun {
4546 param_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4547 return_tpe: Box::new(Type::Fun {
4548 param_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4549 return_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4550 }),
4551 },
4552 );
4553 let term = let_(
4554 "inc",
4555 fun("a", apply(apply(var("+"), var("a")), int(1))),
4556 apply(var("inc"), int(42)),
4557 );
4558 let infered = infer(term, global).unwrap();
4559
4560 assert_eq!(Signature::of_type(infered), "Int".to_owned());
4561 }
4562
4563 #[test]
4564 fn infer_incdec_function() {
4565 let mut global = HashMap::new();
4566 global.insert(
4567 "+".to_owned(),
4568 Type::Fun {
4569 param_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4570 return_tpe: Box::new(Type::Fun {
4571 param_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4572 return_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4573 }),
4574 },
4575 );
4576 global.insert(
4577 "-".to_owned(),
4578 Type::Fun {
4579 param_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4580 return_tpe: Box::new(Type::Fun {
4581 param_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4582 return_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4583 }),
4584 },
4585 );
4586 let term = let_(
4587 "inc",
4588 fun("a", apply(apply(var("+"), var("a")), int(1))),
4589 let_(
4590 "dec",
4591 fun("a", apply(apply(var("-"), var("a")), int(1))),
4592 apply(var("dec"), apply(var("inc"), int(42))),
4593 ),
4594 );
4595 let infered = infer(term, global).unwrap();
4596
4597 assert_eq!(Signature::of_type(infered), "Int".to_owned());
4598 }
4599
4600 #[test]
4601 fn infer_cannot_possible() {
4602 let mut global = HashMap::new();
4603 global.insert(
4604 "+".to_owned(),
4605 Type::Fun {
4606 param_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4607 return_tpe: Box::new(Type::Fun {
4608 param_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4609 return_tpe: Box::new(Type::Literal(TypeLiteral::Int)),
4610 }),
4611 },
4612 );
4613 global.insert("True".to_owned(), bool_type());
4614 let term = apply(apply(var("+"), var("True")), int(1));
4615 assert!(infer(term, global).is_err());
4616 }
4617
4618 // --- A constructor pattern finds only this module's own unions ------------
4619
4620 /// The qualified name of `name` as declared by `module` of the package `main`.
4621 fn qual(module: &str, name: &str) -> QualName {
4622 QualName::in_module(crate::PackageName::new("main").unwrap(), module, name)
4623 }
4624
4625 /// `Main`'s own unions, as `translate_pattern` receives them: one nullary
4626 /// `Main.Size`.
4627 fn main_size() -> (QualName, canonical::UnionType) {
4628 (
4629 qual("Main", "Size"),
4630 canonical::UnionType {
4631 span: NodeSpan::none(),
4632 variables: vec![],
4633 variants: vec![canonical::TypeConstructor {
4634 name: "Big".into(),
4635 type_parameters: vec![],
4636 tpe: qual("Main", "Size"),
4637 }],
4638 },
4639 )
4640 }
4641
4642 /// A nullary constructor pattern for `name`, building the union `tpe`.
4643 fn constructor_pattern(name: &str, tpe: QualName) -> canonical::Pattern {
4644 canonical::Pattern {
4645 span: NodeSpan::none(),
4646 kind: canonical::PatternKind::Constructor {
4647 ctor: canonical::TypeConstructor {
4648 name: name.into(),
4649 type_parameters: vec![],
4650 tpe,
4651 },
4652 args: vec![],
4653 },
4654 }
4655 }
4656
4657 /// The four things `canonical::ExpressionKind` calls a name stay four things in the
4658 /// IR.
4659 ///
4660 /// They used to be one: every one of them became `TermKind::Identifier(String)`, and
4661 /// the string is bare for a local and qualified for the other three, so nothing
4662 /// downstream could tell a parameter from an import from a constructor
4663 /// ([`DEC-18` decision
4664 /// 1](../../docs/decisions/dec-18.md#1--the-backend-reads-a-typed-ir-and-the-typer-is-what-produces-it)).
4665 ///
4666 /// Written against hand-built canonical expressions rather than against source, so
4667 /// that all four are read off one translation with no other module needing to be
4668 /// checked first.
4669 ///
4670 /// Mutation-checked by giving the `VarForeign` and `VarTopLevel` arms of
4671 /// `canonical_expr_to_term` the same `ReferenceKind`, which is the collapse this
4672 /// pins: the two assertions naming them then read the same value.
4673 #[test]
4674 fn the_four_kinds_of_name_stay_apart() {
4675 let (union_name, union) = main_size();
4676 let translation = Translation::of_types(HashMap::from([(union_name.clone(), &union)]));
4677 let lib = crate::PackageName::new("lib").unwrap();
4678 let lib_size = QualName::in_module(lib.clone(), "Lib", "size");
4679
4680 let reference = |kind: canonical::ExpressionKind| {
4681 let mut counter = 0;
4682 let expression = canonical::Expression::bare(kind);
4683
4684 match canonical_expr_to_term(&expression, &translation, &mut counter) {
4685 Some(Term {
4686 kind: TermKind::Identifier(reference),
4687 ..
4688 }) => reference,
4689 other => panic!("expected a name, got {:?}", other),
4690 }
4691 };
4692
4693 assert_eq!(
4694 reference(canonical::ExpressionKind::VarLocal("size".into())).kind,
4695 ReferenceKind::Local
4696 );
4697 assert_eq!(
4698 reference(canonical::ExpressionKind::VarTopLevel(qual("Main", "size"))).kind,
4699 ReferenceKind::TopLevel(qual("Main", "size"))
4700 );
4701 assert_eq!(
4702 reference(canonical::ExpressionKind::VarForeign(
4703 lib_size.clone(),
4704 lib.clone(),
4705 canonical::Type::Variable("a".into())
4706 ))
4707 .kind,
4708 ReferenceKind::Foreign(lib_size, lib, 0)
4709 );
4710 assert_eq!(
4711 reference(canonical::ExpressionKind::VarConstructor(
4712 qual("Main", "Big"),
4713 canonical::Type::Type(union_name.clone(), vec![])
4714 ))
4715 .kind,
4716 ReferenceKind::Constructor(Constructor {
4717 union: union_name,
4718 name: "Big".into(),
4719 index: 0,
4720 arity: 0,
4721 })
4722 );
4723 }
4724
4725 /// `A.S` builds `A.Size`, and a `Main` that happens to declare its own `Size`
4726 /// is not where that union is found.
4727 ///
4728 /// `BUG-35`: the lookup narrowed the constructor's type to its unqualified half,
4729 /// so `A.S` found `Main.Size` and the pattern was translated at the local type.
4730 /// With no `A` in the translation, the lookup finds nothing at all.
4731 ///
4732 /// Mutation-checked by restoring the narrowed lookup
4733 /// (`unions` keyed by `Name`, `get(&ctor.tpe.unqualified_name())`): the
4734 /// pattern is then translated and the assertion goes red.
4735 #[test]
4736 fn an_imported_constructor_does_not_find_a_local_type_of_the_same_name() {
4737 let (name, union) = main_size();
4738 let translation = Translation::of_types(HashMap::from([(name, &union)]));
4739 let mut counter = 0;
4740
4741 let pattern = constructor_pattern("S", qual("A", "Size"));
4742
4743 assert!(
4744 translate_pattern(&pattern, &translation, &mut counter).is_none(),
4745 "`A.S` is not a constructor of `Main.Size`"
4746 );
4747 }
4748
4749 /// The other half: `Main`'s own constructor still finds `Main`'s own union, so
4750 /// the test above is not passing because the lookup stopped finding anything.
4751 #[test]
4752 fn a_local_constructor_finds_its_own_type() {
4753 let (name, union) = main_size();
4754 let translation = Translation::of_types(HashMap::from([(name, &union)]));
4755 let mut counter = 0;
4756
4757 let pattern = constructor_pattern("Big", qual("Main", "Size"));
4758
4759 let translated = translate_pattern(&pattern, &translation, &mut counter)
4760 .expect("`Main.Big` is a constructor of `Main.Size`");
4761
4762 match translated.kind {
4763 TermPatternKind::Constructor { ctor, .. } => {
4764 assert_eq!(ctor.union, qual("Main", "Size"));
4765 }
4766 other => panic!("expected a constructor pattern, got {:?}", other),
4767 }
4768 }
4769
4770 // --- Display for Type ---------------------------------------------------
4771
4772 fn int_t() -> Type {
4773 Type::Literal(TypeLiteral::Int)
4774 }
4775 fn bool_t() -> Type {
4776 bool_type()
4777 }
4778 fn char_t() -> Type {
4779 Type::Literal(TypeLiteral::Char)
4780 }
4781 fn fun_t(param: Type, ret: Type) -> Type {
4782 Type::Fun {
4783 param_tpe: Box::new(param),
4784 return_tpe: Box::new(ret),
4785 }
4786 }
4787 /// A union declared in a module called `Widget`, which is never what `Display`
4788 /// writes — the point of the tests below is that it writes the bare `name`.
4789 fn adt(name: &str, args: Vec<Type>) -> Type {
4790 Type::Adt(qual("Widget", name), args)
4791 }
4792
4793 /// `Display for Type` is the text diagnostics quote back to the user, so its two
4794 /// parenthesisation rules and its inference-variable spelling are user-visible
4795 /// output. Nothing else pins them: the pipeline test that renders a type mismatch
4796 /// only ever reaches the `Literal` arms. Dropping a parenthesis here would print
4797 /// `Maybe Maybe Int`, which reads as a different type, with the suite still green.
4798 #[test]
4799 fn display_writes_types_the_way_the_source_spells_them() {
4800 let cases: Vec<(Type, &str)> = vec![
4801 // A function in *parameter* position is parenthesised, because `->` is
4802 // right-associative: `(a -> b) -> c` and `a -> b -> c` are different types.
4803 (
4804 fun_t(fun_t(int_t(), bool_t()), int_t()),
4805 "(Int -> Bool) -> Int",
4806 ),
4807 // In *return* position it is not, for the same reason: the chain already
4808 // re-reads as itself.
4809 (
4810 fun_t(int_t(), fun_t(bool_t(), char_t())),
4811 "Int -> Bool -> Char",
4812 ),
4813 // An applied `Adt` nested inside another needs parens to survive a re-read.
4814 (
4815 adt("Maybe", vec![adt("Maybe", vec![int_t()])]),
4816 "Maybe (Maybe Int)",
4817 ),
4818 // So does a function used as an `Adt` argument.
4819 (
4820 adt("Maybe", vec![fun_t(int_t(), bool_t())]),
4821 "Maybe (Int -> Bool)",
4822 ),
4823 // A *nullary* `Adt` argument does not: there is nothing to mis-group.
4824 (adt("List", vec![adt("Never", vec![])]), "List Never"),
4825 // And an applied `Adt` in parameter position does not either — application
4826 // binds tighter than `->`.
4827 (
4828 fun_t(adt("Maybe", vec![int_t()]), bool_t()),
4829 "Maybe Int -> Bool",
4830 ),
4831 (Type::Tuple(Tuple::two(int_t(), bool_t())), "( Int, Bool )"),
4832 (
4833 Type::Tuple(Tuple::three(int_t(), bool_t(), char_t())),
4834 "( Int, Bool, Char )",
4835 ),
4836 // Inference variables have no source syntax; Elm spells them `t{n}`.
4837 (Type::Variable(TypeVariable::flexible(7)), "t7"),
4838 ];
4839
4840 for (tpe, expected) in cases {
4841 assert_eq!(format!("{}", tpe), expected, "rendering {:?}", tpe);
4842 }
4843 }
4844
4845 /// `ErrorKind::CircularType` names one type, but the solution a variable would
4846 /// have had to contain itself in is built out of everything it was unified
4847 /// against — so one type is enough to hold two same-named declarations.
4848 ///
4849 /// Written by hand because no Zelkova source available today produces a circular
4850 /// type at all: the constructs that do (`let`, lambdas) are unimplemented, and
4851 /// `unifier.rs` is the only thing that raises the variant.
4852 ///
4853 /// Mutation-checked by quoting `tpe` through `Display` unconditionally, the way
4854 /// the arm was first written, which reports *contain itself in `Box Size Size`*.
4855 #[test]
4856 fn a_circular_type_naming_two_modules_alike_qualifies_both() {
4857 let tpe = Type::Adt(
4858 qual("Lib", "Box"),
4859 vec![
4860 Type::Adt(qual("A", "Size"), vec![]),
4861 Type::Adt(qual("B", "Size"), vec![]),
4862 ],
4863 );
4864
4865 let kind = ErrorKind::CircularType {
4866 tpe: Box::new(tpe),
4867 origin: Box::new(Origin::new(Reason::Annotation, NodeSpan::none())),
4868 };
4869
4870 assert_eq!(
4871 kind.message(&Spellings::default()),
4872 "circular type: a type variable would have to contain itself in \
4873 `Lib.Box A.Size B.Size`"
4874 );
4875 }
4876
4877 /// The counterpart: one declaration per spelling, so the type is quoted the way
4878 /// the source writes it.
4879 #[test]
4880 fn a_circular_type_with_no_collision_stays_unqualified() {
4881 let kind = ErrorKind::CircularType {
4882 tpe: Box::new(adt("Box", vec![adt("Size", vec![])])),
4883 origin: Box::new(Origin::new(Reason::Annotation, NodeSpan::none())),
4884 };
4885
4886 assert_eq!(
4887 kind.message(&Spellings::default()),
4888 "circular type: a type variable would have to contain itself in `Box Size`"
4889 );
4890 }
4891}