832375f2ac
All 176 files in the four accumulating directories now use a zero-padded 4-digit counter prefix that reflects creation order (`NNNN-slug.md`). The counter is assigned per directory in strict git-log creation order; ties broken alphabetically by original name. The old `YYYY-MM-DD-` prefix on docs/specs/ and docs/plans/ files is dropped — the date is recoverable from git log and the counter carries the ordering. A file's counter is stable for the life of the file: never reassigned, never reused, never compacted. Deleted files retire their counter; subsequent files do not fill the gap. This is the property that lets cross-references stay literal — refs use the full filename including the counter (`design/contracts/0007-honesty-rule.md`) so they grep cleanly and resolve directly without a glob step. 313 cross-references updated across .md/.rs/.toml/.c/.json files (test pins, include_str! paths, design-INDEX entries, baseline notes, runtime C comments, inter-contract markdown links incl. bare basename and `../models/foo.md` forms). CLAUDE.md gets a new "File-naming convention" section spelling out the rule and rationale. skills/brainstorm/SKILL.md and skills/planner/SKILL.md updated so new spec/plan creation produces counter-prefixed names from the start. The full test suite (cargo test --workspace) passes.
57 lines
2.5 KiB
Markdown
57 lines
2.5 KiB
Markdown
# Method dispatch
|
|
|
|
## Method dispatch
|
|
|
|
The class-method resolution rule that pairs with the
|
|
[typeclasses](0013-typeclasses.md) contract; the `Show`/`Eq`/`Ord` instances
|
|
the rule dispatches against live in [prelude classes](0017-prelude-classes.md).
|
|
|
|
Dispatch is two-mode:
|
|
|
|
**Polymorphic call sites** (inside a fn body with `forall` +
|
|
constraint set): the constraint names the class via the qualified
|
|
`Constraint.class` field (canonical form: bare for same-module,
|
|
`<module>.<Class>` for cross-module; see
|
|
[memory model](0008-memory-model.md) for the canonical-form rule).
|
|
Synth's residual carries the class name directly;
|
|
constraint-discharge at fn-body-end matches against the workspace
|
|
registry by `(class, type_hash)` key.
|
|
|
|
**Monomorphic call sites**: synth consults the workspace-flat
|
|
`Env.method_to_candidate_classes: BTreeMap<MethodName,
|
|
BTreeSet<QualifiedClassName>>` index, then runs the 5-step
|
|
dispatch rule:
|
|
|
|
1. Parse the `Term::Var.name` for an optional class qualifier
|
|
(last-dot-segment is the method name; everything before is the
|
|
qualified class).
|
|
2. If `method_to_candidate_classes` has no entry for the method
|
|
name, fall through to the existing Var-arm branches (free fn
|
|
lookup, dot-qualified cross-module).
|
|
3. Qualifier present: filter candidates to the named class. Empty
|
|
result fires `UnknownClass`. Singleton survivor proceeds.
|
|
4. Qualifier empty (bare-method form): singleton candidate proceeds
|
|
directly; multiple candidates yield a multi-candidate residual
|
|
for discharge-time refinement.
|
|
5. At discharge, refinement runs: concrete `type_` filters
|
|
candidates via the workspace registry; rigid-var `type_` filters
|
|
via the active fn's declared constraints
|
|
(`env.active_declared_constraints`). Single survivor discharges;
|
|
multiple survivors fire `AmbiguousMethodResolution` (concrete) or
|
|
`MissingConstraint` (rigid-var); zero survivors fire `NoInstance`
|
|
(concrete) or `MissingConstraint` (rigid-var).
|
|
|
|
The `method_to_candidate_classes` index is the load-bearing data
|
|
structure for this routing — its construction in `build_check_env`
|
|
inverts the per-module `class_methods` maps (themselves tuple-keyed
|
|
by `(qualified-class, method)`) to a workspace-flat
|
|
method-name-to-class-set map.
|
|
|
|
Class-fn collisions resolve at the call site, not at workspace load
|
|
time: the fn lookup precedence (locals → caller-module-fn →
|
|
imported-fn) runs ahead of the class-method branch. When both
|
|
sides have a match, the fn wins and a `class-method-shadowed-by-fn`
|
|
warning surfaces the shadow.
|
|
|
|
Ratified by: `crates/ail/tests/show_no_instance_e2e.rs`.
|