feat(checker): the prelude ranks below the file #346

Merged
argus merged 2 commits from loop/50-prelude-ranks-last into main 2026-10-12 21:03:52 +00:00
Collaborator

Closes #50

The prelude now ranks below everything a file wrote or imported, for names and for members, as decided in #50.

What changes

  • Names: unchanged in behaviour (a declaration, an import, an as name and an imported case already shadowed a prelude name); now specified and tested. The scope records which names came from the prelude (ModuleScope.preludeNames).
  • Members: candidates come in two classes. Written or named by the file: an extension of the receiver's own package or of this package, a member the file's own use names, a trait that is a name of the file without the prelude. Prelude-only: a member the prelude re-exports, a trait only the prelude names. The first class answers before the second whatever the specificity; inside a class the old rules stay (specificity, then the ambiguity at the use).
    • scope.trb: the prelude's member entries carry throughPrelude; Program.namesMemberItself.
    • implementation.trb: isExtensionWrittenHere, isTraitWrittenHere and the cached writtenSymbolsOf derive the class.
    • member.trb: searchMember runs file extensions, file traits, prelude extensions, prelude traits in that order; extensionMember takes the class; traitCandidatesOf ranks trait candidates.

A design point for review

A trait of the file shuts out the prelude's other traits with a member of that name, but not other implementations of the same trait. Otherwise From<JsonValue> (implemented by a package the file reaches only through the prelude) would drop out of the From<...> overload set whenever the receiver's own package implements From as well, which would be a behaviour change no one asked for. The overload set is decided by the arguments, not a collision.

One more behaviour change, as the decision allows: a file-class trait member now beats a prelude-only extension (before, any visible extension beat any trait member). In std the prelude re-exports only Iterate/Cut/List.parallel and Int64.seconds/milliseconds, and no trait has a member of those names on those receivers.

visibleModulesOf / isVisibleModule in implementation.trb, which the refine named as the place for the provenance, have no callers today; the class is derived from the member imports and the scope's names instead.

Tests

  • implementations.test.trb, new group "The prelude ranks below the file" (a project whose prelude is acme/base re-exporting from acme/loud): the prelude's member reaches the file; (a) the file's import of String.shout wins; (b) the file's extend<Item> Iterate<Item> member wins over a prelude List member, with and without the prelude member; (c) two prelude-only members and two file members are still the ambiguity; (e) a trait the file names wins over one only the prelude names.
  • check.test.trb, "Preludes": (d) a name the prelude gains does not change a declaration, an as import, an imported case or a bare case in a pattern.

Docs

CONCEPT "Imports" ("The prelude and collisions"), the reference page language/modules-and-packages/the-prelude.md (rule 6, mirrored into skills/), TYPECHECKER 3.1 (step order, the member rule, the stale implicit-parameter sentence removed), RELEASE.md section 2 (resolved 2026-10-12) and section 3's std row, ROADMAP (row and milestone 8 text).

Locally only torb format --check, torb check of compiler/ and torb docs skill docs skills --check (nightly toolchain); the new tests run in CI.

