Skip to main content

zelkova_compiler/canonical/
derivation.rs

1//! Derivation: what a class says about how it is derived, and what a `derived` instance is
2//! made of.
3//!
4//! [Type classes](../../../docs/spec/type-classes.md#an-instance-may-be-derived) is the
5//! rule, and this module is its three halves, each run during canonicalization.
6//!
7//! # A derivation is checked where it is written
8//!
9//! [`class_derivations`] holds each `derived member` of a class body to what the chapter
10//! asks of it: it names a member, once; the member's signature is `a -> a -> R` or
11//! `a -> R` with `R` free of the class variable; its bindings are exactly the two or three
12//! that signature calls for; and the derivations cover every member or none. What passes
13//! is kept on the [`ClassSignature`], so an importing module reads it from the interface.
14//!
15//! # What a derived instance requires
16//!
17//! [`derive_all`] takes every `derived` instance of a module together. Each is read for
18//! the shape its head gives a walk — a union's constructors, a tuple, `()` — and for what
19//! every argument of every variant needs, which is an instance of the derived class at the
20//! argument's type. An argument that is a variable of the head is a constraint on the
21//! instance: that is the context, inferred. An argument of a concrete type needs an
22//! instance in scope, and one that is an application needs the instance of its head and
23//! whatever that instance's context asks of the arguments, down to the variables.
24//!
25//! An instance that writes a context has that context and no other. What its arguments
26//! need is still read, and each constraint of it has to be one the written context
27//! provides, itself or through a class it is a superclass of ([`provides`]); one that is
28//! not is [`Error::DerivedInstanceContextTooNarrow`].
29//!
30//! A recursive type asks for its own instance, and a group of types may ask for each
31//! other's, so the instances being derived count as in scope with the contexts being
32//! inferred, and the contexts are computed together as a fixed point: each starts empty
33//! and grows by what the others' contexts ask, until nothing grows. A written context is
34//! where its instance starts and stays. A context holds pairs of a class and one of the
35//! head's variables, and the classes that can appear in one are not only the derived one:
36//! a written or imported instance's context names whatever its parameters need, and that
37//! is followed too. The set of such pairs is finite, the classes in scope times the
38//! head's variables, so it stops. What the instance ends with is read off once more from
39//! scratch, which is what makes its order the order the type's arguments are written in
40//! and not the order the iteration happened to find them.
41//!
42//! # A derived instance is given its members
43//!
44//! The walk is written out as canonical code ([`Generated`]) and the instance carries it
45//! as bindings, where a written instance's would be. From there the typer checks them
46//! against the member's signature with the inferred context given, and nothing after
47//! canonicalization knows the instance was derived.
48//!
49//! The class's bindings are *placed*, not called
50//! ([*The bindings are inlined*](../../../docs/spec/type-classes.md#the-bindings-are-inlined-not-called)).
51//! `combine`'s first parameter is bound once, by a `case` of one branch whose scrutinee is
52//! the answer for one part, and its second is replaced by the rest of the walk, so that
53//! the rest is evaluated where the body reaches it and nowhere else
54//! ([`DEC-24` decision 8](../../../docs/decisions/dec-24.md#8--combines-first-parameter-is-a-value-and-its-second-is-the-rest-of-the-walk)).
55//! `matched`, `differed` and `atConstructor` are placed the same way, their parameters
56//! bound to the values the walk hands them.
57//!
58//! Three things make that safe.
59//!
60//! - **Capture.** The rest of the walk mentions the names the definition gave the
61//!   arguments, and a class author's binding may bind any name a source file can spell.
62//!   The names the definition gives are `$left`, `$right`, `$value`, `$a1`, `$b1`, and so
63//!   on, and every name a placed body binds is replaced by one of its own, `$3$x`: a `$`, a
64//!   serial and the name the class wrote. No source file can write a `$`, so no binding of
65//!   a class can bind one of these. What that makes true is that no generated binder is ever
66//!   in the scope of another binding of the same name, however many copies of a body nest in
67//!   each other. A name is still bound in more than one place: each alternative of a walk
68//!   binds `$a1`, `$b1` and so on in its own branch, and the rest of the walk is copied at
69//!   every mention of `combine`'s second parameter, carrying the names it binds with it. Those
70//!   are sibling scopes, in which nothing is captured. The JavaScript emitter leaves a name
71//!   that is not a reserved word as it is, so each is an identifier there, and none is a name
72//!   the emitter makes for itself: those are a `$` and a word (`$curry`), a `$` and digits,
73//!   and names with a package, `companion` or `is` as their first segment, where the first
74//!   segment of these is a serial.
75//! - **`Position` values.** A constructor's place in its declaration is a value of
76//!   `Basics.Position`, whose one constructor is exposed to no module. The definition
77//!   names it by [`scalars::POSITION`], the way the compiler names a scalar, and never
78//!   through scope.
79//! - **Spans.** A class's bindings were written in the class's file and the instance is in
80//!   another's, so a span carried over would point at unrelated text. Every node of a
81//!   generated definition, the placed bodies included, is given the span of the word
82//!   `derived`, which is where an error in one is blamed.
83//!
84//! What a placed body may name is what its home module exposes, and a body that names a
85//! value its home module does not expose is not checked where it is placed: the typer
86//! reads only what the module it checks imports, so such a binding is left unchecked, as
87//! one naming any other name the typer cannot read is.
88//!
89//! # What the code costs
90//!
91//! The rest of the walk is copied at every place `combine`'s body names its second
92//! parameter. A body that names it `k` times, in a constructor of `n` arguments, makes
93//! `k^n` copies of the rest, so the size of a derived member is exponential in a
94//! constructor's arity whenever `k` is more than one, and nothing here bounds it. At run
95//! time each path evaluates the rest at most once, which is what the rule asks; it is the
96//! generated code that is large. `LANG-88` tracks it.
97
98use super::classes::mentions;
99use super::environment::{Environment, RootEnvironment};
100use super::{
101    binding_value, CaseBranch, ClassSignature, Constraint, DeclarationSite, Derivation,
102    DerivationBindings, DerivationRole, Error, Expression, ExpressionKind, Field, HeadName,
103    InstanceHead, Member, Pattern, PatternField, PatternKind, Type, TypeConstructor, UnionType,
104    Value,
105};
106use crate::name::{Name, QualName};
107use crate::scalars;
108use std::cell::Cell;
109use std::collections::HashMap;
110use std::convert::TryFrom;
111use zelkova_syntax::parser;
112use zelkova_syntax::position::NodeSpan;
113use zelkova_syntax::tuple::Tuple;
114
115// ── The class side ───────────────────────────────────────────────────────────
116
117/// What is wrong with the signature of a member a derivation was written for — see
118/// [`Error::DerivationSignature`].
119#[derive(Debug, Clone, Copy, PartialEq, Eq)]
120pub enum DerivationSignatureProblem {
121    /// No parameter of the member holds the class variable: `bottom : a` and
122    /// `allValues : List a`. A derivation walks values of the type, and there is none to
123    /// walk, so it would have to build one from a description of the type's constructors.
124    NoClassValue,
125    /// The class variable is in the answer: `add : a -> a -> a`. The walk would be asked
126    /// for another value of the type it is walking.
127    ResultMentionsClassVariable,
128    /// Some other shape: a derivation is for `a -> a -> R` and `a -> R`.
129    Shape,
130}
131
132/// Which walk a member's signature gives its derivation, and the type it answers with.
133enum Walk {
134    /// `a -> a -> R`.
135    Pair(Type),
136    /// `a -> R`.
137    Single(Type),
138}
139
140/// The walk the signature `tpe` of a member of a class over `variable` admits, or why it
141/// admits none.
142fn walk_of(tpe: &Type, variable: &Name) -> Result<Walk, DerivationSignatureProblem> {
143    let is_class_variable = |tpe: &Type| matches!(tpe, Type::Variable(name) if name == variable);
144
145    if let Type::Arrow(first, rest) = tpe {
146        if is_class_variable(first) {
147            if let Type::Arrow(second, result) = rest.as_ref() {
148                if is_class_variable(second) && !mentions(result, variable) {
149                    return Ok(Walk::Pair(result.as_ref().clone()));
150                }
151            }
152            if !mentions(rest, variable) {
153                return Ok(Walk::Single(rest.as_ref().clone()));
154            }
155        }
156    }
157
158    let mut parameters = Vec::new();
159    let mut result = tpe;
160    while let Type::Arrow(parameter, rest) = result {
161        parameters.push(parameter.as_ref());
162        result = rest;
163    }
164
165    Err(
166        if !parameters
167            .iter()
168            .any(|parameter| mentions(parameter, variable))
169        {
170            DerivationSignatureProblem::NoClassValue
171        } else if mentions(result, variable) {
172            DerivationSignatureProblem::ResultMentionsClassVariable
173        } else {
174            DerivationSignatureProblem::Shape
175        },
176    )
177}
178
179/// The names a derivation's bindings are written under for `walk`, in the order the
180/// chapter lists them.
181fn required(walk: &Walk) -> &'static [DerivationRole] {
182    match walk {
183        Walk::Pair(_) => &[
184            DerivationRole::Matched,
185            DerivationRole::Differed,
186            DerivationRole::Combine,
187        ],
188        Walk::Single(_) => &[DerivationRole::AtConstructor, DerivationRole::Combine],
189    }
190}
191
192/// The derivations of `class`, each held to the rules a derivation follows, and every error
193/// of the ones that do not pass.
194///
195/// `signature` is `class` as `class_signature` built it, so the members are known. Every
196/// binding of every derivation is canonicalized, a derivation that fails its checks
197/// included, so that a name one cannot resolve is reported whatever else is wrong with it;
198/// every such name is pushed onto `unresolved`.
199///
200/// A derivation that fails is left out of what comes back, and its member is one the class
201/// does not derive. A class that derives some of its members and not all is its own
202/// error, naming the ones left out ([`Error::DerivationIncomplete`]); a member whose
203/// derivation is there and failed is not named in it, since that derivation has its own.
204pub(super) fn class_derivations(
205    env: &RootEnvironment,
206    class: &parser::ClassDecl,
207    class_name: &Name,
208    signature: &ClassSignature,
209    unresolved: &mut Vec<Error>,
210) -> (Vec<Derivation>, Vec<Error>) {
211    let mut errors = Vec::new();
212    let mut derivations: Vec<Derivation> = Vec::new();
213    // The span of the first derivation written for each member, valid or not.
214    let mut first: HashMap<&Name, NodeSpan> = HashMap::new();
215
216    for derivation in class.members.iter().filter_map(|member| match member {
217        parser::ClassMember::Derivation(derivation) => Some(derivation),
218        parser::ClassMember::Signature(_) => None,
219    }) {
220        // Every binding is read, so that what it names is resolved and reported. A binding
221        // that did not canonicalize is a binding that was written: its name is kept, so
222        // the derivation is not also reported as missing it.
223        let mut bindings: Vec<(&parser::FunBinding, Option<Value>)> = Vec::new();
224        for binding in &derivation.bindings {
225            match binding_value(env, binding, unresolved) {
226                Ok(value) => bindings.push((binding, Some(value))),
227                Err(error) => {
228                    errors.push(error);
229                    bindings.push((binding, None));
230                }
231            }
232        }
233
234        let Some(member) = signature
235            .members
236            .iter()
237            .find(|member| member.name == derivation.member)
238        else {
239            errors.push(Error::DerivationForNonMember(
240                derivation.member.clone(),
241                class_name.clone(),
242                derivation.span,
243            ));
244            continue;
245        };
246
247        if let Some(earlier) = first.get(&derivation.member) {
248            errors.push(Error::DerivationRepeated(
249                derivation.member.clone(),
250                derivation.span,
251                *earlier,
252            ));
253            continue;
254        }
255        first.insert(&derivation.member, derivation.span);
256
257        let walk = match walk_of(&member.tpe, &signature.variable) {
258            Ok(walk) => walk,
259            Err(problem) => {
260                errors.push(Error::DerivationSignature(
261                    derivation.member.clone(),
262                    problem,
263                    derivation.span,
264                    member.span,
265                ));
266                continue;
267            }
268        };
269
270        let before = errors.len();
271        let mut found: HashMap<DerivationRole, Value> = HashMap::new();
272        let mut written: HashMap<DerivationRole, NodeSpan> = HashMap::new();
273        let mut failed: Vec<DerivationRole> = Vec::new();
274
275        for (binding, value) in bindings {
276            let Some(role) = required(&walk)
277                .iter()
278                .find(|role| role.name() == binding.name.as_str())
279            else {
280                errors.push(Error::DerivationBindingUnexpected(
281                    binding.name.clone(),
282                    derivation.member.clone(),
283                    required(&walk)
284                        .iter()
285                        .map(|role| Name::new(role.name()))
286                        .collect(),
287                    binding.span,
288                ));
289                continue;
290            };
291
292            if let Some(earlier) = written.get(role) {
293                errors.push(Error::DerivationBindingRepeated(
294                    binding.name.clone(),
295                    derivation.member.clone(),
296                    binding.span,
297                    *earlier,
298                ));
299                continue;
300            }
301            written.insert(*role, binding.span);
302
303            match value {
304                Some(value) => {
305                    if value.arity() > role.parameters() {
306                        errors.push(Error::DerivationBindingTakesTooMany(
307                            binding.name.clone(),
308                            derivation.member.clone(),
309                            role.parameters(),
310                            binding.span,
311                        ));
312                    } else {
313                        found.insert(*role, value);
314                    }
315                }
316                None => failed.push(*role),
317            }
318        }
319
320        for role in required(&walk) {
321            if !written.contains_key(role) {
322                errors.push(Error::DerivationBindingMissing(
323                    Name::new(role.name()),
324                    derivation.member.clone(),
325                    derivation.span,
326                ));
327            }
328        }
329
330        if errors.len() > before || !failed.is_empty() {
331            continue;
332        }
333
334        let bindings = match walk {
335            Walk::Pair(_) => match (
336                found.remove(&DerivationRole::Matched),
337                found.remove(&DerivationRole::Differed),
338                found.remove(&DerivationRole::Combine),
339            ) {
340                (Some(matched), Some(differed), Some(combine)) => DerivationBindings::Pair {
341                    matched: Box::new(matched),
342                    differed: Box::new(differed),
343                    combine: Box::new(combine),
344                },
345                _ => continue,
346            },
347            Walk::Single(_) => match (
348                found.remove(&DerivationRole::AtConstructor),
349                found.remove(&DerivationRole::Combine),
350            ) {
351                (Some(at_constructor), Some(combine)) => DerivationBindings::Single {
352                    at_constructor: Box::new(at_constructor),
353                    combine: Box::new(combine),
354                },
355                _ => continue,
356            },
357        };
358        let result = match walk {
359            Walk::Pair(result) | Walk::Single(result) => result,
360        };
361
362        derivations.push(Derivation {
363            member: derivation.member.clone(),
364            result,
365            bindings,
366            span: derivation.span,
367        });
368    }
369
370    // A class that derives some of its members and not the rest could only be half derived
371    // and half written.
372    let covered = signature
373        .members
374        .iter()
375        .filter(|member| first.contains_key(&member.name))
376        .count();
377    if covered > 0 && covered < signature.members.len() {
378        let left_out: Vec<Name> = signature
379            .members
380            .iter()
381            .filter(|member| !first.contains_key(&member.name))
382            .map(|member| member.name.clone())
383            .collect();
384        errors.push(Error::DerivationIncomplete(
385            class_name.clone(),
386            left_out,
387            class.span,
388        ));
389    }
390
391    (derivations, errors)
392}
393
394// ── The instance side ────────────────────────────────────────────────────────
395
396/// What is wrong with the type a `derived` instance is for, that it has no shape to walk —
397/// see [`Error::DerivedInstanceNoShape`].
398#[derive(Debug, Clone, PartialEq)]
399pub enum DerivedShapeProblem {
400    /// A [scalar type](../../docs/spec/types.md#scalar-types) has no shape for a walk to
401    /// read, so its instances are written: the type.
402    Scalar(Name),
403    /// A type whose constructors are not in scope — one imported without them: the type.
404    NoConstructors(Name),
405    /// `()` for a class with a member whose derivation walks one value, which has no
406    /// element to begin at: the class.
407    UnitHasNoElement(Name),
408}
409
410/// The part of a type a walk found an argument in: where a requirement of a derived
411/// instance came from.
412#[derive(Debug, Clone, PartialEq)]
413pub enum DerivedPart {
414    /// An argument of a variant of a union.
415    Variant(Name),
416    /// An element of a tuple, counting from one.
417    Element(usize),
418}
419
420/// An argument of a derived instance's type with no instance of the derived class — see
421/// [`Error::DerivedInstanceRequires`].
422#[derive(Debug, Clone, PartialEq)]
423pub struct DerivedRequirement {
424    /// The class being derived.
425    pub class: Name,
426    /// What the argument was found in.
427    pub part: DerivedPart,
428    /// The type of the argument, as written in the type's declaration.
429    pub argument: String,
430    /// The type that has no instance: the argument itself, or what an instance an
431    /// application of it needs asks for.
432    pub missing: String,
433    /// Whether `missing` is a function type, which no instance can be declared for.
434    pub function: bool,
435    /// Where the type being derived for was declared, when that is in this module.
436    pub declared: DeclarationSite,
437}
438
439/// A constraint a `derived` instance needs and the context written on it does not provide —
440/// see [`Error::DerivedInstanceContextTooNarrow`].
441#[derive(Debug, Clone, PartialEq)]
442pub struct DerivedContextGap {
443    /// The class being derived.
444    pub class: Name,
445    /// The constraint the context does not provide, as a context writes it: `Eq a`.
446    pub missing: String,
447    /// The first argument that needs it was found in this.
448    pub part: DerivedPart,
449    /// The type of that argument, as written in the type's declaration.
450    pub argument: String,
451}
452
453/// A `derived` instance of the module under check, as [`derive_all`] reads it.
454pub(super) struct Candidate<'a> {
455    /// The class being derived.
456    pub class: &'a QualName,
457    pub head: &'a InstanceHead,
458    /// The context written on the instance and where, when one is written and resolved.
459    pub context: Option<(&'a [Constraint], NodeSpan)>,
460    /// Where the word `derived` was written.
461    pub span: NodeSpan,
462}
463
464/// What a derived instance comes to: its context and its members.
465pub(super) struct Derived {
466    /// The context the instance wrote, when it wrote one. Otherwise the constraints the
467    /// instance needs of its head's variables, in the order the type's arguments are
468    /// written in, each once.
469    pub context: Vec<Constraint>,
470    /// One binding per member of the class, in the order the class declares them.
471    pub bindings: Vec<Value>,
472}
473
474/// What the walk of one derived instance reads: the alternatives a value may be and, for
475/// each, the types of its arguments.
476enum Shape<'a> {
477    /// A declared union and where it was declared, when that is the module under check.
478    Union(&'a UnionType, DeclarationSite),
479    /// A tuple of two or three elements.
480    Tuple(usize),
481    /// `()`.
482    Unit,
483}
484
485/// One way a value of a type may be built: a constructor of a union, or the one way a
486/// tuple or `()` is.
487struct Alternative<'a> {
488    /// The constructor, for a union.
489    constructor: Option<&'a TypeConstructor>,
490    /// How many arguments it has.
491    arity: usize,
492}
493
494impl Shape<'_> {
495    fn alternatives(&self) -> Vec<Alternative<'_>> {
496        match self {
497            Shape::Union(union, _) => union
498                .variants
499                .iter()
500                .map(|constructor| Alternative {
501                    constructor: Some(constructor),
502                    arity: constructor.type_parameters.len(),
503                })
504                .collect(),
505            Shape::Tuple(arity) => vec![Alternative {
506                constructor: None,
507                arity: *arity,
508            }],
509            Shape::Unit => vec![Alternative {
510                constructor: None,
511                arity: 0,
512            }],
513        }
514    }
515}
516
517/// An argument a derived instance's type holds, and what it asks.
518struct Requirement {
519    part: DerivedPart,
520    /// The argument's type, over the head's variables.
521    tpe: Type,
522}
523
524/// One derived instance, read for its shape and what that shape asks.
525struct Plan<'a> {
526    candidate: &'a Candidate<'a>,
527    shape: Shape<'a>,
528    requirements: Vec<Requirement>,
529}
530
531/// What an instance in scope needs of its head's variables.
532struct Known {
533    /// The head's variables, in the order the head writes them.
534    variables: Vec<Name>,
535    /// The constraints on them, each a class and a variable of the head.
536    context: Vec<(QualName, Name)>,
537}
538
539type Table = HashMap<(QualName, HeadName), Known>;
540
541/// An instance of the module under check as it is written: its class and head, and the
542/// context it writes of its own. A derived instance that writes none has an empty one here,
543/// which is where its inferred context starts.
544pub(super) struct WrittenInstance {
545    pub class: QualName,
546    pub head: InstanceHead,
547    pub context: Vec<(QualName, Name)>,
548}
549
550/// Derive every instance of `candidates`: the context each needs, and the members each is
551/// made of, or why it cannot be.
552///
553/// The answer is one entry per candidate, in order. `written` is every instance of the module
554/// with the context it writes, which an argument's type may need; the instances imported are
555/// read from `env`. An instance that has an error in its own right — `signature` has no derivation
556/// for it, the type has no shape — is one entry's errors, and is still counted as in scope
557/// for the others, so that one failure is not restated by every type that holds it.
558///
559/// `signature` is the class each candidate derives, as the module that declares it
560/// published it, or `None` when that declaration did not canonicalize and the error behind
561/// it has been reported.
562pub(super) fn derive_all<'a>(
563    env: &'a RootEnvironment,
564    candidates: &'a [Candidate<'a>],
565    signatures: &[Option<&ClassSignature>],
566    written: &[WrittenInstance],
567) -> Vec<Result<Derived, Vec<Error>>> {
568    let mut table: Table = HashMap::new();
569    for published in env.imported_instances() {
570        let signature = &published.signature;
571        table.insert(
572            (signature.class.clone(), signature.head.name()),
573            Known {
574                variables: signature.head.variables().into_iter().cloned().collect(),
575                context: signature
576                    .context
577                    .iter()
578                    .map(|constraint| (constraint.class.clone(), constraint.variable.clone()))
579                    .collect(),
580            },
581        );
582    }
583    for instance in written {
584        table.insert(
585            (instance.class.clone(), instance.head.name()),
586            Known {
587                variables: instance.head.variables().into_iter().cloned().collect(),
588                context: instance.context.clone(),
589            },
590        );
591    }
592    // Every candidate is in scope for the others, needing what it writes of its own and
593    // nothing more yet.
594    for candidate in candidates {
595        table
596            .entry((candidate.class.clone(), candidate.head.name()))
597            .or_insert_with(|| Known {
598                variables: candidate.head.variables().into_iter().cloned().collect(),
599                context: Vec::new(),
600            });
601    }
602
603    let plans: Vec<Result<Plan, Vec<Error>>> = candidates
604        .iter()
605        .zip(signatures)
606        .map(|(candidate, signature)| plan(env, candidate, *signature))
607        .collect();
608
609    // The fixed point. A context only grows, from nothing, by what an instance asks given
610    // every context as it stands. A written context is the whole of its instance's and does
611    // not grow.
612    loop {
613        let mut grown = false;
614
615        for plan in plans.iter().filter_map(|plan| plan.as_ref().ok()) {
616            if plan.candidate.context.is_some() {
617                continue;
618            }
619            let mut needed = Vec::new();
620            for requirement in &plan.requirements {
621                // A failure is the final pass's to report; here it asks nothing more.
622                let _ = reduce(&table, plan.candidate.class, &requirement.tpe, &mut needed);
623            }
624
625            let key = (plan.candidate.class.clone(), plan.candidate.head.name());
626            if let Some(known) = table.get_mut(&key) {
627                for constraint in needed {
628                    if !known.context.contains(&constraint) {
629                        known.context.push(constraint);
630                        grown = true;
631                    }
632                }
633            }
634        }
635
636        if !grown {
637            break;
638        }
639    }
640
641    plans
642        .into_iter()
643        .zip(signatures)
644        .map(|(plan, signature)| {
645            let plan = plan?;
646            let candidate = plan.candidate;
647
648            // What is read now is the context the fixed point reached, read from scratch.
649            let mut context: Vec<(QualName, Name)> = Vec::new();
650            let mut errors = Vec::new();
651            for requirement in &plan.requirements {
652                let read = context.len();
653                let reduced = reduce(&table, candidate.class, &requirement.tpe, &mut context);
654
655                // `context` holds each constraint once, so what this argument added is what
656                // no earlier argument asked, and a gap is reported at the first that needs it.
657                if let Some((written, written_span)) = candidate.context {
658                    for (class, variable) in &context[read..] {
659                        if !provides(env, written, class, variable) {
660                            errors.push(Error::DerivedInstanceContextTooNarrow(
661                                Box::new(DerivedContextGap {
662                                    class: candidate.class.unqualified_name(),
663                                    missing: format!("{} {}", class.unqualified_name(), variable),
664                                    part: requirement.part.clone(),
665                                    argument: type_text(&requirement.tpe),
666                                }),
667                                written_span,
668                                candidate.span,
669                            ));
670                        }
671                    }
672                }
673
674                if let Err(missing) = reduced {
675                    errors.push(Error::DerivedInstanceRequires(
676                        Box::new(DerivedRequirement {
677                            class: candidate.class.unqualified_name(),
678                            part: requirement.part.clone(),
679                            argument: type_text(&requirement.tpe),
680                            function: matches!(missing, Type::Arrow(..)),
681                            missing: type_text(&missing),
682                            declared: match &plan.shape {
683                                Shape::Union(_, declared) => *declared,
684                                Shape::Tuple(_) | Shape::Unit => DeclarationSite::Unknown,
685                            },
686                        }),
687                        candidate.span,
688                    ));
689                }
690            }
691            if !errors.is_empty() {
692                return Err(errors);
693            }
694
695            // A class that is not derivable stopped the plan, so there is a signature.
696            let Some(signature) = signature else {
697                return Err(Vec::new());
698            };
699            let bindings = Generated::new(env, candidate, &plan.shape, signature).members();
700
701            Ok(Derived {
702                context: match candidate.context {
703                    Some((written, _)) => written.to_vec(),
704                    None => context
705                        .into_iter()
706                        .map(|(class, variable)| Constraint {
707                            class,
708                            variable,
709                            span: candidate.span,
710                        })
711                        .collect(),
712                },
713                bindings,
714            })
715        })
716        .collect()
717}
718
719/// Whether `context` provides `class` of `variable`: it writes that constraint, or one on
720/// the same variable for a class `class` is a superclass of, however many classes away.
721///
722/// A class whose declaration is not in scope has no superclasses to follow here.
723fn provides(
724    env: &RootEnvironment,
725    context: &[Constraint],
726    class: &QualName,
727    variable: &Name,
728) -> bool {
729    let mut pending: Vec<&QualName> = context
730        .iter()
731        .filter(|constraint| &constraint.variable == variable)
732        .map(|constraint| &constraint.class)
733        .collect();
734    let mut seen: Vec<&QualName> = Vec::new();
735
736    while let Some(candidate) = pending.pop() {
737        if candidate == class {
738            return true;
739        }
740        if seen.contains(&candidate) {
741            continue;
742        }
743        seen.push(candidate);
744        if let Some(signature) = env.class_signature(candidate) {
745            pending.extend(
746                signature
747                    .superclasses
748                    .iter()
749                    .map(|superclass| &superclass.class),
750            );
751        }
752    }
753
754    false
755}
756
757/// Read one derived instance for its shape and what that shape asks, or say why it cannot
758/// be derived.
759///
760/// An empty list of errors is a failure already reported: the class's own declaration did
761/// not canonicalize, or the head's type did not.
762fn plan<'a>(
763    env: &'a RootEnvironment,
764    candidate: &'a Candidate<'a>,
765    signature: Option<&ClassSignature>,
766) -> Result<Plan<'a>, Vec<Error>> {
767    let Some(signature) = signature else {
768        return Err(Vec::new());
769    };
770
771    let class = candidate.class.unqualified_name();
772    if !signature.derivable() {
773        // A class whose derivations were rejected has said so where it is declared, and an
774        // instance asking to be derived does not say it again.
775        return Err(if signature.derivations_rejected {
776            Vec::new()
777        } else {
778            vec![Error::DerivedInstanceNotDerivable(class, candidate.span)]
779        });
780    }
781
782    let (shape, requirements) = match candidate.head {
783        InstanceHead::Type(name, variables) => {
784            if scalars::scalar_of(name).is_some() {
785                return Err(vec![Error::DerivedInstanceNoShape(
786                    DerivedShapeProblem::Scalar(name.unqualified_name()),
787                    candidate.span,
788                )]);
789            }
790
791            let Some(union) = env.find_union(name) else {
792                return Err(Vec::new());
793            };
794            if union.variants.is_empty() {
795                return Err(vec![Error::DerivedInstanceNoShape(
796                    DerivedShapeProblem::NoConstructors(name.unqualified_name()),
797                    candidate.span,
798                )]);
799            }
800
801            // The union's own variables stand for the head's, whatever it names them.
802            let renamed: HashMap<&Name, &Name> = union.variables.iter().zip(variables).collect();
803            let requirements = union
804                .variants
805                .iter()
806                .flat_map(|constructor| {
807                    let renamed = &renamed;
808                    constructor
809                        .type_parameters
810                        .iter()
811                        .map(move |tpe| Requirement {
812                            part: DerivedPart::Variant(constructor.name.clone()),
813                            tpe: rename(tpe, renamed),
814                        })
815                })
816                .collect();
817
818            let declared = if super::classes::declaring_module(name) == *env.module_name() {
819                DeclarationSite::InThisModule(union.span)
820            } else {
821                DeclarationSite::Unknown
822            };
823            (Shape::Union(union, declared), requirements)
824        }
825        InstanceHead::Tuple(tuple) => {
826            let requirements = tuple
827                .iter()
828                .enumerate()
829                .map(|(index, variable)| Requirement {
830                    part: DerivedPart::Element(index + 1),
831                    tpe: Type::Variable(variable.clone()),
832                })
833                .collect();
834            (Shape::Tuple(tuple.iter().count()), requirements)
835        }
836        InstanceHead::Unit => {
837            if signature.walks_one_value() {
838                return Err(vec![Error::DerivedInstanceNoShape(
839                    DerivedShapeProblem::UnitHasNoElement(class),
840                    candidate.span,
841                )]);
842            }
843            (Shape::Unit, Vec::new())
844        }
845    };
846
847    Ok(Plan {
848        candidate,
849        shape,
850        requirements,
851    })
852}
853
854/// `tpe` with each variable of `renamed` written as the variable it maps to.
855fn rename(tpe: &Type, renamed: &HashMap<&Name, &Name>) -> Type {
856    match tpe {
857        Type::Variable(name) => Type::Variable(
858            renamed
859                .get(name)
860                .map(|name| (*name).clone())
861                .unwrap_or_else(|| name.clone()),
862        ),
863        Type::Type(name, args) => Type::Type(
864            name.clone(),
865            args.iter().map(|arg| rename(arg, renamed)).collect(),
866        ),
867        Type::Record(fields) => Type::Record(
868            fields
869                .iter()
870                .map(|(label, tpe)| (label.clone(), rename(tpe, renamed)))
871                .collect(),
872        ),
873        Type::Arrow(parameter, result) => Type::Arrow(
874            Box::new(rename(parameter, renamed)),
875            Box::new(rename(result, renamed)),
876        ),
877        Type::Tuple(tuple) => Type::Tuple(tuple.map(|element| rename(element, renamed))),
878        Type::Unit => Type::Unit,
879    }
880}
881
882/// Reduce `class` required of `tpe` to what it asks of the variables of the instance being
883/// derived, added to `needed` as a class and a variable, each once. `Err` is the type that
884/// has no instance.
885///
886/// A variable is a constraint. A declared type, a tuple and `()` need the instance of
887/// their head, and what that instance's context asks of its variables is asked of the type's
888/// arguments in turn, which are smaller than the type. A function type has no instance, and
889/// a record is [accepted without being checked](../../../docs/tickets/lang-85.md), as the
890/// solver accepts an obligation at one.
891fn reduce(
892    table: &Table,
893    class: &QualName,
894    tpe: &Type,
895    needed: &mut Vec<(QualName, Name)>,
896) -> Result<(), Type> {
897    let (head, arguments): (HeadName, Vec<&Type>) = match tpe {
898        Type::Variable(variable) => {
899            let constraint = (class.clone(), variable.clone());
900            if !needed.contains(&constraint) {
901                needed.push(constraint);
902            }
903            return Ok(());
904        }
905        Type::Arrow(..) => return Err(tpe.clone()),
906        Type::Record(_) => return Ok(()),
907        Type::Type(name, arguments) => (HeadName::Type(name.clone()), arguments.iter().collect()),
908        Type::Tuple(Tuple::Two(first, second)) => (HeadName::TwoTuple, vec![first, second]),
909        Type::Tuple(Tuple::Three(first, second, third)) => {
910            (HeadName::ThreeTuple, vec![first, second, third])
911        }
912        Type::Unit => (HeadName::Unit, Vec::new()),
913    };
914
915    let Some(known) = table.get(&(class.clone(), head)) else {
916        return Err(tpe.clone());
917    };
918    if known.variables.len() != arguments.len() {
919        return Err(tpe.clone());
920    }
921
922    for (class, variable) in &known.context {
923        let Some(position) = known.variables.iter().position(|bound| bound == variable) else {
924            continue;
925        };
926        reduce(table, class, arguments[position], needed)?;
927    }
928
929    Ok(())
930}
931
932/// `tpe` as the source writes it, for a message.
933fn type_text(tpe: &Type) -> String {
934    fn go(tpe: &Type, nested: bool) -> String {
935        match tpe {
936            Type::Variable(name) => name.to_string(),
937            Type::Type(name, args) if args.is_empty() => name.unqualified_name().to_string(),
938            Type::Type(name, args) => {
939                let text = std::iter::once(name.unqualified_name().to_string())
940                    .chain(args.iter().map(|arg| go(arg, true)))
941                    .collect::<Vec<_>>()
942                    .join(" ");
943                if nested {
944                    format!("({})", text)
945                } else {
946                    text
947                }
948            }
949            Type::Arrow(parameter, result) => {
950                let text = format!("{} -> {}", go(parameter, true), go(result, false));
951                if nested {
952                    format!("({})", text)
953                } else {
954                    text
955                }
956            }
957            Type::Tuple(tuple) => format!(
958                "({})",
959                tuple
960                    .iter()
961                    .map(|element| go(element, false))
962                    .collect::<Vec<_>>()
963                    .join(", ")
964            ),
965            Type::Unit => "()".to_owned(),
966            Type::Record(fields) => format!(
967                "{{ {} }}",
968                fields
969                    .iter()
970                    .map(|(label, tpe)| format!("{} : {}", label, go(tpe, false)))
971                    .collect::<Vec<_>>()
972                    .join(", ")
973            ),
974        }
975    }
976
977    go(tpe, false)
978}
979
980// ── Generating the members ───────────────────────────────────────────────────
981
982/// The names a generated definition gives its parameters and the arguments it takes apart.
983/// Each starts with a `$`, which no source file can write and no class author's binding can
984/// therefore bind.
985const LEFT: &str = "$left";
986const RIGHT: &str = "$right";
987const VALUE: &str = "$value";
988
989fn left_argument(index: usize) -> Name {
990    Name::new(format!("$a{}", index + 1))
991}
992
993fn right_argument(index: usize) -> Name {
994    Name::new(format!("$b{}", index + 1))
995}
996
997/// The members of one derived instance, written out as canonical code.
998struct Generated<'a> {
999    /// Where the word `derived` was written: the span of every node generated.
1000    span: NodeSpan,
1001    shape: &'a Shape<'a>,
1002    class: &'a QualName,
1003    signature: &'a ClassSignature,
1004    /// Whether the class is declared in the module the instance is in, which decides how a
1005    /// member is named.
1006    class_here: bool,
1007    /// How many fresh names the instance's members have used: see [`Generated::fresh`].
1008    serial: Cell<usize>,
1009}
1010
1011/// What a placed body's names stand for: the fresh name each local the body bound has, and
1012/// the one local that is replaced by an expression.
1013#[derive(Clone, Default)]
1014struct Scope<'a> {
1015    renames: HashMap<Name, Name>,
1016    /// The second parameter of `combine`, and the rest of the walk it stands for.
1017    replaced: Option<(&'a Name, &'a Expression)>,
1018}
1019
1020impl<'a> Scope<'a> {
1021    /// `name`, bound again from here on, to `fresh`.
1022    fn rename(&mut self, name: &Name, fresh: Name) {
1023        self.renames.insert(name.clone(), fresh);
1024        // What a pattern binds is what the name means now, and not what it replaced.
1025        if matches!(self.replaced, Some((replaced, _)) if replaced == name) {
1026            self.replaced = None;
1027        }
1028    }
1029
1030    /// The fresh name `name` is bound to, or `name` where nothing here bound it.
1031    fn renamed(&self, name: &Name) -> Name {
1032        self.renames
1033            .get(name)
1034            .cloned()
1035            .unwrap_or_else(|| name.clone())
1036    }
1037}
1038
1039impl<'a> Generated<'a> {
1040    fn new(
1041        env: &RootEnvironment,
1042        candidate: &'a Candidate<'a>,
1043        shape: &'a Shape<'a>,
1044        signature: &'a ClassSignature,
1045    ) -> Generated<'a> {
1046        Generated {
1047            span: candidate.span,
1048            shape,
1049            class: candidate.class,
1050            signature,
1051            class_here: super::classes::declaring_module(candidate.class) == *env.module_name(),
1052            serial: Cell::new(0),
1053        }
1054    }
1055
1056    /// One definition per member of the class, in the order it declares them.
1057    fn members(&self) -> Vec<Value> {
1058        self.signature
1059            .members
1060            .iter()
1061            .filter_map(|member| {
1062                let derivation = self.signature.derivation(&member.name)?;
1063                Some(self.member(member, derivation))
1064            })
1065            .collect()
1066    }
1067
1068    fn member(&self, member: &Member, derivation: &Derivation) -> Value {
1069        let (parameters, body) = match &derivation.bindings {
1070            DerivationBindings::Pair {
1071                matched,
1072                differed,
1073                combine,
1074            } => (
1075                vec![LEFT, RIGHT],
1076                self.walk_pair(member, matched, differed, combine),
1077            ),
1078            DerivationBindings::Single {
1079                at_constructor,
1080                combine,
1081            } => (
1082                vec![VALUE],
1083                self.walk_single(member, at_constructor, combine),
1084            ),
1085        };
1086
1087        Value::Value {
1088            name: member.name.clone(),
1089            patterns: parameters
1090                .into_iter()
1091                .map(|name| self.pattern(PatternKind::Variable(Name::new(name))))
1092                .collect(),
1093            body,
1094            span: self.span,
1095        }
1096    }
1097
1098    /// The walk over two values: take the first apart, take the second apart, and fold the
1099    /// arguments of the pair when the two are of one constructor.
1100    fn walk_pair(
1101        &self,
1102        member: &Member,
1103        matched: &Value,
1104        differed: &Value,
1105        combine: &Value,
1106    ) -> Expression {
1107        let alternatives = self.shape.alternatives();
1108
1109        let branches = alternatives
1110            .iter()
1111            .enumerate()
1112            .map(|(index, alternative)| {
1113                let left_names: Vec<Name> = (0..alternative.arity).map(left_argument).collect();
1114                let right_names: Vec<Name> = (0..alternative.arity).map(right_argument).collect();
1115
1116                // The answer for each pair of arguments, folded right-nested onto what the
1117                // walk ends at when nothing told the two values apart.
1118                let mut rest = self.place(matched, Vec::new());
1119                for (left, right) in left_names.iter().zip(&right_names).rev() {
1120                    let answer = self.apply(
1121                        self.apply(self.member_reference(member), self.local(left)),
1122                        self.local(right),
1123                    );
1124                    rest = self.place_combine(combine, answer, rest);
1125                }
1126
1127                // The second value is the same constructor, or it is not and `differed`
1128                // answers for the pair, handed where each was declared.
1129                let mut same_or_not = vec![(
1130                    self.alternative_pattern(alternative, Some(&right_names)),
1131                    rest,
1132                )];
1133                for (other_index, other) in alternatives.iter().enumerate() {
1134                    if other_index != index {
1135                        same_or_not.push((
1136                            self.alternative_pattern(other, None),
1137                            self.place(
1138                                differed,
1139                                vec![self.position(index), self.position(other_index)],
1140                            ),
1141                        ));
1142                    }
1143                }
1144
1145                (
1146                    self.alternative_pattern(alternative, Some(&left_names)),
1147                    self.case(self.local_str(RIGHT), same_or_not),
1148                )
1149            })
1150            .collect();
1151
1152        self.case(self.local_str(LEFT), branches)
1153    }
1154
1155    /// The walk over one value: take it apart, and fold the answer for its constructor with
1156    /// the answer for each argument.
1157    fn walk_single(&self, member: &Member, at_constructor: &Value, combine: &Value) -> Expression {
1158        let alternatives = self.shape.alternatives();
1159
1160        let branches = alternatives
1161            .iter()
1162            .enumerate()
1163            .map(|(index, alternative)| {
1164                let names: Vec<Name> = (0..alternative.arity).map(left_argument).collect();
1165
1166                // `combine p (combine a1 (… an))`: the constructor's answer when it has
1167                // one, and each argument's, the last of them standing for the rest of the
1168                // walk where the one before it asks for it.
1169                let mut answers: Vec<Expression> = Vec::new();
1170                if alternative.constructor.is_some() {
1171                    answers.push(self.place(at_constructor, vec![self.position(index)]));
1172                }
1173                for name in &names {
1174                    answers.push(self.apply(self.member_reference(member), self.local(name)));
1175                }
1176
1177                let body = match answers.pop() {
1178                    Some(last) => answers.into_iter().rev().fold(last, |rest, answer| {
1179                        self.place_combine(combine, answer, rest)
1180                    }),
1181                    // A tuple or `()` with no element to begin at has no answer; a class
1182                    // that walks one value is not derived for `()`, and a tuple has
1183                    // elements, so this is not reached.
1184                    None => self.expression(ExpressionKind::Unit),
1185                };
1186
1187                (self.alternative_pattern(alternative, Some(&names)), body)
1188            })
1189            .collect();
1190
1191        self.case(self.local_str(VALUE), branches)
1192    }
1193
1194    /// The binding of the derivation placed for `arguments`: each parameter bound, by a
1195    /// `case` of one branch, to the argument it receives, and any argument beyond the
1196    /// parameters the binding was written with applied to the body.
1197    fn place(&self, binding: &Value, arguments: Vec<Expression>) -> Expression {
1198        let (patterns, body) = value_parts(binding);
1199
1200        let mut scope = Scope::default();
1201        let mut arguments = arguments.into_iter();
1202        let mut bound: Vec<(Pattern, Expression)> = Vec::new();
1203        for pattern in patterns {
1204            let Some(argument) = arguments.next() else {
1205                break;
1206            };
1207            bound.push((self.bind_pattern(pattern, &mut scope), argument));
1208        }
1209
1210        let applied = arguments.fold(self.rewrite(body, &scope), |function, argument| {
1211            self.apply(function, argument)
1212        });
1213
1214        self.bind(bound, applied)
1215    }
1216
1217    /// `combine` placed for the answer to one part and the rest of the walk.
1218    ///
1219    /// The first parameter is bound once, to the answer. The second is replaced by the
1220    /// rest, wherever the body names it and nowhere else, so that the rest is evaluated
1221    /// where the body reaches it. A binding written with fewer parameters is applied to
1222    /// what it did not bind, which makes the rest an argument as a call would.
1223    fn place_combine(&self, combine: &Value, answer: Expression, rest: Expression) -> Expression {
1224        let (patterns, body) = value_parts(combine);
1225        let mut scope = Scope::default();
1226
1227        match patterns.as_slice() {
1228            [] => self.apply(self.apply(self.rewrite(body, &scope), answer), rest),
1229            [first] => {
1230                let first = self.bind_pattern(first, &mut scope);
1231                let applied = self.apply(self.rewrite(body, &scope), rest);
1232                self.bind(vec![(first, answer)], applied)
1233            }
1234            [first, second, ..] => {
1235                let first = self.bind_pattern(first, &mut scope);
1236                match &second.kind {
1237                    PatternKind::Variable(name) => {
1238                        scope.replaced = Some((name, &rest));
1239                        let placed = self.rewrite(body, &scope);
1240                        self.bind(vec![(first, answer)], placed)
1241                    }
1242                    // The rest is never named, so it is never evaluated.
1243                    PatternKind::Anything => {
1244                        let placed = self.rewrite(body, &scope);
1245                        self.bind(vec![(first, answer)], placed)
1246                    }
1247                    // A pattern that takes the rest apart has to have it to do so.
1248                    _ => {
1249                        let second = self.bind_pattern(second, &mut scope);
1250                        let placed = self.rewrite(body, &scope);
1251                        self.bind(vec![(first, answer), (second, rest)], placed)
1252                    }
1253                }
1254            }
1255        }
1256    }
1257
1258    /// `body` under one `case` of one branch for each of `bound`, the first outermost.
1259    fn bind(&self, bound: Vec<(Pattern, Expression)>, body: Expression) -> Expression {
1260        bound
1261            .into_iter()
1262            .rev()
1263            .fold(body, |body, (pattern, scrutinee)| {
1264                self.case(scrutinee, vec![(pattern, body)])
1265            })
1266    }
1267
1268    // ── Rewriting a placed body ──────────────────────────────────────────────
1269
1270    /// A name for one variable a placed body binds, which no other binder of the instance
1271    /// shares: `$` and a serial, then the name the class wrote — `$3$x`.
1272    ///
1273    /// A body is placed once for every part the walk meets, and a part's body is placed
1274    /// inside the one before it, so copies of one body would each bind the same spelling
1275    /// inside the others' scope. No generated binder is ever in the scope of another binding
1276    /// of the same name, so generated code does not depend on how a later phase scopes a name
1277    /// that is bound again, which matters while the typer drops a shadowed outer binder when
1278    /// an inner scope ends (`BUG-49`). The same name is bound in more than one place all the same, since
1279    /// the rest of the walk is copied at each mention of `combine`'s second parameter; those
1280    /// are sibling scopes.
1281    fn fresh(&self, original: &Name) -> Name {
1282        let serial = self.serial.get();
1283        self.serial.set(serial + 1);
1284
1285        Name::new(format!("${}${}", serial, original))
1286    }
1287
1288    /// `pattern` as a placed body binds it: every node carries the span of `derived`, and
1289    /// every variable is a fresh one, which `scope` now maps the written name to.
1290    fn bind_pattern(&self, pattern: &Pattern, scope: &mut Scope) -> Pattern {
1291        let kind = match &pattern.kind {
1292            PatternKind::Variable(name) => {
1293                let fresh = self.fresh(name);
1294                scope.rename(name, fresh.clone());
1295                PatternKind::Variable(fresh)
1296            }
1297            PatternKind::Constructor { ctor, args } => PatternKind::Constructor {
1298                ctor: ctor.clone(),
1299                args: args
1300                    .iter()
1301                    .map(|arg| self.bind_pattern(arg, scope))
1302                    .collect(),
1303            },
1304            PatternKind::Tuple(tuple) => {
1305                PatternKind::Tuple(tuple.map(|element| self.bind_pattern(element, scope)))
1306            }
1307            PatternKind::Hole(args) => PatternKind::Hole(
1308                args.iter()
1309                    .map(|arg| self.bind_pattern(arg, scope))
1310                    .collect(),
1311            ),
1312            PatternKind::Record(fields) => PatternKind::Record(
1313                fields
1314                    .iter()
1315                    .map(|field| PatternField {
1316                        label: field.label.clone(),
1317                        label_span: self.span,
1318                        pattern: self.bind_pattern(&field.pattern, scope),
1319                    })
1320                    .collect(),
1321            ),
1322            kind @ (PatternKind::Anything
1323            | PatternKind::Int(_)
1324            | PatternKind::Float(_)
1325            | PatternKind::Char(_)
1326            | PatternKind::String(_)
1327            | PatternKind::Unit) => kind.clone(),
1328        };
1329
1330        self.pattern(kind)
1331    }
1332
1333    /// `expression` as it is placed here: every node carries the span of `derived`, a
1334    /// local is the fresh name `scope` gives it, and a reference to the local `scope`
1335    /// replaces is the expression it replaces it with.
1336    fn rewrite(&self, expression: &Expression, scope: &Scope) -> Expression {
1337        let again = |expression: &Expression| self.rewrite(expression, scope);
1338
1339        let kind = match &expression.kind {
1340            ExpressionKind::VarLocal(name) => match scope.replaced {
1341                Some((replaced, with)) if replaced == name => return with.clone(),
1342                _ => ExpressionKind::VarLocal(scope.renamed(name)),
1343            },
1344            ExpressionKind::Apply(function, argument) => {
1345                ExpressionKind::Apply(Box::new(again(function)), Box::new(again(argument)))
1346            }
1347            ExpressionKind::If(condition, then, otherwise) => ExpressionKind::If(
1348                Box::new(again(condition)),
1349                Box::new(again(then)),
1350                Box::new(again(otherwise)),
1351            ),
1352            ExpressionKind::Case(scrutinee, branches) => ExpressionKind::Case(
1353                Box::new(again(scrutinee)),
1354                branches
1355                    .iter()
1356                    .map(|branch| {
1357                        // A branch binds its own names, which shadow what the scope
1358                        // renames or replaces.
1359                        let mut inner = scope.clone();
1360                        let pattern = self.bind_pattern(&branch.pattern, &mut inner);
1361                        CaseBranch {
1362                            pattern,
1363                            expression: self.rewrite(&branch.expression, &inner),
1364                            span: self.span,
1365                        }
1366                    })
1367                    .collect(),
1368            ),
1369            ExpressionKind::Accessor(label, _) => {
1370                ExpressionKind::Accessor(label.clone(), self.span)
1371            }
1372            ExpressionKind::Access(record, label, _) => {
1373                ExpressionKind::Access(Box::new(again(record)), label.clone(), self.span)
1374            }
1375            ExpressionKind::Record(fields) => ExpressionKind::Record(
1376                fields
1377                    .iter()
1378                    .map(|field| self.rewrite_field(field, scope))
1379                    .collect(),
1380            ),
1381            ExpressionKind::Update(record, fields) => ExpressionKind::Update(
1382                Box::new(again(record)),
1383                fields
1384                    .iter()
1385                    .map(|field| self.rewrite_field(field, scope))
1386                    .collect(),
1387            ),
1388            ExpressionKind::Tuple(tuple) => ExpressionKind::Tuple(tuple.map(again)),
1389            kind @ (ExpressionKind::VarTopLevel(_)
1390            | ExpressionKind::VarKernel(_)
1391            | ExpressionKind::VarForeign(..)
1392            | ExpressionKind::VarConstructor(..)
1393            | ExpressionKind::Char(_)
1394            | ExpressionKind::String(_)
1395            | ExpressionKind::Int(_)
1396            | ExpressionKind::Float(_)
1397            | ExpressionKind::Unit
1398            | ExpressionKind::Hole) => kind.clone(),
1399        };
1400
1401        self.expression(kind)
1402    }
1403
1404    fn rewrite_field(&self, field: &Field, scope: &Scope) -> Field {
1405        Field {
1406            label: field.label.clone(),
1407            label_span: self.span,
1408            value: self.rewrite(&field.value, scope),
1409        }
1410    }
1411
1412    // ── Building code ────────────────────────────────────────────────────────
1413
1414    fn expression(&self, kind: ExpressionKind) -> Expression {
1415        Expression::new(self.span, kind)
1416    }
1417
1418    fn pattern(&self, kind: PatternKind) -> Pattern {
1419        Pattern::new(self.span, kind)
1420    }
1421
1422    fn local(&self, name: &Name) -> Expression {
1423        self.expression(ExpressionKind::VarLocal(name.clone()))
1424    }
1425
1426    fn local_str(&self, name: &str) -> Expression {
1427        self.local(&Name::new(name))
1428    }
1429
1430    fn apply(&self, function: Expression, argument: Expression) -> Expression {
1431        self.expression(ExpressionKind::Apply(
1432            Box::new(function),
1433            Box::new(argument),
1434        ))
1435    }
1436
1437    fn case(&self, scrutinee: Expression, branches: Vec<(Pattern, Expression)>) -> Expression {
1438        self.expression(ExpressionKind::Case(
1439            Box::new(scrutinee),
1440            branches
1441                .into_iter()
1442                .map(|(pattern, expression)| CaseBranch {
1443                    pattern,
1444                    expression,
1445                    span: self.span,
1446                })
1447                .collect(),
1448        ))
1449    }
1450
1451    /// A reference to `member`, which the module declaring the class names the way it names
1452    /// any value of its own, and every other module the way it names an imported one.
1453    fn member_reference(&self, member: &Member) -> Expression {
1454        let name = self.class.sibling(&member.name);
1455
1456        self.expression(if self.class_here {
1457            ExpressionKind::VarTopLevel(name)
1458        } else {
1459            ExpressionKind::VarForeign(name, self.class.package().clone(), member.tpe.clone())
1460        })
1461    }
1462
1463    /// The `Position` of the `index`th alternative of the type: the constructor of
1464    /// `Basics.Position`, which is exposed to no module and so is named by its
1465    /// declaration, applied to the place as an `Int`.
1466    fn position(&self, index: usize) -> Expression {
1467        let position = scalars::POSITION.qual_name();
1468        let int = scalars::INT.qual_name();
1469
1470        let constructor = self.expression(ExpressionKind::VarConstructor(
1471            position.sibling(&Name::new(scalars::POSITION.name)),
1472            Type::Arrow(
1473                Box::new(Type::Type(int, Vec::new())),
1474                Box::new(Type::Type(position, Vec::new())),
1475            ),
1476        ));
1477        // A place that does not fit an `Int` is a type with more constructors than a
1478        // module can declare.
1479        let place = i64::try_from(index).unwrap_or(i64::MAX);
1480
1481        self.apply(constructor, self.expression(ExpressionKind::Int(place)))
1482    }
1483
1484    /// The pattern for `alternative`, with each argument bound to the name of `names` or,
1485    /// with none, matching anything.
1486    fn alternative_pattern(&self, alternative: &Alternative, names: Option<&[Name]>) -> Pattern {
1487        let arguments: Vec<Pattern> = (0..alternative.arity)
1488            .map(|index| {
1489                self.pattern(match names.and_then(|names| names.get(index)) {
1490                    Some(name) => PatternKind::Variable(name.clone()),
1491                    None => PatternKind::Anything,
1492                })
1493            })
1494            .collect();
1495
1496        match alternative.constructor {
1497            Some(constructor) => self.pattern(PatternKind::Constructor {
1498                ctor: constructor.clone(),
1499                args: arguments,
1500            }),
1501            None => match tuple_of(arguments) {
1502                Ok(tuple) => self.pattern(PatternKind::Tuple(tuple)),
1503                Err(_) => self.pattern(PatternKind::Unit),
1504            },
1505        }
1506    }
1507}
1508
1509/// The patterns of `value` and its body, whichever form it was canonicalized as.
1510fn value_parts(value: &Value) -> (Vec<&Pattern>, &Expression) {
1511    match value {
1512        Value::Value { patterns, body, .. } => (patterns.iter().collect(), body),
1513        Value::TypedValue { patterns, body, .. } => {
1514            (patterns.iter().map(|(pattern, _)| pattern).collect(), body)
1515        }
1516    }
1517}
1518
1519/// `items` as a tuple of two or three, or handed back when it is neither.
1520fn tuple_of<T>(mut items: Vec<T>) -> Result<Tuple<T>, Vec<T>> {
1521    match items.len() {
1522        2 | 3 => {
1523            let third = if items.len() == 3 { items.pop() } else { None };
1524            match (items.pop(), items.pop(), third) {
1525                (Some(second), Some(first), Some(third)) => Ok(Tuple::three(first, second, third)),
1526                (Some(second), Some(first), None) => Ok(Tuple::two(first, second)),
1527                _ => Err(Vec::new()),
1528            }
1529        }
1530        _ => Err(items),
1531    }
1532}