Skip to main content

zelkova_compiler/canonical/
classes.rs

1//! What a `class` and an `instance` declaration are once canonicalized, and the checks
2//! [Type classes](../../../docs/spec/type-classes.md) holds each one to.
3//!
4//! A class is a name in the types namespace, and its members are values of the module
5//! that declares it. An instance has no name: it reaches another module through
6//! [`Interface::instances`](crate::Interface::instances), which every module re-publishes
7//! whole, so an instance is in scope everywhere its declaring module is reachable through
8//! imports, whatever any `exposing` list says.
9//!
10//! Nothing here type checks anything. A member's signature is canonicalized as a type; an
11//! instance's bindings and a derivation's are canonicalized as ordinary values. The typer
12//! reads an instance's bindings against the member signatures this module keeps
13//! (`typer::classes`), and a derivation's bindings against the types the chapter gives
14//! each (`typer::DerivationCheck`).
15//!
16//! A derivation is checked where it is written, in `canonical::derivation`, which is also
17//! where a `derived` instance is given its context and its members. This module holds the
18//! shapes it works in and the checks that do not depend on a derivation.
19
20use super::derivation::{derive_all, Candidate, Derived, WrittenInstance};
21use super::environment::{Environment, RootEnvironment};
22use super::{
23    binding_value, validate_context, Error, InstanceHeadProblem, NameTakenBy, Type, Value,
24};
25use crate::name::{Name, QualName};
26use crate::{ModuleName, SourceSpan, SpanLabel};
27use std::collections::{HashMap, HashSet};
28use zelkova_syntax::parser;
29use zelkova_syntax::position::NodeSpan;
30use zelkova_syntax::tuple::Tuple;
31
32/// A constraint: a class, resolved to its declaration, and the type variable it is on.
33///
34/// What a class head's superclasses, an instance's context and an annotation's context
35/// are made of.
36#[derive(Debug, Clone, PartialEq)]
37pub struct Constraint {
38    /// The class, named by the package and module that declared it.
39    pub class: QualName,
40    /// The type variable the class is required of.
41    pub variable: Name,
42    /// Where the constraint was written.
43    pub span: NodeSpan,
44}
45
46/// One member signature of a class: `compare : a -> a -> Order`.
47#[derive(Debug, Clone, PartialEq)]
48pub struct Member {
49    pub name: Name,
50    /// The signature as written, the class variable free in it. Outside the class the
51    /// member's type is this with the class's own constraint in front, which no
52    /// canonical [`Type`] can express; the class carries the constraint instead.
53    pub tpe: Type,
54    /// Where the signature was written.
55    pub span: NodeSpan,
56}
57
58/// What a class declares that another module can see: its members and superclasses, and the
59/// derivations it carries.
60///
61/// It is what [`Interface::classes`](crate::Interface::classes) carries for each class a
62/// module exposes, and what an importer checks an instance of that class against. The
63/// derivations are in it because a `derived` instance is usually written beside its type,
64/// in a module other than the class's, and its members are written out of the bindings
65/// there.
66#[derive(Debug, Clone, PartialEq)]
67pub struct ClassSignature {
68    /// The class variable, `a` in `class Comparable a where`.
69    pub variable: Name,
70    /// The superclasses, each a constraint on [`variable`](Self::variable).
71    pub superclasses: Vec<Constraint>,
72    /// The member signatures, in the order written.
73    pub members: Vec<Member>,
74    /// The derivations that passed every check, in the order written, at most one per
75    /// member. A derivation that did not is reported and is not here, so the member it
76    /// was for is one this class does not [derive](Self::derivable).
77    pub derivations: Vec<Derivation>,
78    /// Whether the module that declares the class rejected one of its derivations: one
79    /// did not pass the checks a derivation is held to, the class derives some of its
80    /// members and not the rest, or the type checker rejected one's binding. That module
81    /// has reported why, so an instance asking to be derived is not told again that the
82    /// class is not derivable, and a derived instance's members do not report the type
83    /// error a second time.
84    pub derivations_rejected: bool,
85    /// Where the head line was written, `class` through `where`.
86    pub span: NodeSpan,
87}
88
89impl ClassSignature {
90    /// The derivation of `member`, when it has one.
91    pub fn derivation(&self, member: &Name) -> Option<&Derivation> {
92        self.derivations
93            .iter()
94            .find(|derivation| &derivation.member == member)
95    }
96
97    /// Whether an instance of this class may be
98    /// [derived](../../docs/spec/type-classes.md#a-class-says-how-it-is-derived): every
99    /// member carries a derivation. A class with no member has nothing to derive and is
100    /// not.
101    pub fn derivable(&self) -> bool {
102        !self.members.is_empty()
103            && self
104                .members
105                .iter()
106                .all(|member| self.derivation(&member.name).is_some())
107    }
108
109    /// Whether some member's derivation walks one value, which a `()` has no element to
110    /// begin at.
111    pub fn walks_one_value(&self) -> bool {
112        self.derivations
113            .iter()
114            .any(|derivation| matches!(derivation.bindings, DerivationBindings::Single { .. }))
115    }
116}
117
118/// A `class` declaration of the module under check.
119#[derive(Debug, PartialEq)]
120pub struct Class {
121    pub signature: ClassSignature,
122}
123
124/// A derivation in a class body, once it has passed the checks a derivation is held to:
125/// `derived eq` and the bindings under it.
126#[derive(Debug, Clone, PartialEq)]
127pub struct Derivation {
128    /// The member it is for.
129    pub member: Name,
130    /// `R`, the type the member answers with: what `matched`, `atConstructor` and
131    /// `combine` produce, and the type of the member's signature once its class-variable
132    /// parameters are taken off.
133    pub result: Type,
134    /// The bindings the member's signature calls for, canonicalized as ordinary values.
135    pub bindings: DerivationBindings,
136    /// Where `derived name` was written.
137    pub span: NodeSpan,
138}
139
140/// The bindings of a derivation. Which three or two there are is decided by the member's
141/// signature, and each is held in its own field so that none can be missing. Each is
142/// boxed, for the reason a `Value` is large.
143#[derive(Debug, Clone, PartialEq)]
144pub enum DerivationBindings {
145    /// A derivation over two values, for a member at `a -> a -> R`.
146    Pair {
147        matched: Box<Value>,
148        differed: Box<Value>,
149        combine: Box<Value>,
150    },
151    /// A derivation over one value, for a member at `a -> R`.
152    Single {
153        at_constructor: Box<Value>,
154        combine: Box<Value>,
155    },
156}
157
158/// Which binding of a derivation a value is. The type each has is the one
159/// [the chapter](../../docs/spec/type-classes.md#a-class-says-how-it-is-derived)
160/// gives it, over [`Derivation::result`] and `Position`.
161#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
162pub enum DerivationRole {
163    /// `matched : R`.
164    Matched,
165    /// `differed : Position -> Position -> R`.
166    Differed,
167    /// `atConstructor : Position -> R`.
168    AtConstructor,
169    /// `combine : R -> R -> R`.
170    Combine,
171}
172
173impl DerivationRole {
174    /// The name the binding is written under.
175    pub fn name(&self) -> &'static str {
176        match self {
177            DerivationRole::Matched => "matched",
178            DerivationRole::Differed => "differed",
179            DerivationRole::AtConstructor => "atConstructor",
180            DerivationRole::Combine => "combine",
181        }
182    }
183
184    /// How many parameters the binding may be written with: the arguments the walk
185    /// supplies it. A binding written with fewer is applied to the rest, and one written
186    /// with more would need a function to be built from the walk, which canonical code
187    /// has no form for.
188    pub fn parameters(&self) -> usize {
189        match self {
190            DerivationRole::Matched => 0,
191            DerivationRole::AtConstructor => 1,
192            DerivationRole::Differed | DerivationRole::Combine => 2,
193        }
194    }
195}
196
197impl DerivationBindings {
198    /// Every binding with its role, in the order the chapter lists them.
199    pub fn roles(&self) -> Vec<(DerivationRole, &Value)> {
200        match self {
201            DerivationBindings::Pair {
202                matched,
203                differed,
204                combine,
205            } => vec![
206                (DerivationRole::Matched, matched.as_ref()),
207                (DerivationRole::Differed, differed.as_ref()),
208                (DerivationRole::Combine, combine.as_ref()),
209            ],
210            DerivationBindings::Single {
211                at_constructor,
212                combine,
213            } => vec![
214                (DerivationRole::AtConstructor, at_constructor.as_ref()),
215                (DerivationRole::Combine, combine.as_ref()),
216            ],
217        }
218    }
219}
220
221/// The type an instance is for: a declared type applied to distinct variables, one per
222/// parameter; a tuple of distinct variables; or `()`.
223#[derive(Debug, Clone, PartialEq, Eq, Hash)]
224pub enum InstanceHead {
225    /// A declared type, named by its declaration, and the variables it is applied to.
226    Type(QualName, Vec<Name>),
227    Tuple(Tuple<Name>),
228    Unit,
229}
230
231impl InstanceHead {
232    /// The name at the front of the head, which together with the class is what
233    /// identifies an instance.
234    pub fn name(&self) -> HeadName {
235        match self {
236            InstanceHead::Type(name, _) => HeadName::Type(name.clone()),
237            InstanceHead::Tuple(Tuple::Two(..)) => HeadName::TwoTuple,
238            InstanceHead::Tuple(Tuple::Three(..)) => HeadName::ThreeTuple,
239            InstanceHead::Unit => HeadName::Unit,
240        }
241    }
242
243    /// The variables the head binds, in the order written.
244    pub fn variables(&self) -> Vec<&Name> {
245        match self {
246            InstanceHead::Type(_, variables) => variables.iter().collect(),
247            InstanceHead::Tuple(tuple) => tuple.iter().collect(),
248            InstanceHead::Unit => Vec::new(),
249        }
250    }
251}
252
253/// The name at the front of an [`InstanceHead`]. Two instances of one class whose heads
254/// share it are one instance declared twice.
255#[derive(Debug, Clone, PartialEq, Eq, Hash)]
256pub enum HeadName {
257    Type(QualName),
258    TwoTuple,
259    ThreeTuple,
260    Unit,
261}
262
263impl HeadName {
264    /// The head in the words of the source, for a message.
265    pub fn describe(&self) -> String {
266        match self {
267            HeadName::Type(name) => format!("`{}`", name.unqualified_name()),
268            HeadName::TwoTuple => "a tuple of two".to_owned(),
269            HeadName::ThreeTuple => "a tuple of three".to_owned(),
270            HeadName::Unit => "`()`".to_owned(),
271        }
272    }
273
274    /// The module that declares the head's type, when one does. A tuple and `()` are
275    /// declared in no module.
276    pub fn module(&self) -> Option<ModuleName> {
277        match self {
278            HeadName::Type(name) => Some(declaring_module(name)),
279            HeadName::TwoTuple | HeadName::ThreeTuple | HeadName::Unit => None,
280        }
281    }
282}
283
284/// What identifies an instance: its class, and the name at the front of its head.
285#[derive(Debug, Clone, PartialEq)]
286pub struct InstanceName {
287    pub class: QualName,
288    pub head: HeadName,
289}
290
291/// What an instance declares that another module can see: everything but its body.
292#[derive(Debug, Clone, PartialEq)]
293pub struct InstanceSignature {
294    /// The class, named by the package and module that declared it.
295    pub class: QualName,
296    pub head: InstanceHead,
297    /// What the instance needs of the head's variables, each on a variable the head
298    /// binds: the constraints written in front of its `=>`, and, for a derived instance
299    /// that writes none, the ones inferred from what the type holds
300    /// ([*What a derived instance requires*](../../docs/spec/type-classes.md#what-a-derived-instance-requires)).
301    pub context: Vec<Constraint>,
302    /// The module that declared the instance. An instance that reaches a module by two
303    /// routes is recognised as one by it.
304    pub module: ModuleName,
305    /// Where the head line was written, `instance` through `where`, in the declaring
306    /// module's source.
307    pub span: NodeSpan,
308}
309
310/// An `instance` declaration of the module under check.
311///
312/// A derived instance is one with the bindings its class's derivation stands for. Past this
313/// point it is read like a written one, bar [`derived`](Self::derived), which says only that
314/// its bindings are generated.
315#[derive(Debug, PartialEq)]
316pub struct Instance {
317    pub signature: InstanceSignature,
318    /// Whether the body is the word `derived`. The type checker reads it for one purpose:
319    /// an error in a binding generated out of a derivation the class's module rejected is
320    /// that derivation's error, reported where it was written.
321    pub derived: bool,
322    /// One binding per member, each canonicalized as an ordinary value. For a written
323    /// instance they are in the order written, and a binding that did not canonicalize
324    /// is left out and its error reported. For a derived one they are the members of
325    /// the class in the order it declares them, each generated out of the class's
326    /// derivation, and every node of one carries the span of the word `derived`.
327    pub bindings: Vec<Value>,
328}
329
330/// An instance as an [`Interface`](crate::Interface) publishes it: its signature, and
331/// where it was written when the interface that first published it knew its file.
332#[derive(Debug, Clone, PartialEq)]
333pub struct PublishedInstance {
334    pub signature: InstanceSignature,
335    pub source: Option<SourceSpan>,
336}
337
338impl PublishedInstance {
339    /// Whether `self` and `other` are the same declaration, reached by two routes.
340    pub(crate) fn same_declaration(&self, other: &PublishedInstance) -> bool {
341        self.signature.class == other.signature.class
342            && self.signature.head.name() == other.signature.head.name()
343            && self.signature.module == other.signature.module
344    }
345}
346
347/// Where a declaration an error refers to was written: in the module under check, in an
348/// imported module whose file is known, or somewhere no label can honestly point at.
349#[derive(Debug, Clone, Copy, PartialEq)]
350pub enum DeclarationSite {
351    InThisModule(NodeSpan),
352    InImportedModule(SourceSpan),
353    Unknown,
354}
355
356impl DeclarationSite {
357    /// A secondary label under the declaration, when there is somewhere to put one.
358    pub fn label(&self, message: String) -> Option<SpanLabel> {
359        match self {
360            DeclarationSite::InThisModule(span) => span.span().map(|span| SpanLabel {
361                span,
362                message,
363                primary: false,
364                file: None,
365            }),
366            DeclarationSite::InImportedModule(source) => Some(SpanLabel {
367                span: source.span,
368                message,
369                primary: false,
370                file: Some(source.file),
371            }),
372            DeclarationSite::Unknown => None,
373        }
374    }
375}
376
377/// The module `name` is declared in.
378pub(crate) fn declaring_module(name: &QualName) -> ModuleName {
379    ModuleName::new(name.package().clone(), name.module_name())
380}
381
382/// The class name and variable of a class head shaped `Comparable a`, or `None` for a
383/// head shaped any other way.
384fn class_head(head: &parser::Type) -> Option<(&Name, &Name)> {
385    let parser::TypeKind::Unqualified(name, args) = &head.kind else {
386        return None;
387    };
388
389    match args.as_slice() {
390        [parser::Type {
391            kind: parser::TypeKind::Variable(variable),
392            ..
393        }] => Some((name, variable)),
394        _ => None,
395    }
396}
397
398/// The member names a class declaration writes, each with where its signature was
399/// written, in source order. Read off the declaration as parsed, so a class that fails
400/// to canonicalize still says which names it would have declared.
401pub(super) fn member_names(class: &parser::ClassDecl) -> impl Iterator<Item = (&Name, NodeSpan)> {
402    class.members.iter().filter_map(|member| match member {
403        parser::ClassMember::Signature(signature) => Some((&signature.name, signature.span)),
404        parser::ClassMember::Derivation(_) => None,
405    })
406}
407
408/// Register the name of every class `classes` declares in `env`, so a superclass or an
409/// instance can name one written further down the file.
410///
411/// A class whose head is not a name applied to one variable, and one whose name a type
412/// or an earlier class of the module already has, is reported and not registered. What
413/// comes back is the index in `classes` of each class that was, with its name and
414/// variable, beside the errors.
415pub(super) fn declare_classes<'a>(
416    env: &mut RootEnvironment,
417    classes: &'a [parser::ClassDecl],
418    types: &[parser::UnionType],
419) -> (Vec<(usize, &'a Name, &'a Name)>, Vec<Error>) {
420    let mut declared: Vec<(usize, &Name, &Name)> = Vec::new();
421    let mut first: HashMap<&Name, NodeSpan> = HashMap::new();
422    let mut errors = Vec::new();
423
424    for (index, class) in classes.iter().enumerate() {
425        let Some((name, variable)) = class_head(&class.head) else {
426            errors.push(Error::InvalidClassHead(class.head.span));
427            continue;
428        };
429
430        if let Some(tpe) = types.iter().find(|tpe| &tpe.name == name) {
431            errors.push(Error::ClassNameTaken(
432                name.clone(),
433                NameTakenBy::Type,
434                class.span,
435                tpe.span,
436            ));
437            continue;
438        }
439
440        if let Some(earlier) = first.get(name) {
441            errors.push(Error::ClassNameTaken(
442                name.clone(),
443                NameTakenBy::Class,
444                class.span,
445                *earlier,
446            ));
447            continue;
448        }
449
450        first.insert(name, class.span);
451        env.insert_declared_class(name);
452        declared.push((index, name, variable));
453    }
454
455    (declared, errors)
456}
457
458/// The signature of `class`, a class `declare_classes` registered as `name` over
459/// `variable`, or every error that kept it from having one.
460pub(super) fn class_signature(
461    env: &RootEnvironment,
462    class: &parser::ClassDecl,
463    name: &Name,
464    variable: &Name,
465) -> Result<ClassSignature, Vec<Error>> {
466    let mut errors = Vec::new();
467
468    let superclasses = match constraints(
469        env,
470        class.context.as_ref(),
471        &[variable],
472        Error::ConstraintVariableUnbound,
473    ) {
474        Ok(superclasses) => superclasses,
475        Err(context_errors) => {
476            errors.extend(context_errors);
477            Vec::new()
478        }
479    };
480
481    let mut members = Vec::new();
482    let mut first: HashMap<&Name, NodeSpan> = HashMap::new();
483
484    for member in class.members.iter() {
485        let parser::ClassMember::Signature(signature) = member else {
486            continue;
487        };
488
489        if let Some(earlier) = first.get(&signature.name) {
490            errors.push(Error::MemberDeclaredTwice(
491                signature.name.clone(),
492                signature.span,
493                *earlier,
494            ));
495            continue;
496        }
497        first.insert(&signature.name, signature.span);
498
499        if let Some(context) = &signature.context {
500            errors.push(Error::MemberConstrained(
501                signature.name.clone(),
502                context.span,
503            ));
504        }
505
506        if signature.marked_unsafe {
507            errors.push(Error::MemberUnsafe(signature.name.clone(), signature.span));
508        }
509
510        match Type::from_parser_type(env, &signature.tpe) {
511            Ok(tpe) if !mentions(&tpe, variable) => {
512                errors.push(Error::MemberMissesClassVariable(
513                    signature.name.clone(),
514                    name.clone(),
515                    variable.clone(),
516                    signature.span,
517                ));
518            }
519            Ok(tpe) => members.push(Member {
520                name: signature.name.clone(),
521                tpe,
522                span: signature.span,
523            }),
524            Err(error) => errors.push(error),
525        }
526    }
527
528    if errors.is_empty() {
529        Ok(ClassSignature {
530            variable: variable.clone(),
531            superclasses,
532            members,
533            derivations: Vec::new(),
534            derivations_rejected: false,
535            span: class.span,
536        })
537    } else {
538        Err(errors)
539    }
540}
541
542/// Whether the type variable `variable` occurs anywhere in `tpe`.
543pub(super) fn mentions(tpe: &Type, variable: &Name) -> bool {
544    match tpe {
545        Type::Variable(name) => name == variable,
546        Type::Type(_, args) => args.iter().any(|arg| mentions(arg, variable)),
547        Type::Record(fields) => fields.values().any(|field| mentions(field, variable)),
548        Type::Arrow(param, result) => mentions(param, variable) || mentions(result, variable),
549        Type::Tuple(tuple) => tuple.iter().any(|element| mentions(element, variable)),
550        Type::Unit => false,
551    }
552}
553
554/// Every type variable `tpe` mentions, each once, in the order first written.
555///
556/// Read off the type as parsed, so an annotation's context can be checked against its
557/// type whether or not the type itself canonicalizes.
558pub(super) fn written_variables(tpe: &parser::Type) -> Vec<&Name> {
559    fn walk<'a>(tpe: &'a parser::Type, into: &mut Vec<&'a Name>) {
560        match &tpe.kind {
561            parser::TypeKind::Variable(name) => {
562                if !into.contains(&name) {
563                    into.push(name);
564                }
565            }
566            parser::TypeKind::Unqualified(_, args) => args.iter().for_each(|arg| walk(arg, into)),
567            parser::TypeKind::Arrow(param, result) => {
568                walk(param, into);
569                walk(result, into);
570            }
571            parser::TypeKind::Tuple(tuple) => tuple.iter().for_each(|element| walk(element, into)),
572            parser::TypeKind::Record(fields) => {
573                fields.iter().for_each(|field| walk(&field.value, into))
574            }
575            parser::TypeKind::Unit => {}
576        }
577    }
578
579    let mut variables = Vec::new();
580    walk(tpe, &mut variables);
581    variables
582}
583
584/// The constraints `context` writes, each resolved to a class and checked to be on one
585/// of `bound`: the variables the head it stands in front of binds, or the variables the
586/// type of the annotation it stands in front of mentions.
587///
588/// A constraint on a variable outside `bound` is reported as `unbound` builds it, from
589/// the variable and where it was written, since what the variable is missing from is
590/// the caller's to say. Every bad constraint of the context is reported, each at its
591/// own span.
592pub(super) fn constraints(
593    env: &RootEnvironment,
594    context: Option<&parser::Context>,
595    bound: &[&Name],
596    unbound: fn(Name, NodeSpan) -> Error,
597) -> Result<Vec<Constraint>, Vec<Error>> {
598    let Some(context) = context else {
599        return Ok(Vec::new());
600    };
601
602    let shaped = validate_context(context)?;
603    let mut constraints = Vec::new();
604    let mut errors = Vec::new();
605
606    for ((class, args), written) in shaped.into_iter().zip(context.constraints.iter()) {
607        let resolved = env.find_class(class).cloned();
608        if resolved.is_none() {
609            errors.push(Error::ClassNotFound(class.clone(), written.span));
610        }
611
612        let variable = match args {
613            [parser::Type {
614                kind: parser::TypeKind::Variable(variable),
615                span,
616            }] => {
617                if bound.contains(&variable) {
618                    Some(variable.clone())
619                } else {
620                    errors.push(unbound(variable.clone(), *span));
621                    None
622                }
623            }
624            _ => {
625                errors.push(Error::ConstraintNotOnVariable(written.span));
626                None
627            }
628        };
629
630        if let (Some(class), Some(variable)) = (resolved, variable) {
631            constraints.push(Constraint {
632                class,
633                variable,
634                span: written.span,
635            });
636        }
637    }
638
639    if errors.is_empty() {
640        Ok(constraints)
641    } else {
642        Err(errors)
643    }
644}
645
646/// The class and the head `instance` names, or every error that kept them from
647/// resolving.
648fn instance_head(
649    env: &RootEnvironment,
650    instance: &parser::InstanceDecl,
651) -> Result<(QualName, InstanceHead), Vec<Error>> {
652    let head = &instance.head;
653    let parser::TypeKind::Unqualified(class, args) = &head.kind else {
654        return Err(vec![Error::InvalidInstanceHead(
655            InstanceHeadProblem::NotAClass,
656            head.span,
657        )]);
658    };
659
660    let [argument] = args.as_slice() else {
661        return Err(vec![Error::InvalidInstanceHead(
662            InstanceHeadProblem::ClassApplied(args.len()),
663            head.span,
664        )]);
665    };
666
667    let mut errors = Vec::new();
668    let written = class;
669    let class = env.find_class(written).cloned();
670    if class.is_none() {
671        errors.push(Error::ClassNotFound(written.clone(), head.span));
672    }
673
674    let tpe = instance_head_type(env, argument);
675    match (class, tpe) {
676        (Some(class), Ok(tpe)) if errors.is_empty() => Ok((class, tpe)),
677        (_, tpe) => {
678            errors.extend(tpe.err().into_iter().flatten());
679            Err(errors)
680        }
681    }
682}
683
684/// The type an instance head applies its class to, held to the three forms a head may
685/// take.
686fn instance_head_type(
687    env: &RootEnvironment,
688    argument: &parser::Type,
689) -> Result<InstanceHead, Vec<Error>> {
690    match &argument.kind {
691        parser::TypeKind::Unqualified(name, args) => {
692            let Some(declared) = env.find_type(name) else {
693                return Err(vec![Error::TypeNotFound(name.clone(), argument.span)]);
694            };
695            if declared.arity() != args.len() {
696                return Err(vec![Error::TypeArityMismatch(
697                    name.clone(),
698                    declared.arity(),
699                    args.len(),
700                    argument.span,
701                )]);
702            }
703
704            let name = declared.name.clone();
705            Ok(InstanceHead::Type(name, distinct_variables(args.iter())?))
706        }
707        parser::TypeKind::Tuple(tuple) => {
708            distinct_variables(tuple.iter())?;
709            let tuple = tuple.try_map(|element| match &element.kind {
710                parser::TypeKind::Variable(name) => Ok(name.clone()),
711                _ => Err(vec![Error::InvalidInstanceHead(
712                    InstanceHeadProblem::ArgumentNotVariable,
713                    element.span,
714                )]),
715            })?;
716            Ok(InstanceHead::Tuple(tuple))
717        }
718        parser::TypeKind::Unit => Ok(InstanceHead::Unit),
719        parser::TypeKind::Variable(name) => Err(vec![Error::InvalidInstanceHead(
720            InstanceHeadProblem::Variable(name.clone()),
721            argument.span,
722        )]),
723        parser::TypeKind::Arrow(..) => Err(vec![Error::InvalidInstanceHead(
724            InstanceHeadProblem::Function,
725            argument.span,
726        )]),
727        parser::TypeKind::Record(..) => Err(vec![Error::InvalidInstanceHead(
728            InstanceHeadProblem::Record,
729            argument.span,
730        )]),
731    }
732}
733
734/// The names of `args`, each of which has to be a type variable and none of which may
735/// repeat an earlier one. Every argument that breaks either rule is an error at its own
736/// span.
737fn distinct_variables<'a>(
738    args: impl Iterator<Item = &'a parser::Type>,
739) -> Result<Vec<Name>, Vec<Error>> {
740    let mut seen: HashSet<&Name> = HashSet::new();
741    let mut variables = Vec::new();
742    let mut errors = Vec::new();
743
744    for arg in args {
745        match &arg.kind {
746            parser::TypeKind::Variable(name) if seen.contains(name) => {
747                errors.push(Error::InvalidInstanceHead(
748                    InstanceHeadProblem::RepeatedVariable(name.clone()),
749                    arg.span,
750                ));
751            }
752            parser::TypeKind::Variable(name) => {
753                seen.insert(name);
754                variables.push(name.clone());
755            }
756            _ => errors.push(Error::InvalidInstanceHead(
757                InstanceHeadProblem::ArgumentNotVariable,
758                arg.span,
759            )),
760        }
761    }
762
763    if errors.is_empty() {
764        Ok(variables)
765    } else {
766        Err(errors)
767    }
768}
769
770/// What [`do_instances`] made of a module's instance declarations.
771pub(super) struct Instances {
772    /// Every instance that passed every check, in source order.
773    pub instances: Vec<Instance>,
774    /// Why each of the others did not, and every name a binding could not resolve. An
775    /// instance of a class whose own declaration failed is among the others with nothing
776    /// said here, since that declaration's error says it.
777    pub errors: Vec<Error>,
778}
779
780/// Canonicalize every `instance` declaration of a module, and hold each to the rules a
781/// declaration of one has to follow.
782///
783/// Every head is resolved first, so that a superclass instance written further down the
784/// file satisfies one written above it. Every `derived` instance is then read together
785/// with the others ([`derive_all`]): what each needs of its type's arguments is its
786/// context, and what each is made of is the members its class's derivation stands for.
787/// Then each instance in turn: its context, its bindings against its class's members, and
788/// the three rules about where it stands, in the order a reader wants them — [the orphan
789/// rule](../../../docs/spec/type-classes.md#where-an-instance-may-be-declared), the same
790/// instance declared twice, and a superclass with no instance for the head.
791///
792/// A duplicate is looked for among the instances this module declares and every
793/// instance its imports brought into scope. Where the orphan rule holds and imports
794/// cannot form a cycle, only the module's own can collide, and the check does not lean
795/// on either.
796pub(super) fn do_instances(
797    env: &RootEnvironment,
798    instances: &[parser::InstanceDecl],
799    unresolved: &mut Vec<Error>,
800) -> Instances {
801    let module = env.module_name().clone();
802    let mut errors = Vec::new();
803
804    let heads: Vec<Result<(QualName, InstanceHead), Vec<Error>>> = instances
805        .iter()
806        .map(|instance| instance_head(env, instance))
807        .collect();
808
809    // Every instance whose class and head resolved, own or imported, by what identifies
810    // it. A superclass is satisfied by any of them. An imported instance that failed in
811    // its own module is not among them: its interface is incomplete, and so is this
812    // module's scope, which is what lets the caller drop the error that absence raises.
813    let mut in_scope: HashSet<(QualName, HeadName)> = heads
814        .iter()
815        .filter_map(|head| head.as_ref().ok())
816        .map(|(class, head)| (class.clone(), head.name()))
817        .collect();
818    in_scope.extend(env.imported_instances().iter().map(|published| {
819        (
820            published.signature.class.clone(),
821            published.signature.head.name(),
822        )
823    }));
824
825    // The context each instance writes, resolved once: the instances being derived are
826    // read against the ones written out, and each reports its own errors in its turn.
827    let mut contexts: Vec<Option<Result<Vec<Constraint>, Vec<Error>>>> = instances
828        .iter()
829        .zip(&heads)
830        .map(|(instance, head)| {
831            let (_, head) = head.as_ref().ok()?;
832            Some(constraints(
833                env,
834                instance.context.as_ref(),
835                &head.variables(),
836                Error::ConstraintVariableUnbound,
837            ))
838        })
839        .collect();
840
841    // Every instance with the context it writes, which a derived one may need of its type's
842    // arguments.
843    let written: Vec<WrittenInstance> = heads
844        .iter()
845        .zip(&contexts)
846        .filter_map(|(head, context)| {
847            let (class, head) = head.as_ref().ok()?;
848            // A context that did not resolve is reported in its instance's turn, and reads
849            // as none here.
850            let context = match context {
851                Some(Ok(context)) => context
852                    .iter()
853                    .map(|constraint| (constraint.class.clone(), constraint.variable.clone()))
854                    .collect(),
855                _ => Vec::new(),
856            };
857
858            Some(WrittenInstance {
859                class: class.clone(),
860                head: head.clone(),
861                context,
862            })
863        })
864        .collect();
865
866    let candidates: Vec<(usize, Candidate)> = instances
867        .iter()
868        .zip(&heads)
869        .zip(&contexts)
870        .enumerate()
871        .filter_map(|(index, ((instance, head), context))| {
872            let parser::InstanceBody::Derived(span) = &instance.body else {
873                return None;
874            };
875            let (class, head) = head.as_ref().ok()?;
876            let context = match (&instance.context, context) {
877                (Some(written), Some(Ok(context))) => Some((context.as_slice(), written.span)),
878                _ => None,
879            };
880
881            Some((
882                index,
883                Candidate {
884                    class,
885                    head,
886                    context,
887                    span: *span,
888                },
889            ))
890        })
891        .collect();
892    let (indices, candidates): (Vec<usize>, Vec<Candidate>) = candidates.into_iter().unzip();
893    let signatures: Vec<Option<&ClassSignature>> = candidates
894        .iter()
895        .map(|candidate| env.class_signature(candidate.class))
896        .collect();
897    let mut derived: HashMap<usize, Result<Derived, Vec<Error>>> = indices
898        .into_iter()
899        .zip(derive_all(env, &candidates, &signatures, &written))
900        .collect();
901
902    let mut declared: Vec<(QualName, HeadName, NodeSpan)> = Vec::new();
903    let mut kept = Vec::new();
904
905    for (index, (instance, head)) in instances.iter().zip(heads).enumerate() {
906        // An instance whose class or head did not resolve has nothing to hold its
907        // context or its bindings to.
908        let (class, head) = match head {
909            Ok(resolved) => resolved,
910            Err(head_errors) => {
911                errors.extend(head_errors);
912                continue;
913            }
914        };
915        let class = &class;
916
917        let mut instance_errors = Vec::new();
918        let mut failed_silently = false;
919        let signature = env.class_signature(class);
920
921        let mut context = match contexts[index].take() {
922            Some(Ok(context)) => context,
923            Some(Err(context_errors)) => {
924                instance_errors.extend(context_errors);
925                Vec::new()
926            }
927            None => Vec::new(),
928        };
929
930        let bindings = match &instance.body {
931            parser::InstanceBody::Derived(_) => {
932                // The context is the one the instance writes, which `derive_all` held to
933                // what its type's arguments need, or the one it inferred.
934                match derived.remove(&index) {
935                    Some(Ok(derived)) => {
936                        context = derived.context;
937                        derived.bindings
938                    }
939                    Some(Err(derive_errors)) => {
940                        // No error here is a failure reported elsewhere, in the class's
941                        // own declaration, and the instance has no members to keep.
942                        failed_silently |= derive_errors.is_empty();
943                        instance_errors.extend(derive_errors);
944                        Vec::new()
945                    }
946                    None => Vec::new(),
947                }
948            }
949            parser::InstanceBody::Bindings(bindings) => {
950                let (values, binding_errors) =
951                    instance_bindings(env, class, signature, instance, bindings, unresolved);
952                instance_errors.extend(binding_errors);
953                values
954            }
955        };
956
957        let head_name = head.name();
958
959        let class_module = declaring_module(class);
960        let head_module = head_name.module();
961        if class_module != module && head_module.as_ref() != Some(&module) {
962            instance_errors.push(Error::OrphanInstance(
963                Box::new(InstanceName {
964                    class: class.clone(),
965                    head: head_name.clone(),
966                }),
967                instance.span,
968            ));
969        }
970
971        let first = declared
972            .iter()
973            .find(|(c, h, _)| c == class && *h == head_name)
974            .map(|(_, _, span)| DeclarationSite::InThisModule(*span))
975            .or_else(|| {
976                env.imported_instances()
977                    .iter()
978                    .find(|published| {
979                        &published.signature.class == class
980                            && published.signature.head.name() == head_name
981                    })
982                    .map(|published| match published.source {
983                        Some(source) => DeclarationSite::InImportedModule(source),
984                        None => DeclarationSite::Unknown,
985                    })
986            });
987        if let Some(first) = first {
988            instance_errors.push(Error::DuplicateInstance(
989                Box::new(InstanceName {
990                    class: class.clone(),
991                    head: head_name.clone(),
992                }),
993                instance.span,
994                first,
995            ));
996        }
997        declared.push((class.clone(), head_name.clone(), instance.span));
998
999        if let Some(signature) = signature {
1000            for superclass in &signature.superclasses {
1001                if !in_scope.contains(&(superclass.class.clone(), head_name.clone())) {
1002                    instance_errors.push(Error::MissingSuperclassInstance(
1003                        Box::new(InstanceName {
1004                            class: class.clone(),
1005                            head: head_name.clone(),
1006                        }),
1007                        superclass.class.clone(),
1008                        instance.span,
1009                    ));
1010                }
1011            }
1012        }
1013
1014        if instance_errors.is_empty() && !failed_silently {
1015            kept.push(Instance {
1016                signature: InstanceSignature {
1017                    class: class.clone(),
1018                    head: head.clone(),
1019                    context,
1020                    module: module.clone(),
1021                    span: instance.span,
1022                },
1023                bindings,
1024                derived: matches!(instance.body, parser::InstanceBody::Derived(_)),
1025            });
1026        } else {
1027            errors.extend(instance_errors);
1028        }
1029    }
1030
1031    Instances {
1032        instances: kept,
1033        errors,
1034    }
1035}
1036
1037/// The bindings of `instance`, an instance of `class`, each canonicalized as an ordinary
1038/// value, beside the errors of every binding that names no member, binds one a second
1039/// time or does not canonicalize, and of every member nothing binds.
1040///
1041/// `signature` is `None` when `class` resolved and its declaration did not canonicalize;
1042/// there are then no members to hold the bindings to, and the failure that says so has
1043/// been reported.
1044fn instance_bindings(
1045    env: &RootEnvironment,
1046    class: &QualName,
1047    signature: Option<&ClassSignature>,
1048    instance: &parser::InstanceDecl,
1049    bindings: &[parser::FunBinding],
1050    unresolved: &mut Vec<Error>,
1051) -> (Vec<Value>, Vec<Error>) {
1052    let mut values = Vec::new();
1053    let mut errors = Vec::new();
1054    let mut first: HashMap<&Name, NodeSpan> = HashMap::new();
1055    let class_name = class.unqualified_name();
1056
1057    for binding in bindings {
1058        if let Some(signature) = signature {
1059            if !signature.members.iter().any(|m| m.name == binding.name) {
1060                errors.push(Error::InstanceBindingNotMember(
1061                    binding.name.clone(),
1062                    class_name.clone(),
1063                    binding.span,
1064                ));
1065                continue;
1066            }
1067        }
1068
1069        if let Some(earlier) = first.get(&binding.name) {
1070            errors.push(Error::InstanceMemberBoundTwice(
1071                binding.name.clone(),
1072                binding.span,
1073                *earlier,
1074            ));
1075            continue;
1076        }
1077        first.insert(&binding.name, binding.span);
1078
1079        match binding_value(env, binding, unresolved) {
1080            Ok(value) => values.push(value),
1081            Err(error) => errors.push(error),
1082        }
1083    }
1084
1085    if let Some(signature) = signature {
1086        for member in &signature.members {
1087            if !first.contains_key(&member.name) {
1088                errors.push(Error::InstanceMemberMissing(
1089                    member.name.clone(),
1090                    class_name.clone(),
1091                    instance.span,
1092                ));
1093            }
1094        }
1095    }
1096
1097    (values, errors)
1098}