Section 4: Module System
Goal: Multi-file compilation
SPEC:
spec/18-modules.md
DESIGN:design/09-modules/index.md
PROPOSAL:proposals/approved/no-circular-imports-proposal.md— Circular import rejection
PROPOSAL:proposals/approved/module-system-details-proposal.md— Entry points, re-export chains, visibility
Status: In-progress — Core evaluator complete (4.1-4.6), LLVM multi-file infrastructure present (dependency graph, topological sort, symbol mangling), tooling pending (4.7), module details pending (4.8), constants parser done / evaluator pending (4.11), extension parser + basic evaluator done / type checker pending (4.12). Verified 2026-03-29.
4.1 Module Definition
-
Implement: Module structure — spec/18-modules.md § Module Structure
- Rust Tests:
oric/src/imports/tests.rs— 14 tests: path resolution, test module detection, parent module import rules, cycle detection;ori_eval/src/module_registration/tests.rs— 9 tests: function/variant/newtype/impl/extend/def_impl registration - Ori Tests:
tests/spec/modules/use_imports.ori(13 tests, pub/private functions, types, closures, higher-order functions, config vars) - LLVM Support: LLVM codegen for module loading — multi_file.rs infrastructure exists (451 lines, dep graph, topo sort, module-qualified mangling), no integration tests
- LLVM Rust Tests:
ori_llvm/tests/module_tests.rs— module loading codegen (file does not exist) - AOT Tests: No AOT coverage yet
- Rust Tests:
-
Implement: Module corresponds to file — spec/18-modules.md § Module Structure
- Rust Tests:
oric/src/imports/mod.rs::resolve_relative_import_tracked()— probes<path>.orithen<path>/mod.ori - Ori Tests:
tests/spec/modules/_test/directory_module.test.ori— directory module resolution
- Rust Tests:
-
Implement: Module name from file path — spec/18-modules.md § Module Structure
- Rust Tests:
oric/src/imports/tests.rs—generate_relative_candidates_file_module,_parent_path,_nested_directory,_with_extension(4 tests);ori_llvm/src/aot/multi_file/tests.rs—derive_module_name(3 tests) - Ori Tests: N/A (tested via Rust unit tests)
- Rust Tests:
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (4.1) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.1 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.1: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
4.2 Import Parsing
Relative imports:
Module imports:
Private imports:
Aliases:
-
Implement:
use './path' { item1, item2 }— spec/18-modules.md § Relative Imports- Rust Tests:
oric/src/imports/tests.rs— path resolution tests - Ori Tests:
tests/spec/modules/_test/use_imports.test.ori(4 tests: add, make_multiplier, calculate, double)
- Rust Tests:
-
Implement: Parent
use '../utils' { helper }— spec/18-modules.md § Relative Imports- Rust Tests:
oric/src/imports/tests.rs::generate_relative_candidates_parent_path - Ori Tests:
tests/spec/modules/_test/use_imports.test.ori(uses"../use_imports")
- Rust Tests:
-
Implement: Subdirectory
use './http/client' { get }— spec/18-modules.md § Relative Imports WEAK TESTS- Rust Tests:
oric/src/imports/tests.rs::generate_relative_candidates_nested_directory - Ori Tests: N/A (tested via Rust unit tests only)
- Gap: Need Ori spec test for subdirectory relative imports (currently Rust unit test only, no end-to-end
.oritest)
- Rust Tests:
-
Implement:
use std.module { item }— spec/18-modules.md § Module Imports- Rust Tests:
oric/src/imports/tests.rs::resolve_module_path_not_found— stdlib path resolution - Ori Tests: 415 of 882 spec/library
.orifiles usestd.testing(406 import{ assert_eq })
- Rust Tests:
-
Implement: Nested
use std.net.http { get }— spec/18-modules.md § Module Imports- Rust Tests: Parser supports multi-segment paths (verified via
test_import_without_def_basic); no runtime test - Ori Tests: N/A — no nested stdlib modules exist yet to test
- Rust Tests: Parser supports multi-segment paths (verified via
-
Implement:
use './path' { ::private_item }— spec/18-modules.md § Private Imports- Rust Tests:
oric/tests/phases/parse/imports.rs::test_import_private_basic,test_import_private_with_alias - Ori Tests:
tests/spec/modules/_test/use_private.test.ori(2 tests: private fn access, private + public combo)
- Rust Tests:
-
Implement:
::prefix — spec/18-modules.md § Private Imports- Rust Tests: Parser tests verify
items[0].is_privateflag set for::prefix - Ori Tests:
tests/spec/modules/_test/use_private.test.ori
- Rust Tests: Parser tests verify
-
Implement:
use './math' { add as plus }— spec/18-modules.md § Aliases- Rust Tests:
ori_parse/src/grammar/— alias parsing - Ori Tests:
tests/spec/modules/_test/use_aliases.test.ori(3 tests: add as plus, make_multiplier as create_multiplier, double as twice)
- Rust Tests:
-
Implement: Module alias
use std.net.http as http— spec/18-modules.md § Aliases- Rust Tests:
ori_parse/src/grammar/— module alias parsing - Ori Tests:
tests/spec/modules/_test/module_alias.test.ori(11 tests: qualified accessmath.add(),math.subtract(),math.multiply(),math.square(),math.double(),math.make_adder(),math.use_internal()) - Note: Parsing and runtime complete; qualified access works via evaluator. Type checker ModuleNamespace support pending.
- Rust Tests:
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (4.2) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.2 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.2: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
4.3 Visibility
-
Implement:
pubon functions — spec/18-modules.md § Visibility- Rust Tests:
ori_parse/src/grammar/—pubkeyword parsing - Ori Tests:
tests/spec/modules/use_imports.ori(9 pub functions);_test/use_imports.test.oriimports 4 of them
- Rust Tests:
-
Implement:
pubon types — spec/18-modules.md § Visibility WEAK TESTS- Rust Tests:
ori_parse/src/grammar/— type visibility parsing - Ori Tests:
library/std/prelude.ori—pub type Option,pub type Result;use_imports.orihaspub type Point - Gap: No cross-module type import test —
pub type Pointis declared but never imported in a cross-module test
- Rust Tests:
-
Implement:
pubon config variables — spec/18-modules.md § Visibility [partial] INCOMPLETE- Parser: Config visibility parsing works — 6 parser tests in
oric/tests/phases/parse/imports.rs - Ori Declaration:
tests/spec/modules/use_imports.ori(pub $default_timeout, private$internal_limit) - Evaluator: Constant import resolution NOT implemented —
_test/use_constants.test.oriis#skip("constant import resolution not yet implemented") - Note: Parser done, evaluator not done. Previously marked [x] incorrectly — reopened
- Parser: Config visibility parsing works — 6 parser tests in
-
Implement: Re-exports
pub use— spec/18-modules.md § Re-exports WEAK TESTS- Rust Tests:
ori_parse/src/grammar/— re-export parsing - Ori Tests:
tests/spec/modules/reexporter.ori(pub use "./math_lib" { add, multiply }, self-test only) - Gap: No cross-module re-export consumption test —
reexporter.oritests itself but no file imports from it - Note: Basic re-export works; multi-level chain resolution pending (4.8)
- Rust Tests:
-
Implement: Private by default — spec/18-modules.md § Visibility NEEDS PIN
- Rust Tests:
oric/src/imports/tests.rs— visibility enforcement - Ori Tests:
tests/spec/modules/_test/use_private.test.ori(private access with::prefix) - Gap: No
#compile_failtest for importing a private item without::from a non-test module
- Rust Tests:
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (4.3) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.3 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.3: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
4.4 Module Resolution
-
Implement: File path resolution — spec/18-modules.md § Module Resolution
- Rust Tests:
oric/src/imports/tests.rs— 4 candidate generation tests (generate_relative_candidates_*) - Ori Tests:
tests/spec/modules/_test/directory_module.test.ori(2 tests),_test/precedence.test.ori(file precedence over dir)
- Rust Tests:
-
Implement: Module dependency graph — spec/18-modules.md § Dependency Graph
- Rust Tests:
oric/src/imports/tests.rs—LoadingContextcycle detection;ori_llvm/src/aot/incremental/deps/tests.rs— 12 tests - Ori Tests: N/A (tested via Rust unit tests)
- Note: Both eval (via Salsa) and LLVM (explicit
DependencyGraph) have dependency tracking with tests
- Rust Tests:
-
Implement: Cycle detection — spec/18-modules.md § Cycle Detection, proposals/approved/no-circular-imports-proposal.md
- Rust Tests:
oric/src/imports/tests.rs—loading_context_cycle_detection,loading_context_cycle_error;ori_llvm/src/aot/multi_file/tests.rs::test_graph_build_context_cycle_detection - Ori Tests: N/A (tested via Rust unit tests)
- Note: Both eval and LLVM backends have cycle detection
- Rust Tests:
-
Implement: Enhanced cycle error messages — proposals/approved/no-circular-imports-proposal.md § Error Message
- Show full cycle path in error (a.ori -> b.ori -> a.ori)
- Include actionable help: “extract shared types”, “use dependency inversion”, “restructure boundaries”
- Rust Tests:
oric/src/imports/tests.rs— cycle error formatting tests - Ori Tests:
tests/spec/modules/cycle_error_message.ori
-
Implement: Report all cycles (not just first) — proposals/approved/no-circular-imports-proposal.md § Detection Algorithm
- Continue detection after finding first cycle
- Report each cycle with full path
- Rust Tests:
oric/src/imports/tests.rs— multi-cycle detection tests - Ori Tests:
tests/spec/modules/multiple_cycles.ori
-
Implement: Name resolution — spec/18-modules.md § Name Resolution
- Rust Tests: All import test files exercise name resolution
- Ori Tests: All import tests verify name resolution (use_imports, use_private, use_aliases, module_alias)
-
Implement: Qualified access — spec/18-modules.md § Qualified Accessevaluator
- Rust Tests: Qualified access evaluation tested via module_alias tests
- Ori Tests:
tests/spec/modules/_test/module_alias.test.ori(11 tests:math.add(),math.multiply(), etc.) - LLVM Support: LLVM codegen for qualified access dispatch — multi_file.rs has module-qualified mangling (
_ori_<module>$<function>) - LLVM Rust Tests:
ori_llvm/tests/module_tests.rs— qualified access codegen (file does not exist) - AOT Tests: No AOT coverage yet
- Note: Runtime evaluation complete; type checker needs ModuleNamespace support
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (4.4) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.4 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.4: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
4.5 Test Modules
-
Implement:
_test/convention — spec/18-modules.md § Test Modules- Rust Tests:
oric/src/imports/tests.rs— 4is_test_moduletests: valid, not_in_test_dir, wrong_extension, nested - Ori Tests:
tests/spec/modules/_test/test_module_access.test.ori(2 tests)
- Rust Tests:
-
Implement: Test files access private items — spec/18-modules.md § Test Modules
- Rust Tests:
oric/src/imports/tests.rs— 3is_parent_module_importtests - Ori Tests:
tests/spec/modules/_test/test_module_access.test.ori(accesses privateinternal_helperwithout::prefix)
- Rust Tests:
4.6 Prelude
-
Implement: Types:
Option,Result,Error,Ordering— spec/18-modules.md § Prelude- Rust Tests:
ori_eval/src/interpreter/— built-in type tests - Ori Tests: Option/Result used throughout the spec test suite (882
.orifiles under tests/+library/), Ordering verified intests/spec/types/ordering/ - LLVM Support: LLVM codegen for prelude type representations — Option/Result have inline IR in lower_calls.rs
- LLVM Rust Tests:
ori_llvm/tests/module_tests.rs— prelude type codegen (file does not exist) - AOT Tests: No AOT coverage yet
- Rust Tests:
-
Implement: Built-in functions:
print,panic,int,float,str,byte— spec/18-modules.md § Prelude- Rust Tests:
register_prelude()registers 8 function_vals; print/panic registered separately - Ori Tests: Built-ins used throughout test suite
- LLVM Support: LLVM codegen for built-in functions —
printvia_ori_print,panicvia_ori_panic, conversions via inline IR - LLVM Rust Tests:
ori_llvm/tests/module_tests.rs— built-in function codegen (file does not exist) - AOT Tests: No AOT coverage yet
- Rust Tests:
-
Implement: Built-in methods:
.len(),.is_empty(),.is_some(), etc. — Lean Core- Rust Tests:
ori_eval/src/methods.rs— method dispatch tests - Ori Tests:
tests/spec/traits/core/— len (14 tests), comparable (58 tests);tests/spec/types/— option, result tests - LLVM Support: LLVM codegen for built-in methods — inline IR in
lower_calls.rs(len, is_empty, is_some, is_none, unwrap, unwrap_or, is_ok, is_err, compare) - LLVM Rust Tests:
ori_llvm/tests/module_tests.rs— built-in method codegen (file does not exist) - AOT Tests: No AOT coverage yet
- Rust Tests:
-
Implement: Auto-import prelude from
library/std/prelude.ori— spec/18-modules.md § Preluderesolve_imports()loads prelude viaprelude_candidates()walk-up search- All public functions from prelude available without import
- Rust Tests:
ori_eval/src/interpreter/— prelude loading tests - Ori Tests: 415 of 882 spec/library
.orifiles usestd.testing(406 import{ assert_eq }), which depends on prelude - LLVM Support: LLVM codegen for prelude auto-loading
- LLVM Rust Tests:
ori_llvm/tests/module_tests.rs— prelude loading codegen (file does not exist) - AOT Tests: No AOT coverage yet
-
Implement: Prelude functions auto-available
assert,assert_eq,assert_ne,assert_some,assert_none,assert_ok,assert_erris_some,is_none,is_ok,is_errlen,is_emptycompare,min,max- LLVM Support: LLVM codegen for prelude functions — partial (print, panic, len, compare have IR; assert_* not yet)
- LLVM Rust Tests:
ori_llvm/tests/module_tests.rs— prelude function codegen (file does not exist) - AOT Tests: No AOT coverage yet
- Note: Trait definitions in prelude (Eq, Comparable, etc.) parse but need Section 3 for full integration
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (4.6) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.6 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.6: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
4.7 Import Graph Tooling
PROPOSAL:
proposals/approved/no-circular-imports-proposal.md § Tooling Support
-
Implement:
ori check --cycles— Check for cycles without full compilation- Fast path: parse imports only, build graph, detect cycles
- Rust Tests:
oric/src/commands/— cycle checking tests - Ori Tests:
tests/cli/check_cycles.ori
-
Implement:
ori graph --imports— Visualize import graph- Output DOT format for graphviz
- Usage:
ori graph --imports > imports.dot && dot -Tpng imports.dot -o imports.png - Rust Tests:
oric/src/commands/— graph output tests - Ori Tests:
tests/cli/graph_imports.ori
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (4.7) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.7 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.7: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
4.8 Module System Details
PROPOSAL:
proposals/approved/module-system-details-proposal.md
Entry Point Files
-
Implement:
lib.orias library entry point — spec/18-modules.md § Entry Point Files- Rust Tests:
ori_eval/src/interpreter/module/— library entry detection - Ori Tests:
tests/spec/modules/library_entry.ori
- Rust Tests:
-
Implement: Distinguish
lib.orivsmod.ori— spec/18-modules.md § Entry Point Files- Package root requires
lib.ori, notmod.ori - Rust Tests:
ori_eval/src/interpreter/module/— entry point validation - Ori Tests:
tests/spec/modules/entry_point_validation.ori
- Package root requires
Binary-Library Separation
-
Implement: Binary accesses library via public API only — spec/18-modules.md § Library + Binary
use "my_pkg" { item }accesseslib.oriexportsuse "my_pkg" { ::private }is an error (no private access)- Rust Tests:
ori_eval/src/interpreter/module/— binary-library access tests - Ori Tests:
tests/spec/modules/binary_library_access.ori
Re-export Chains
-
Implement: Multi-level re-export resolution — spec/18-modules.md § Re-export Chains
- Track visibility through chain (all levels must be
pub) - Aliases propagate through chains
- Rust Tests:
ori_eval/src/interpreter/module/— re-export chain tests - Ori Tests:
tests/spec/modules/reexport_chain.ori
- Track visibility through chain (all levels must be
-
Implement: Diamond re-exports — spec/18-modules.md § Re-export Chains
- Same item via multiple paths is not an error
- Rust Tests:
ori_eval/src/interpreter/module/— diamond import tests - Ori Tests:
tests/spec/modules/diamond_reexport.ori
Error Messages
-
Implement: E1101 (missing module) — proposals/approved/module-system-details-proposal.md § Error Messages
- Show paths checked:
file.ori,file/mod.ori - Rust Tests:
ori_diagnostic/src/— error formatting tests - Ori Tests:
tests/spec/modules/error_missing_module.ori
- Show paths checked:
-
Implement: E1102 (missing export) — proposals/approved/module-system-details-proposal.md § Error Messages
- Show available exports in error message
- “Did you mean?” suggestion
- Rust Tests:
ori_diagnostic/src/— error formatting tests - Ori Tests:
tests/spec/modules/error_missing_export.ori
-
Implement: E1103 (private item) — proposals/approved/module-system-details-proposal.md § Error Messages
- Help text: “use
::itemfor explicit private access” - Rust Tests:
ori_diagnostic/src/— error formatting tests - Ori Tests:
tests/spec/modules/error_private_item.ori
- Help text: “use
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (4.8) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.8 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.8: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
4.9 Remaining Work (Pre-existing)
Parsing/Runtime complete, type checker pending:
-
Module alias syntax:
use "../math_lib" as math— parsing, runtime -
Re-exports:
pub use './client' { get, post }— basic parsing, basic resolution WEAK TESTS- Gap: No cross-module re-export consumption test
-
Qualified access:
module.function()— runtime -
Type checker ModuleNamespace support — pending
-
Multi-level re-export chain resolution — pending (4.8)
-
Nested stdlib modules (
std.net.http) — no modules to test yet -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (4.9) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.9 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.9: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
4.11 Module-Level Constants
Source: grammar.ebnf § constant_decl, spec/12-constants.md
Module-level constants declared with let $NAME = value.
let $PI = 3.14159
let $MAX_SIZE: int = 1000
pub let $VERSION = "1.0.0"
Status: Parser complete, evaluator incomplete.
Parser
-
Implement: Parse
let $NAME = value—constant_declproduction- Rust Tests:
compiler/ori_parse/src/grammar/item/config/mod.rs—parse_const()implementation;oric/tests/phases/parse/imports.rs—test_import_constant_basic,_multiple,_mixed_with_regular,_mixed_with_private(6 tests) - Ori Tests:
tests/spec/modules/use_imports.ori— declarespub $default_timeout = 30and$internal_limit = 100
- Rust Tests:
-
Implement: Parse typed constants
let $NAME: Type = value- Rust Tests:
oric/tests/phases/parse/imports.rs— constant parsing tests cover typed forms
- Rust Tests:
-
Implement: Parse public constants
pub let $NAME = value- Rust Tests:
oric/tests/phases/parse/imports.rs— visibility parsing for constants
- Rust Tests:
Evaluator
-
Implement: Evaluate module-level constants at load time
- Rust Tests:
ori_eval/src/interpreter/mod.rs— constant evaluation - Ori Tests:
tests/spec/declarations/constants_eval.ori - LLVM Support: LLVM codegen for module constants
- LLVM Rust Tests:
ori_llvm/tests/constant_tests.rs - AOT Tests: No AOT coverage yet
- Rust Tests:
-
Implement: Register constants in module namespace
- Rust Tests:
ori_eval/src/interpreter/module_loading.rs— constant registration - Ori Tests:
tests/spec/modules/import_constants.ori
- Rust Tests:
Type Checker
-
Implement: Type check constant initializers
- Rust Tests:
ori_types/src/check/— constant type checking - Ori Tests:
tests/spec/types/constant_types.ori
- Rust Tests:
-
Implement: Enforce constant expression restrictions (no function calls with side effects)
- Rust Tests:
ori_types/src/check/— constant expression validation - Ori Compile-Fail Tests:
tests/compile-fail/constant_non_const_expr.ori
- Rust Tests:
Import/Export
-
Implement: Export constants via
pub let- Ori Tests:
tests/spec/modules/export_constants.ori
- Ori Tests:
-
Implement: Import constants via
use "path" { $CONST }- Ori Tests:
tests/spec/modules/import_constants.ori
- Ori Tests:
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (4.11) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.11 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.11: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
4.12 Extension Methods
PROPOSAL:
proposals/approved/extension-methods-proposal.md
Extension methods add methods to existing types without modifying their definition.
Status: Parser and basic evaluator complete. Type checker integration, conflict detection, orphan rules, error codes (E0850-E0852), LLVM codegen pending.
Extension Definition
-
Implement:
extend Type { @method (self) -> T = ... }— proposals/approved/extension-methods-proposal.md § Extension Definition [partial]- Parse
extendblocks —compiler/ori_parse/src/grammar/item/extend.rs - Register extension methods in type environment —
ori_eval/src/module_registration/tests.rshastest_collect_extend_methodsandtest_collect_extend_methods_with_config(2 tests) - Rust Tests:
oric/tests/phases/parse/extensions.rs— 12 parser tests: extend with where clause, multiple bounds, multiple methods, extension import variants - Ori Tests:
tests/spec/extensions/list_methods.ori— end-to-end test withextend str { @shout, @whisper }andextend [T] { @count, @empty } - Type Checker: Type checker integration for extension method resolution — not implemented
- Conflict Detection: Conflict detection for ambiguous extension methods — not implemented
- Parse
-
Implement: Constrained extensions with angle brackets — proposals/approved/extension-methods-proposal.md § Constrained Extensions
- Parse
extend<T: Clone> [T] { ... }syntax — parser supports this - Type checker constraint enforcement
- Ori Tests:
tests/spec/extensions/constrained.ori
- Parse
-
Implement: Constrained extensions with where clause — proposals/approved/extension-methods-proposal.md § Constrained Extensions
- Parse
extend [T] where T: Clone { ... }syntax — parser supports this - Type checker where clause enforcement
- Ori Tests:
tests/spec/extensions/constrained_where.ori
- Parse
-
Implement: Extension visibility — proposals/approved/extension-methods-proposal.md § Visibility
pub extendmakes all methods public- Non-pub
extendis module-private - Block-level visibility only (no per-method pub)
- Rust Tests:
ori_eval/src/interpreter/module/— visibility tests - Ori Tests:
tests/spec/extensions/visibility.ori
-
Implement: Extension restrictions — proposals/approved/extension-methods-proposal.md § What Can Be Extended
- Error on field addition attempt
- Error on trait implementation in extend block
- Error on override of existing method
- Error on static method (no self)
- Rust Tests:
ori_diagnostic/src/— restriction error tests - Ori Tests:
tests/spec/extensions/restrictions.ori
Extension Import
-
Implement:
extension "path" { Type.method }— proposals/approved/extension-methods-proposal.md § Extension Import [partial]- Parse
extensionimport syntax —compiler/ori_parse/src/grammar/item/extension_import.rs - Method-level granularity — parser enforces method-level granularity
- Rust Tests:
oric/tests/phases/parse/extensions.rs— extension import tests: basic, multiple items, relative path, public, private, with regular imports, multiple types, missing dot error - Ori Tests:
tests/spec/extensions/import.ori— end-to-end extension import test (not yet created) - Runtime: Extension import resolution in evaluator — not implemented
- Parse
-
Implement: Wildcard prohibition — proposals/approved/extension-methods-proposal.md § Import Syntax
- Error on
extension "path" { Type.* } - Rust Tests:
ori_diagnostic/src/— wildcard error tests - Ori Tests:
tests/spec/extensions/no_wildcard.ori
- Error on
-
Implement: Re-export extensions — proposals/approved/extension-methods-proposal.md § Scoping
pub extension "path" { Type.method }for re-export- No transitive propagation without explicit re-export
- Rust Tests:
ori_eval/src/interpreter/module/— re-export tests - Ori Tests:
tests/spec/extensions/reexport.ori
Method Resolution
-
Implement: Resolution order — proposals/approved/extension-methods-proposal.md § Resolution Order
- Inherent > Trait > Extension
- Rust Tests:
ori_types/src/check/— resolution order tests - Ori Tests:
tests/spec/extensions/resolution_order.ori
-
Implement: Conflict detection — proposals/approved/extension-methods-proposal.md § Conflict Resolution
- Error on ambiguous extension methods
- Qualified syntax for disambiguation:
module.Type.method(v) - Rust Tests:
ori_types/src/check/— conflict detection tests - Ori Tests:
tests/spec/extensions/conflict.ori
Orphan Rules
-
Implement: Same-package rule — proposals/approved/extension-methods-proposal.md § Orphan Rules
- Extension must be in same package as type OR trait bound
- Error for foreign type without local trait bound
- Rust Tests:
ori_types/src/check/— orphan rule tests - Ori Tests:
tests/spec/extensions/orphan.ori
Error Messages
-
Implement: E0850 (ambiguous extension) — proposals/approved/extension-methods-proposal.md § Error Messages
- Show all candidate extensions
- Help text for qualified syntax
- Rust Tests:
ori_diagnostic/src/— error formatting tests - Ori Tests:
tests/spec/extensions/error_ambiguous.ori
-
Implement: E0851 (method not found) — proposals/approved/extension-methods-proposal.md § Error Messages
- Suggest extension import if method exists in known module
- Rust Tests:
ori_diagnostic/src/— error formatting tests - Ori Tests:
tests/spec/extensions/error_not_found.ori
-
Implement: E0852 (orphan violation) — proposals/approved/extension-methods-proposal.md § Error Messages
- Show package location of foreign type
- Help: “define a newtype wrapper or use a local trait bound”
- Rust Tests:
ori_diagnostic/src/— error formatting tests - Ori Tests:
tests/spec/extensions/error_orphan.ori
LLVM Support
Note on Type Definitions:
- Full prelude with user-defined Option, Result, etc. requires Section 5 (Type Declarations)
- Currently using built-in types in evaluator
- See section-05-type-declarations.md § 5.1-5.4 for type definition work
-
Implement: Extension method codegen — Extension methods in LLVM backend
- Same codegen as regular methods
- LLVM Rust Tests:
ori_llvm/tests/extension_tests.rs - AOT Tests: No AOT coverage yet
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (4.12) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.12 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.12: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
4.10 Section Completion Checklist
Exit Criteria: Multi-file projects compile (core support complete) Status: Section 4 evaluator and parser complete. 27 of 35 [x] items fully verified, 4 have weak tests, 1 incomplete (config var imports reopened), 1 needs negative pin. LLVM multi-file infrastructure present (15 unit tests, zero integration tests). Extension parser and basic evaluator ahead of roadmap. Constant parser ahead of roadmap. Verified 2026-03-29.
- Core module imports working (relative, module, private, aliases)
- Visibility system working (
pub, private by default,::) — note:pubon config vars parser-only, evaluator incomplete - Module resolution working (path resolution, stdlib lookup, directory modules, file precedence)
- Cycle detection working (Rust unit tests:
loading_context_cycle_*inoric/src/imports/tests.rs) - Test module private access working (
_test/convention,test_module_access.test.ori) - Built-in prelude types and functions working (Option, Result, Ordering, print, panic, etc.)
- Auto-load stdlib prelude (
use std.testingworks across the 415 of 882 spec/library.orifiles that import it) -
Selftype parsing in traits (see Section 3) - Trait/impl parsing at module level (see Section 3)
- Module alias syntax (
use "../path" as alias) — parsing/runtime complete - Re-exports (
pub use) — basic parsing/resolution complete WEAK TESTS — self-test only, no cross-module consumption - Qualified access (
module.function()) — runtime complete - Type checker ModuleNamespace support — pending
- LLVM multi-file AOT compilation — infrastructure exists (multi_file.rs, 15 unit tests), no integration tests
- Enhanced cycle error messages (4.4) — pending
- Type definitions parsing (see Section 5)
- Module system negative tests — zero
#compile_failtests exist for the module system - Cross-module type import test —
pub type Pointdeclared but never imported cross-module - Cross-module re-export consumption test —
reexporter.oritests itself but nobody imports from it -
oric/src/imports/mod.rsfile split — 603 lines, exceeds 500-line limit - Run full test suite:
./test-all.sh -
/tpr-reviewpassed — independent Codex review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — implementation hygiene review clean (phase boundaries, SSOT, algorithmic DRY, naming). MUST run AFTER/tpr-reviewis clean. -
/improve-toolingretrospective completed — MANDATORY at section close, after both reviews are clean. Reflect on the section’s debugging journey (whichdiagnostics/scripts you ran, which command sequences you repeated, where you added ad-hocdbg!/tracingcalls, where output was hard to interpret) and identify any tool/log/diagnostic improvement that would have made this section materially easier OR that would help the next section touching this area. Implement every accepted improvement NOW (zero deferral) and commit each via SEPARATE/commit-push. The retrospective is mandatory even when nothing felt painful — that is exactly when blind spots accumulate. See.claude/skills/improve-tooling/SKILL.md“Retrospective Mode” for the full protocol. -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) - Subsection close-out (4.10) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.10 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.10: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. - Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.