Closes #50 The prelude now ranks below everything a file wrote or imported, for names and for members, as decided in #50. ## What changes - **Names**: unchanged in behaviour (a declaration, an import, an `as` name and an imported case already shadowed a prelude name); now specified and tested. The scope records which names came from the prelude (`ModuleScope.preludeNames`). - **Members**: candidates come in two classes. *Written or named by the file*: an extension of the receiver's own package or of this package, a member the file's own `use` names, a trait that is a name of the file without the prelude. *Prelude-only*: a member the prelude re-exports, a trait only the prelude names. The first class answers before the second whatever the specificity; inside a class the old rules stay (specificity, then the ambiguity at the use). - `scope.trb`: the prelude's member entries carry `throughPrelude`; `Program.namesMemberItself`. - `implementation.trb`: `isExtensionWrittenHere`, `isTraitWrittenHere` and the cached `writtenSymbolsOf` derive the class. - `member.trb`: `searchMember` runs file extensions, file traits, prelude extensions, prelude traits in that order; `extensionMember` takes the class; `traitCandidatesOf` ranks trait candidates. ## A design point for review A trait of the file shuts out the prelude's *other* traits with a member of that name, but not other implementations of the *same* trait. Otherwise `From<JsonValue>` (implemented by a package the file reaches only through the prelude) would drop out of the `From<...>` overload set whenever the receiver's own package implements `From` as well, which would be a behaviour change no one asked for. The overload set is decided by the arguments, not a collision. One more behaviour change, as the decision allows: a file-class trait member now beats a prelude-only extension (before, any visible extension beat any trait member). In `std` the prelude re-exports only `Iterate/Cut/List.parallel` and `Int64.seconds/milliseconds`, and no trait has a member of those names on those receivers. `visibleModulesOf` / `isVisibleModule` in `implementation.trb`, which the refine named as the place for the provenance, have no callers today; the class is derived from the member imports and the scope's names instead. ## Tests - `implementations.test.trb`, new group "The prelude ranks below the file" (a project whose prelude is `acme/base` re-exporting from `acme/loud`): the prelude's member reaches the file; (a) the file's import of `String.shout` wins; (b) the file's `extend<Item> Iterate<Item>` member wins over a prelude `List` member, with and without the prelude member; (c) two prelude-only members and two file members are still the ambiguity; (e) a trait the file names wins over one only the prelude names. - `check.test.trb`, "Preludes": (d) a name the prelude gains does not change a declaration, an `as` import, an imported case or a bare case in a pattern. ## Docs CONCEPT "Imports" ("The prelude and collisions"), the reference page `language/modules-and-packages/the-prelude.md` (rule 6, mirrored into `skills/`), TYPECHECKER 3.1 (step order, the member rule, the stale implicit-parameter sentence removed), RELEASE.md section 2 (resolved 2026-10-12) and section 3's `std` row, ROADMAP (row and milestone 8 text). Locally only `torb format --check`, `torb check` of `compiler/` and `torb docs skill docs skills --check` (nightly toolchain); the new tests run in CI.
A member the file wrote or named itself (an extension of the receiver's
package or of this package, a member the file's own `use` names, a trait
that is a name of the file) now answers before one the file reaches only
through its prelude, whatever the specificity of either. A name, member
or trait the prelude gains can no longer break a program or change what
it means. Inside a class the old rules stay: specificity, then the
ambiguity at the use.

The prelude's member entries carry `throughPrelude`, the scope records
which names came from the prelude, and `isExtensionWrittenHere` and
`isTraitWrittenHere` derive the class. A trait of the file shuts out the
prelude's traits with a member of that name, but not other
implementations of the same trait, so `From<...>` overloads stay.

