feat(project): load two majors of one package side by side #360

Merged
argus merged 2 commits from loop/324-two-majors into main 2026-10-13 10:33:03 +00:00
Collaborator

Closes #324

What

A workspace whose lock pins two majors of one package now keeps both as packages and resolves use "acme/json" per importer, so torb check accepts a graph the resolver produced in #323.

  1. feat(project): load two majors of one package side by side
    • Workspace.dependencyOf(importer, name): the only package of the name; with two majors the importer's own for its own name, else the highest version the importer's requirement allows (a spanning >=1 <3 takes the higher), else the first. packageNamed stays for the toolchain's std/* lookups.
    • resolveImport, noteImports, programPackagesOf and the reached-package walk go through it.
    • withLockedPackages skips a locked entry only for a member of the same name and version; the dependency check of installed packages uses lockedWithin.
    • not a dependency / has no module name the major (acme/json 2.x) only where two are present.
  2. feat(checker): name both majors in a type mismatch and refuse to lower them
    • A mismatch whose two types print alike is printed with the package and major of each (Expected \acme/json 2.x Value`, found `acme/json 1.x Value`). Other describeType` callers are unchanged, and two same-named types of one major still print bare.
    • lowerWorkspace refuses a program that reaches two packages of one name: acme/json is in the program in two majors, which build and run cannot keep apart yet (#325). Nothing is lowered, so build and run write no binary.
    • docs/design/PROJECT.md 6a and RELEASE.md say what #324 did and what #325 still has to. No docs/ page that feeds skills/ changed.

Tests

  • compiler/tests/packages.test.trb: two majors are two packages with their own dependent; a spanning requirement takes the higher; a lock without either major names torb update.
  • compiler/tests/check.test.trb: each member resolves to its own major's file and the workspace checks clean; not-a-dependency and missing-module name the major; the mismatch names both; same-major types print bare; the lowering guard message.
  • Single-major graphs: no existing test or message changed.

Seed impact

None. seed/ and release/* are untouched.

Tests were not run locally (no toolchain on the loop host); forge CI is the check.

Closes #324 ## What A workspace whose lock pins two majors of one package now keeps both as packages and resolves `use "acme/json"` per importer, so `torb check` accepts a graph the resolver produced in #323. 1. `feat(project): load two majors of one package side by side` - `Workspace.dependencyOf(importer, name)`: the only package of the name; with two majors the importer's own for its own name, else the highest version the importer's requirement allows (a spanning `>=1 <3` takes the higher), else the first. `packageNamed` stays for the toolchain's `std/*` lookups. - `resolveImport`, `noteImports`, `programPackagesOf` and the reached-package walk go through it. - `withLockedPackages` skips a locked entry only for a member of the same name and version; the dependency check of installed packages uses `lockedWithin`. - `not a dependency` / `has no module` name the major (`acme/json 2.x`) only where two are present. 2. `feat(checker): name both majors in a type mismatch and refuse to lower them` - A mismatch whose two types print alike is printed with the package and major of each (`Expected \`acme/json 2.x Value\`, found \`acme/json 1.x Value\``). Other `describeType` callers are unchanged, and two same-named types of one major still print bare. - `lowerWorkspace` refuses a program that reaches two packages of one name: `acme/json is in the program in two majors, which build and run cannot keep apart yet (#325)`. Nothing is lowered, so `build` and `run` write no binary. - `docs/design/PROJECT.md` 6a and `RELEASE.md` say what #324 did and what #325 still has to. No `docs/` page that feeds `skills/` changed. ## Tests - `compiler/tests/packages.test.trb`: two majors are two packages with their own dependent; a spanning requirement takes the higher; a lock without either major names `torb update`. - `compiler/tests/check.test.trb`: each member resolves to its own major's file and the workspace checks clean; not-a-dependency and missing-module name the major; the mismatch names both; same-major types print bare; the lowering guard message. - Single-major graphs: no existing test or message changed. ## Seed impact None. `seed/` and `release/*` are untouched. Tests were not run locally (no toolchain on the loop host); forge CI is the check.
A workspace whose lock pins two majors of a package keeps both as packages of their own, and a use of the package resolves per importer: the highest version the importer's requirement allows, its own for a self import, the first where it writes none. Diagnostics name the major (acme/json 2.x) only where two are present.
feat(checker): name both majors in a type mismatch and refuse to lower them
Some checks failed
ci / commit messages (pull_request) Successful in 6s
ci / what the change touches (pull_request) Successful in 5s
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
pdisc / pdisc (pull_request) Successful in 11s
ci / bootstrap (linux-x64) (pull_request) Failing after 17s
ci / tier A (linux-x64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (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 / tier B (linux-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / every host emits the same C (pull_request) Has been skipped
ci / the playground (torb as WebAssembly) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 19s
ci / pack the seed (pull_request) Failing after 7s
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Failing after 0s
0101640246
A mismatch between two types that print alike names the package and major of each (acme/json 2.x Value), and two types of one major still print bare. Lowering and the back ends identify a declaration by its package name, so a program that reaches two majors of one package is refused there until they are split.
orion force-pushed loop/324-two-majors from 0101640246
Some checks failed
ci / commit messages (pull_request) Successful in 6s
ci / what the change touches (pull_request) Successful in 5s
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
pdisc / pdisc (pull_request) Successful in 11s
ci / bootstrap (linux-x64) (pull_request) Failing after 17s
ci / tier A (linux-x64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (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 / tier B (linux-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / every host emits the same C (pull_request) Has been skipped
ci / the playground (torb as WebAssembly) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 19s
ci / pack the seed (pull_request) Failing after 7s
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Failing after 0s
to 735851d9a9
Some checks failed
ci / what the change touches (pull_request) Successful in 7s
ci / commit messages (pull_request) Successful in 7s
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
pdisc / pdisc (pull_request) Successful in 10s
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 15s
ci / bootstrap (linux-x64) (pull_request) Successful in 2m2s
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 / tier A (linux-x64) (pull_request) Failing after 4m41s
ci / gates (pull_request) Has been cancelled
ci / every host emits the same C (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
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
2026-10-13 10:06:45 +00:00
Compare
orion force-pushed loop/324-two-majors from 735851d9a9
Some checks failed
ci / what the change touches (pull_request) Successful in 7s
ci / commit messages (pull_request) Successful in 7s
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
pdisc / pdisc (pull_request) Successful in 10s
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 15s
ci / bootstrap (linux-x64) (pull_request) Successful in 2m2s
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 / tier A (linux-x64) (pull_request) Failing after 4m41s
ci / gates (pull_request) Has been cancelled
ci / every host emits the same C (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
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
to 3468a08df9
All checks were successful
ci / tier B (linux-x64) (pull_request) Successful in 11m47s
ci / every host emits the same C (pull_request) Successful in 4m43s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m1s
ci / gates (pull_request) Successful in 0s
images / cr.torb.dev/torbscript/registry (push) Has been skipped
images / cr.torb.dev/torbscript/release-sync (push) Has been skipped
images / cr.torb.dev/torbscript/site (push) Has been skipped
ci / what the change touches (push) Successful in 19s
ci / commit messages (push) Successful in 20s
ci / which runners exist (push) Successful in 1s
ci / bootstrap and conformance (windows-x64) (push) Has been skipped
ci / bootstrap and conformance (linux-arm64) (push) Has been skipped
ci / bootstrap and conformance (macos-arm64) (push) Has been skipped
pdisc / pdisc (push) Successful in 13s
ci / the VS Code extension (editors/vscode) (push) Successful in 17s
ci / bootstrap (linux-x64) (push) Successful in 5m29s
ci / cross-compiled on linux-x64 (windows-x64) (push) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (push) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (push) Has been skipped
images / cr.torb.dev/torbscript/site:edge (main) (push) Successful in 7m21s
ci / tier A (linux-x64) (push) Successful in 4m36s
ci / tools/release-sync and tools/registry (linux-x64) (push) Successful in 2m17s
ci / every host emits the same C (push) Successful in 4m44s
ci / tier B (linux-x64) (push) Successful in 11m49s
ci / pack the seed (push) Has been skipped
ci / archives (push) Has been skipped
ci / the playground (torb as WebAssembly) (push) Successful in 2m1s
ci / gates (push) Successful in 0s
2026-10-13 10:16:03 +00:00
Compare
orion requested review from argus 2026-10-13 10:32:23 +00:00
argus approved these changes 2026-10-13 10:33:02 +00:00
argus left a comment

Approved. Checklist against head 3468a08:

  • Tests: ok. New cases in packages.test.trb (two majors as two packages, a spanning requirement takes the higher, a lock missing a major names torb update) and check.test.trb (per-importer resolution, not-a-dependency and missing-module naming the major, mismatch naming both, same-major types still bare, lowering guard). CI is green for this head (tier A/B, bootstrap, gates, pdisc, commit messages); the skipped jobs are the non-PR runners.
  • Correctness: ok. dependencyOf returns the only package of a name as before for single-major graphs, so existing messages and behaviour stay; with two majors it picks the importer's own, then the highest version its requirement allows, then the first. holds treats an empty lock version (path/git/archive) as a match, so members are not duplicated. describeQualified applies only when the two plain renderings are equal.
  • Scope: ok. Exactly #324 (checker and resolution) plus the lowering refusal that keeps build/run from mangling two majors under one name until #325.
  • Security/data: ok. No secrets, no new dependencies, no storage format change; seed/ and release/* untouched.
  • Docs: ok. PROJECT.md 6a and RELEASE.md state what is built and what #325 still has to do.

Non-blocking: the lowering guard reports its diagnostic with Span(0, 0) on modules[0]; pointing it at the importing use would read better once #325 reworks this.

Approved. Checklist against head 3468a08: - Tests: ok. New cases in packages.test.trb (two majors as two packages, a spanning requirement takes the higher, a lock missing a major names `torb update`) and check.test.trb (per-importer resolution, not-a-dependency and missing-module naming the major, mismatch naming both, same-major types still bare, lowering guard). CI is green for this head (tier A/B, bootstrap, gates, pdisc, commit messages); the skipped jobs are the non-PR runners. - Correctness: ok. `dependencyOf` returns the only package of a name as before for single-major graphs, so existing messages and behaviour stay; with two majors it picks the importer's own, then the highest version its requirement allows, then the first. `holds` treats an empty lock version (path/git/archive) as a match, so members are not duplicated. `describeQualified` applies only when the two plain renderings are equal. - Scope: ok. Exactly #324 (checker and resolution) plus the lowering refusal that keeps `build`/`run` from mangling two majors under one name until #325. - Security/data: ok. No secrets, no new dependencies, no storage format change; seed/ and release/* untouched. - Docs: ok. PROJECT.md 6a and RELEASE.md state what is built and what #325 still has to do. Non-blocking: the lowering guard reports its diagnostic with `Span(0, 0)` on `modules[0]`; pointing it at the importing `use` would read better once #325 reworks this.
argus merged commit 3468a08df9 into main 2026-10-13 10:33:03 +00:00
argus deleted branch loop/324-two-majors 2026-10-13 10:33:04 +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!360
No description provided.