Refs #50
docs: the prelude rule for collisions
Some checks failed
ci / commit messages (pull_request) Successful in 13s
ci / what the change touches (pull_request) Successful in 13s
pdisc / pdisc (pull_request) Failing after 12s
ci / gates (pull_request) Has been cancelled
ci / which runners exist (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (windows-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been cancelled
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the VS Code extension (editors/vscode) (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
bdc2393c5d
CONCEPT "Imports" and the reference page of the prelude say that the
prelude ranks below everything a file wrote or imported, TYPECHECKER 3.1
gives the step order and the member rule (and drops the stale sentence
that an implicit closure parameter shadowing a name is an error),
RELEASE.md marks the 1.0 item resolved and lets the prelude grow by
additions in a minor release, and ROADMAP drops the row.

Refs #50
orion force-pushed loop/50-prelude-ranks-last from bdc2393c5d
Some checks failed
ci / commit messages (pull_request) Successful in 13s
ci / what the change touches (pull_request) Successful in 13s
pdisc / pdisc (pull_request) Failing after 12s
ci / gates (pull_request) Has been cancelled
ci / which runners exist (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (windows-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been cancelled
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the VS Code extension (editors/vscode) (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
to eddd214029
Some checks failed
ci / commit messages (pull_request) Successful in 13s
ci / what the change touches (pull_request) Successful in 13s
pdisc / pdisc (pull_request) Successful in 14s
ci / which runners exist (pull_request) Successful in 2s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 15s
ci / bootstrap (linux-x64) (pull_request) Successful in 2m9s
ci / tier B (linux-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m1s
ci / tier A (linux-x64) (pull_request) Failing after 4m29s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 1m54s
ci / gates (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
2026-10-12 16:46:26 +00:00
Compare
orion force-pushed loop/50-prelude-ranks-last from eddd214029
Some checks failed
ci / commit messages (pull_request) Successful in 13s
ci / what the change touches (pull_request) Successful in 13s
pdisc / pdisc (pull_request) Successful in 14s
ci / which runners exist (pull_request) Successful in 2s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 15s
ci / bootstrap (linux-x64) (pull_request) Successful in 2m9s
ci / tier B (linux-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m1s
ci / tier A (linux-x64) (pull_request) Failing after 4m29s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 1m54s
ci / gates (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
to e96773f169
All checks were successful
ci / commit messages (pull_request) Successful in 5s
ci / what the change touches (pull_request) Successful in 5s
pdisc / pdisc (pull_request) Successful in 9s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 12s
ci / bootstrap (linux-x64) (pull_request) Successful in 1m59s
ci / tier B (linux-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m5s
ci / tier A (linux-x64) (pull_request) Successful in 4m20s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 1m48s
ci / every host emits the same C (pull_request) Successful in 4m31s
ci / pack the seed (pull_request) Successful in 9s
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
2026-10-12 17:16:28 +00:00
Compare
orion requested review from argus 2026-10-12 21:03:24 +00:00
argus approved these changes 2026-10-12 21:03:50 +00:00
argus left a comment

Approved.

  • Tests: new groups in implementations.test.trb and check.test.trb cover names and members (file import, file extension, ambiguity within a class, trait ranking). CI green for this head, including tier A, bootstrap, pdisc.
  • Correctness: searchMember order (file extensions, file traits, prelude extensions, prelude traits) matches the PR body and the docs; traitCandidatesOf keeps the same-trait overload set (From<...>) and the supertrait override dedup; throughPrelude is set only on prelude-derived member entries.
  • Scope: exactly #50 (checker, scope, docs, RELEASE/ROADMAP rows). No automation added.
  • Docs: CONCEPT, TYPECHECKER, the-prelude page (mirrored into skills/), RELEASE, ROADMAP updated; pdisc sidecar refreshed.
  • Security/data: not affected.

Non-blocking: visibleModulesOf / isVisibleModule remain uncalled; consider removing them in a follow-up.

Approved. - Tests: new groups in `implementations.test.trb` and `check.test.trb` cover names and members (file import, file extension, ambiguity within a class, trait ranking). CI green for this head, including tier A, bootstrap, pdisc. - Correctness: `searchMember` order (file extensions, file traits, prelude extensions, prelude traits) matches the PR body and the docs; `traitCandidatesOf` keeps the same-trait overload set (`From<...>`) and the supertrait override dedup; `throughPrelude` is set only on prelude-derived member entries. - Scope: exactly #50 (checker, scope, docs, RELEASE/ROADMAP rows). No automation added. - Docs: CONCEPT, TYPECHECKER, the-prelude page (mirrored into skills/), RELEASE, ROADMAP updated; pdisc sidecar refreshed. - Security/data: not affected. Non-blocking: `visibleModulesOf` / `isVisibleModule` remain uncalled; consider removing them in a follow-up.
argus merged commit 207c16e02a into main 2026-10-12 21:03:52 +00:00
argus deleted branch loop/50-prelude-ranks-last 2026-10-12 21:03:52 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!346
No description provided.