Section 3: Traits and Implementations
Goal: Trait-based polymorphism
SPEC:
spec/09-properties-of-types.md,spec/10-declarations.md
Status: In-progress — Core evaluator complete (3.0-3.7, 3.14, 3.16, 3.18-3.21). LLVM AOT: 88 trait tests, 43 derive tests, 17 formattable tests, 26 iterator tests — all passing. 4181 spec tests pass, 0 fail, 42 skip. Evaluator verified complete for all subsections through 3.21. LLVM gaps remain for: Debug (3.9), Traceable (3.13), iterator advanced features (3.8), Index (3.12), derived sum/generic/recursive (3.15). Not started: 3.23 (impl colon syntax), 3.24 (Value trait). 3.22 eliminated per capability-unification decision. Last verified 2026-03-29.
Implementation Location
SYNC POINT: Adding a new derived trait (e.g.,
Debug,Comparable,Reflect) requires updating ALL 5 crates simultaneously. See CLAUDE.md “Adding a New Derived Trait” and memory “Derived Trait Sync — DO NOT” for the full protocol:ori_ir(DerivedTrait enum),ori_types(registration),ori_eval(eval dispatch),ori_llvm(codegen),library/std/prelude.ori(trait definition).
All items in this section (3.0-3.21) are implemented in ori_types (the unified type checker crate).
Key Files:
ori_types/src/check/registration/— Trait/impl registrationori_types/src/check/bounds/— Constraint satisfaction and bound checkingori_types/src/infer/— Type inference including built-in method signatures
PRIORITY NOTE
Per the “Lean Core, Rich Libraries” principle, most built-in functions have been moved from the compiler core to trait methods. The compiler now only provides:
Remaining built-ins:
print(msg: str)- I/Opanic(msg: str)- Control flow
Moved to traits (must implement in this section):
len(collection)->Lentrait with.len()methodis_empty(collection)->IsEmptytrait with.is_empty()methodis_some(option),is_none(option)->Optionmethodsis_ok(result),is_err(result)->Resultmethodscompare(left, right)->Comparabletrait with.compare()methodmin(a, b),max(a, b)->Comparabletrait or standalone functions via traitsassert(condition)->Asserttrait or testing moduleassert_eq(actual, expected),assert_ne(actual, unexpected)-> Testing traits
Without traits, tests cannot use assertions - this blocks the testing workflow.
3.0 Core Library Traits
STATUS: COMPLETE (verified 2026-03-29 — evaluator complete, map/set LLVM equals/hash pending AOT collection infrastructure)
Core library traits are implemented via:
- Runtime: Evaluator’s
MethodRegistryprovides hardcoded Rust dispatch for methods like.len(),.is_empty(),.is_some(), etc. - Type checking:
infer_builtin_method()provides type inference for these methods - Trait bounds:
primitive_implements_trait()inbound_checking.rsrecognizes when types implement these traits
This approach follows the “Lean Core, Rich Libraries” principle — the runtime implementation stays in Rust for efficiency, while the type system recognizes the trait bounds for generic programming.
3.0.1 Len Trait
Proposal: proposals/approved/len-trait-proposal.md (approved 2026-02-18)
- Implemented: Trait bound
Lenrecognized for[T],str,{K: V},Set<T>,Range<T>[done] (2026-02-10)- Rust Tests:
ori_types/src/check/tests.rs—test_len_bound_satisfied_by_* - Ori Tests:
tests/spec/traits/core/len.ori— 14 tests (all pass)
- Rust Tests:
- Implemented:
.len()method works on all collection types [done] (2026-02-10)- Tests:
ori_eval/src/methods.rs— list/string/range method tests - LLVM Support: LLVM codegen for
.len()— inline IR via field extraction inlower_calls.rs - AOT Tests:
ori_llvm/tests/aot/traits.rs—.len()on lists (3 tests) and strings (2 tests) [done] (2026-02-13)
- Tests:
- Implement: Add tuple
Lenbound recognition —(T₁, T₂, ...)(approved in proposal) [done] (2026-02-18)- Rust Tests:
ori_types/src/infer/expr/tests.rs—test_len_satisfied_by_tuple,test_len_satisfied_by_triple_tuple,test_len_satisfied_by_single_tuple,test_len_not_satisfied_by_result - Ori Tests:
tests/spec/traits/core/len.ori— 3 tuple len tests (pair, triple, single)
- Rust Tests:
- Implement: Update prelude
len()to use<T: Len>bound (generic function) [done] (2026-02-18)- Implement: Add
Lentrait definition tolibrary/std/prelude.ori - Ori Tests:
tests/spec/traits/core/len.ori— generic len tests (str, list, tuple via<T: Len>bound)
- Implement: Add
- Spec: Add
Len Traitsection to09-properties-of-types.md[done] (2026-02-18)
3.0.2 IsEmpty Trait
Proposal: proposals/approved/is-empty-trait-proposal.md (approved 2026-02-21)
- Implemented: Trait bound
IsEmptyrecognized for[T],str,{K: V},Set<T>[done] (2026-02-10)- Rust Tests:
ori_types/src/check/tests.rs—test_is_empty_bound_satisfied_by_* - Ori Tests:
tests/spec/traits/core/is_empty.ori— 13 tests (all pass)
- Rust Tests:
- Implemented:
.is_empty()method works on all collection types [done] (2026-02-10)- Tests:
ori_eval/src/methods.rs— list/string method tests - LLVM Support: LLVM codegen for
.is_empty()— inline IR inlower_calls.rs - AOT Tests:
ori_llvm/tests/aot/traits.rs—.is_empty()on lists (2 tests) and strings (2 tests) [done] (2026-02-13)
- Tests:
- Implement: Add
Range<int>and[T, max N]to IsEmpty trait bound recognition- Rust Tests:
ori_types—test_is_empty_bound_satisfied_by_range,test_is_empty_bound_satisfied_by_fixed_list - Ori Tests:
tests/spec/traits/core/is_empty.ori— range and fixed-size list is_empty tests
- Rust Tests:
- Implement: Update prelude
is_empty()to use<T: IsEmpty>bound (generic function)- Implement: Add
IsEmptytrait definition tolibrary/std/prelude.ori - Ori Tests:
tests/spec/traits/core/is_empty.ori— generic is_empty tests (str, map via<T: IsEmpty>bound)
- Implement: Add
- Spec: Verify
IsEmpty Traitsection in09-properties-of-types.md(note: IsEmpty IS present at 9.11; previously this item referenced nonexistent07-properties-of-types.md, corrected 2026-03-29)
3.0.3 Option Methods
- Implemented:
.is_some(),.is_none(),.unwrap(),.unwrap_or(default:)methods [done] (2026-02-10)- Rust Tests:
ori_eval/src/methods.rs—option_methodsmodule - Ori Tests:
tests/spec/traits/core/option.ori— 16 tests (all pass) - LLVM Support: LLVM codegen for Option — tag-based dispatch in
lower_calls.rs - AOT Tests:
ori_llvm/tests/aot/traits.rs—.is_some()(2),.is_none()(2),.unwrap()(1),.unwrap_or()(2) all pass [done] (2026-02-13)
- Rust Tests:
- Type checking:
infer_builtin_method()handles Option methods [done] (2026-02-10)
3.0.4 Result Methods
- Implemented:
.is_ok(),.is_err(),.unwrap()methods [done] (2026-02-10)- Rust Tests:
ori_eval/src/methods.rs—result_methodsmodule - Ori Tests:
tests/spec/traits/core/result.ori— 14 tests (all pass) - LLVM Support: LLVM codegen for Result — tag-based dispatch in
lower_calls.rs - AOT Tests:
ori_llvm/tests/aot/traits.rs—.is_ok()(2),.is_err()(2),.unwrap()(1) all pass [done] (2026-02-13)
- Rust Tests:
- Type checking:
infer_builtin_method()handles Result methods [done] (2026-02-10)
3.0.5 Comparable Trait
- Implemented: Trait bound
Comparablerecognized forint,float,bool,str,char,byte,Duration,Size,[T],Option<T>,Result<T, E>,Ordering[done] (2026-02-10)- Rust Tests:
ori_types/src/check/tests.rs—test_comparable_bound_satisfied_by_* - Ori Tests:
tests/spec/traits/core/comparable.ori— 58 tests (all pass)
- Rust Tests:
- Type checking: All comparable types have
.compare(other:)returningOrdering[done] (2026-02-10)- Type Checking:
ori_types/src/infer/— numeric.rs, string.rs, list.rs, option.rs, result.rs, units.rs, ordering.rs - LLVM Support: LLVM codegen for
.compare()— inline arithmetic/comparison inlower_calls.rs - AOT Tests:
ori_llvm/tests/aot/traits.rs— 7 tests passing:.compare()+ Ordering methods (is_less, is_equal, is_greater, reverse, is_less_or_equal, is_greater_or_equal) [done] (2026-02-13)
- Type Checking:
3.0.6 Eq Trait
- Implemented: Trait bound
Eqrecognized for all primitive types [done] (2026-02-10)- Rust Tests:
ori_types/src/check/tests.rs—test_eq_bound_satisfied_by_* - Ori Tests:
tests/spec/traits/core/eq.ori— 23 tests (all pass) - LLVM Support: LLVM codegen for
==/!=on all primitives [done] - AOT Tests:
ori_llvm/tests/aot/traits.rs—==/!=for int, bool, str (3 tests) [done] (2026-02-13)
- Rust Tests:
Additional Traits
The following traits are also recognized in trait bounds:
- Clone: All primitives, collections
- Hashable:
int,bool,str,char,byte - Default:
int,float,bool,str,Unit,Option<T> - Printable: All primitives
3.1 Trait Declarations
STATUS: COMPLETE (verified 2026-03-29)
-
Implement: Parse
trait Name { ... }— spec/10-declarations.md § Trait Declarations [done] (2026-02-10)- Write test:
tests/spec/traits/declaration.ori— 16 tests (all pass) - Run test:
ori test tests/spec/traits/declaration.ori
- Write test:
-
Implement: Required method signatures — spec/10-declarations.md § Trait Declarations [done] (2026-02-10)
- Write test:
tests/spec/traits/declaration.ori— Greeter, Counter, Calculator traits - Run test: All pass
- Write test:
-
Implement: Default method implementations — spec/10-declarations.md § Trait Declarations [done] (2026-02-10)
- Write test:
tests/spec/traits/declaration.ori(test_default_method: summarize(), is_large()) - Run test: All pass
- Note: Added default trait method dispatch in
module_loading.rs:collect_impl_methods() - LLVM Support: LLVM codegen for default trait method dispatch [done] (2026-02-13)
- Fixed at 3 levels: method registration (register_impl), body type checking (check_impl_block), LLVM codegen (compile_impls)
- AOT Tests:
ori_llvm/tests/aot/traits.rs—test_aot_trait_default_methodpassing [done] (2026-02-13)
- Write test:
-
Implement: Associated types — spec/10-declarations.md § Associated Types [done] (2026-02-10)
- Rust Tests:
ori_types/src/check/tests.rs— associated type parsing - Ori Tests:
tests/spec/traits/associated_types.ori— 2 tests + 1 compile_fail (all pass)
- Rust Tests:
-
Implement:
selfparameter — spec/10-declarations.md § self Parameter [done] (2026-02-10)- Rust Tests:
ori_types/src/check/tests.rs— self parameter handling - Ori Tests:
tests/spec/traits/self_param.ori— 9 tests (all pass)
- Rust Tests:
-
Implement:
Selftype reference — spec/10-declarations.md § Self Type [done] (2026-02-10)- Rust Tests:
ori_types/src/check/tests.rs— Self type resolution - Ori Tests:
tests/spec/traits/self_type.ori— 7 tests (all pass)
- Rust Tests:
-
Implement: Trait inheritance
trait Child: Parent— spec/10-declarations.md § Trait Inheritance [done] (2026-02-10)- Rust Tests:
ori_types/src/check/tests.rs— trait inheritance - Ori Tests:
tests/spec/traits/inheritance.ori— 6 tests including 3-level deep inheritance (all pass)
- Rust Tests:
-
BUG: Static methods
Type.method()not supported — commented out in declaration.ori (Point.new(), Point.origin()) [done] (2026-02-13)- Infrastructure was already working (TypeRef dispatch in method_dispatch.rs). Test file was missing
@new/@originimpl methods + had stale TODO comments. Added methods, uncommented tests, 2 new tests pass.
- Infrastructure was already working (TypeRef dispatch in method_dispatch.rs). Test file was missing
3.2 Trait Implementations
STATUS: COMPLETE (verified 2026-03-29 — evaluator complete; LLVM generic impls intentionally deferred, no monomorphization pipeline)
-
Implement: Inherent impl
impl Type { ... }— spec/10-declarations.md § Inherent Implementations [done] (2026-02-10)- Write test:
tests/spec/traits/declaration.ori(Widget.get_name(), Widget.get_value(), Point.distance_from_origin()) - Run test: All pass
- LLVM Support: LLVM codegen — type-qualified method dispatch (
_ori_Type$methodmangling) - AOT Tests:
ori_llvm/tests/aot/traits.rs— inherent impl (3 tests: method, params, field access), impl_method_field_access (1 test) [done] (2026-02-13)
- Write test:
-
Implement: Trait impl
impl Type: Trait { ... }— spec/10-declarations.md § Trait Implementations [done] (2026-02-10)- Write test:
tests/spec/traits/declaration.ori(Widget.greet(), Widget.describe(), Widget.summarize()) - Run test: All pass
- LLVM Support: LLVM codegen — trait method dispatch (
_ori_Type$$Trait$methodmangling) - AOT Tests:
ori_llvm/tests/aot/traits.rs— trait impl (2 tests: single method, multiple methods) [done] (2026-02-13)
- Write test:
-
Implement: Generic impl
impl<T: Bound> Container<T>: Trait— spec/10-declarations.md § Generic Implementations [done] (2026-02-10)- Rust Tests: Parser tests in
ori_parse/src/grammar/item.rs - Ori Tests:
tests/spec/traits/generic_impl.ori— 4 tests (inherent + trait impls on generic types, all pass) - Note: Added
parse_impl_type()to handleBox<T>syntax in impl blocks. Also addedType::Appliedfor tracking instantiated generic types with their type arguments. - LLVM Support: LLVM codegen for generic impl method dispatch — not explicitly tested (no monomorphization)
- LLVM Rust Tests: Skipped — generic functions are skipped in AOT codegen (no monomorphization pipeline)
- Rust Tests: Parser tests in
-
Implement: Where clauses — spec/10-declarations.md § Where Clauses [done] (2026-02-10)
- Rust Tests:
ori_types/src/check/tests.rs— where clause parsing - Ori Tests:
tests/spec/traits/associated_types.ori—where C.Item: Eqverified
- Rust Tests:
-
Implement: Method resolution in type checker — spec/10-declarations.md § Method Resolution [done] (2026-02-10)
TraitRegistry.lookup_method()checks inherent impls, then trait impls, then default methodsinfer_method_call()uses trait registry, falls back to built-in methods- Rust Tests: Covered by existing tests in
typeck/infer/call.rs - Ori Tests:
tests/spec/traits/declaration.ori,tests/spec/traits/generic_impl.ori,tests/spec/traits/method_call_test.ori - LLVM Support: 4-tier dispatch: built-in → type-qualified → bare-name → LLVM module lookup
- AOT Tests:
ori_llvm/tests/aot/traits.rs— method resolution (1 test: inherent takes priority over trait impl) [done] (2026-02-13)
-
Implement: User-defined impl method dispatch in evaluator [done] (2026-02-10)
- Created
UserMethodRegistryto store impl method definitions - Methods registered via
load_module->register_impl_methods eval_method_callchecks user methods first, falls back to built-in- Added
self_pathtoImplDefAST for type name resolution - Write test: Rust unit tests in
eval/evaluator.rs(4 tests covering dispatch, self access, args, fallback) - Run test: All pass
- LLVM Support: LLVM codegen for user-defined impl method dispatch —
compile_impls()infunction_compiler.rs - AOT Tests:
ori_llvm/tests/aot/traits.rs— user method dispatch covered by inherent impl and trait impl tests [done] (2026-02-13)
- Created
-
Implement: Coherence checking — spec/10-declarations.md § Coherence [done] (2026-02-10)
register_implreturnsResult<(), CoherenceError>and checks for conflicts- Duplicate trait impls for same type rejected
- Duplicate inherent methods on same type rejected
- Multiple inherent impl blocks allowed if methods don’t conflict (merged)
- Added
E2010error code for coherence violations - Write test: Rust unit tests in
typeck/type_registry.rs(3 tests) - Run test: All pass
3.3 Trait Bounds
Complete Implementation: [done] (verified 2026-02-14, re-verified 2026-03-29)
- Parser supports generic parameters with bounds
<T: Trait>,<T: A + B>—parse_generics()+parse_bounds()inori_parse/src/grammar/item/generics/mod.rs - Parser supports where clauses
where T: Clone, U: Default—parse_where_clauses()inori_parse/src/grammar/item/generics/mod.rs -
FunctionAST node storesgenerics: GenericParamRangeandwhere_clauses: Vec<WhereClause>—ori_ir/src/ast/items/function.rs -
FunctionSigin type checker storestype_param_bounds: Vec<Vec<Name>>with bounds —ori_types/src/output/mod.rs -
ParamAST stores type annotation asty: Option<ParsedType>—ori_ir/src/ast/items/function.rs - Type parsing captures identifier names implicitly in
ParsedTypenodes —ori_parse/src/grammar/ty/mod.rs -
infer_function_signature_with_arena()creates fresh type vars for generics and maps params —ori_types/src/check/signatures/mod.rs -
signatures: FxHashMap<Name, FunctionSig>stores signatures for call-time lookup —ori_types/src/check/mod.rs - Bound checking at call sites via inline checks +
type_satisfies_trait()—ori_types/src/infer/expr/calls.rs - E2009 error code for missing trait bound violations —
ori_diagnostic/src/error_code/mod.rs - Unit tests verify end-to-end —
ori_parse/src/grammar/item/generics/tests.rs(5 where-clause tests),ori_parse/src/grammar/ty/tests.rs(trait bound tests),ori_types/src/infer/expr/tests.rs
What Works Now:
- Parsing generic functions:
@compare<T: Comparable> (a: T, b: T) -> Ordering - Parsing multiple bounds:
@process<T: Eq + Clone> (x: T) -> T - Parsing where clauses:
@transform<T> (x: T) -> T where T: Clone = x - Constraint satisfaction checking at call sites
- Error messages when types don’t satisfy required bounds
Implementation Details:
-
Param.tystores type annotations asParsedType; generic parameter names resolved viaFunctionSig.type_params -
FunctionSig.type_param_boundsstores bounds per generic parameter asVec<Vec<Name>> -
infer_function_signature_with_arena()creates fresh type vars and buildsgeneric_param_mapping -
When a param’s type matches a generic, the type var is used instead of inferring
-
Bound checking in
calls.rsresolves type vars after unification and verifies trait impls -
type_satisfies_trait()uses trait registry to verify implementations -
Implement: Single bound
<T: Trait>— spec/10-declarations.md § Generic Declarations [done] (2026-02-10)- Write test: Rust unit tests in
typeck/checker.rs::tests(10 tests pass) - Run test: All pass
- Write test: Rust unit tests in
-
Implement: Multiple bounds
<T: A + B>— spec/10-declarations.md § Generic Declarations [done] (2026-02-10)- Write test:
test_multiple_bounds_parsingin Rust unit tests - Run test: All pass
- Write test:
-
Implement: Constraint satisfaction checking — spec/09-properties-of-types.md § Trait Bounds [done] (2026-02-10)
- Rust Tests:
ori_types/src/check/tests.rs— 10+ constraint satisfaction tests - Ori Tests:
tests/spec/traits/associated_types.ori—needs_eq_item+compile_failfor violated bound
- Rust Tests:
3.4 Associated Types
STATUS: COMPLETE (verified 2026-03-29)
Infrastructure implemented:
-
ParsedType::AssociatedTypevariant inori_ir/src/parsed_type.rs -
Type::Projectionvariant inori_types/src/lib.rs -
Parser handles
Self.ItemandT.Itemsyntax in type positions -
ImplAssocTypefor associated type definitions in impl blocks -
ImplEntry.assoc_typesstores associated type definitions -
TraitRegistry.lookup_assoc_type()resolves associated types -
Implement: Associated type declarations — spec/10-declarations.md § Associated Types [done] (2026-02-10)
- Rust Tests:
ori_parse/src/grammar/ty.rs— associated type parsing tests - Ori Tests:
tests/spec/traits/associated_types.ori— 2 tests (all pass) - Ori Tests:
tests/spec/traits/associated_types_verify.ori— 2 tests (all pass)
- Rust Tests:
-
Implement: Constraints
where T.Item: Eq— spec/10-declarations.md § Where Clauses [done] (2026-02-10)- Rust Tests: Parser/type checker support in
bound_checking.rs - Ori Tests:
tests/spec/traits/associated_types.ori—test_fnbox_fails_eq_constraintcompile_fail passes - Note: Added
WhereConstraintstruct with projection support. Parser handleswhere C.Item: Eq. Bound checking resolves associated types vialookup_assoc_type_by_name().
- Rust Tests: Parser/type checker support in
-
Implement: Impl validation (require all associated types defined) [done] (2026-02-10)
- Rust Tests:
ori_types/src/check/registration/ (trait registration)—validate_associated_types - Ori Tests:
tests/compile-fail/impl_missing_assoc_type.ori— test exists and passes [done] (verified 2026-02-14) - Note: Added validation in
register_impls()that checks all required associated types are defined.
- Rust Tests:
3.5 Derive Traits
STATUS: COMPLETE (verified 2026-03-29 — all 7 DerivedTrait variants synced across ori_ir, ori_types, ori_eval, ori_llvm)
All 5 derive traits implemented in ori_types/src/check/ (derives).
BLOAT:
compiler/ori_eval/src/interpreter/derived_methods.rsis 504 lines — at the 500-line limit. Monitor for growth. Tests attests/spec/traits/derive/all_derives.ori(7 tests pass).
-
Implement: Auto-implement
Eq— spec/10-declarations.md § Attributes [done] (2026-02-10)- Rust Tests:
ori_types/src/check/ (derives)—test_process_struct_derives - Ori Tests:
tests/spec/traits/derive/all_derives.ori+tests/spec/traits/derive/eq.ori— 3+13 tests (all pass) - LLVM Support: Synthetic LLVM IR for derived Eq — field-by-field
icmp eqwith short-circuit AND [done] (2026-02-13) - AOT Tests:
ori_llvm/tests/aot/derives.rs— 4 AOT tests (basic, strings, mixed types, single field) [done] (2026-02-13)
- Rust Tests:
-
Implement: Auto-implement
Clone— spec/10-declarations.md § Attributes [done] (2026-02-10)- Rust Tests:
ori_types/src/check/ (derives)—test_process_multiple_derives - Ori Tests:
tests/spec/traits/derive/all_derives.ori—.clone()on derived Point (passes) - LLVM Support: Synthetic LLVM IR for derived Clone — identity return for value types [done] (2026-02-13)
- AOT Tests:
ori_llvm/tests/aot/derives.rs— 2 AOT tests (basic, large struct sret) [done] (2026-02-13)
- Rust Tests:
-
Implement: Auto-implement
Hashable— spec/10-declarations.md § Attributes [done] (2026-02-10)- Rust Tests:
ori_types/src/check/ (derives) - Ori Tests:
tests/spec/traits/derive/all_derives.ori—.hash()on derived Point (passes) - LLVM Support: Synthetic LLVM IR for derived Hashable — FNV-1a in pure LLVM IR [done] (2026-02-13)
- AOT Tests:
ori_llvm/tests/aot/derives.rs— 2 AOT tests (equal values, different values) [done] (2026-02-13)
- Rust Tests:
-
Implement: Auto-implement
Printable— spec/10-declarations.md § Attributes [done] (2026-02-10)- Rust Tests:
ori_types/src/check/ (derives) - Ori Tests:
tests/spec/traits/derive/all_derives.ori—.to_string()on derived Point (passes) - LLVM Support: Synthetic LLVM IR for derived Printable — runtime str concat via
ori_str_*[done] (2026-02-13) - AOT Tests:
ori_llvm/tests/aot/derives.rs— 1 AOT test (basic non-empty check) [done] (2026-02-13)
- Rust Tests:
-
Implement: Auto-implement
Default— spec/10-declarations.md § Attributes [done] (2026-02-14)- Rust Tests:
ori_types/src/check/ (derives)—create_derived_method_defhandles Default - Ori Tests:
tests/spec/traits/derive/default.ori— 6 tests (basic, multi-type, single field, float, eq integration, nested) [done] (2026-02-14) - LLVM Support: LLVM codegen for derived Default —
const_zeroproduces correct zero-init structs [done] (2026-02-14) - AOT Tests:
ori_llvm/tests/aot/derives.rs— 3 AOT tests (basic, mixed types, eq integration) [done] (2026-02-15)- Fixed: Static method dispatch bug in LLVM codegen —
TypeRefreceivers now handled as static calls (no self param)
- Fixed: Static method dispatch bug in LLVM codegen —
- Rust Tests:
3.6 Section Completion Checklist
- Core library traits (3.0): Len, IsEmpty, Option, Result, Comparable, Eq — mostly complete [partial] (2026-02-10)
- Remaining: IsEmpty — add Range
/[T, max N] support, generic prelude function, spec section (approved 2026-02-21) - Gap: Clone/Hashable/Default/Printable methods NOT callable on primitives — FIXED: V2 type checker resolvers return correct types for clone/hash/equals on primitives [done] (2026-02-15). Clone also works on compound types (collections, wrappers, tuples). hash/equals on compound types reverted (phase boundary leak — evaluator/LLVM not implemented); tracked under 3.14.
- Remaining: IsEmpty — add Range
- Trait declarations (3.1): Parse, required methods, default methods, self, Self, inheritance — all complete [done] (2026-02-10)
- Gap: Static methods
Type.method()— FIXED, was stale TODO [done] (2026-02-13)
- Gap: Static methods
- Trait implementations (3.2): Inherent, trait, generic impls, method resolution, coherence — all complete [done] (2026-02-10)
- Trait bounds (3.3): Single, multiple, constraint satisfaction — all complete [done] (2026-02-10)
- Associated types (3.4): Declaration,
Self.Item, where constraints — all complete [done] (2026-02-10) - Derive traits (3.5): Eq, Clone, Hashable, Printable complete; Default NOT tested [done] (2026-02-10)
- ~239 trait test annotations pass (len: 14, is_empty: 13, option: 16, result: 14, comparable: 58, eq: 23, declaration: 16, self_param: 9, self_type: 7, inheritance: 6, generic_impl: 4, associated_types: 4, default_type_params: 2, default_assoc_types: 4, derive: 16, ordering: 32, method_call: 1) [done] (2026-02-10)
- Run full test suite:
./test-all.sh— 4181 passed, 0 failed, 42 skipped (verified 2026-03-29) - LLVM AOT tests: 88 trait + 43 derive + 17 formattable + 26 iterator = 174 total, all passing (verified 2026-03-29)
- Fixed:
.compare()return type resolved as Ordering — added to V2 type checker [done] (2026-02-13) - Fixed:
.unwrap_or()added to LLVM Option dispatch table [done] (2026-02-13) - Fixed: Default trait methods compiled in LLVM [done] (2026-02-13)
- Fixed: Indirect ABI parameter passing — self loaded from pointer for >16B structs [done] (2026-02-13)
- Fixed: Derive methods wired into LLVM codegen — synthetic IR functions for Eq, Clone, Hashable, Printable [done] (2026-02-13)
- Fixed:
- Operator traits (3.21): User-defined operator dispatch complete — type checker desugaring, evaluator dispatch, LLVM codegen, error messages [done] (2026-02-15)
- Remaining: spec and CLAUDE.md updates verified complete (2026-02-15). Derive for newtypes tracked as optional in 3.21 [done] (2026-02-18)
- Proposals (3.8-3.17): Evaluator verified complete for all proposals (verified 2026-03-29). LLVM gaps remain: Debug (3.9 all items), Traceable (3.13), iterator advanced features (3.8 Phase 2+), Index (3.12), derived sum/generic/recursive (3.15). See per-subsection LLVM items for details.
-
/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. - HYGIENE:
compiler/ori_types/src/registry/traits/mod.rsis 762 source lines — exceeds the 500-line limit. Split into submodules. - WEAK TESTS:
tests/spec/traits/iterator/collect_set.orihas 6#skipmarkers with tautological stub bodies (assert(cond: true)) — exceeds 3-skip budget per file. Replace with real tests or remove stubs and track Set collect as a plan item. - WEAK TESTS: Default type parameters (3.19) has only 2 spec tests. Add edge case tests (multiple defaults, complex cross-references, error cases for invalid ordering).
- WEAK TESTS: Default associated types (3.20) has only 4 spec tests. Add bounds checking tests when feature is implemented.
Exit Criteria: Core trait-based code compiles and runs in evaluator [done]. LLVM codegen for built-in and user methods works [done]. User-defined operator traits complete [done] (2026-02-15). Formal trait proposals (3.8-3.17) evaluator complete, LLVM partial.
-
/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 (3.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-3.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 3.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.
3.7 Clone Trait Formal Definition
STATUS: COMPLETE (verified 2026-03-29)
Proposal: proposals/approved/clone-trait-proposal.md
Formalizes the Clone trait that enables explicit value duplication. The trait is already recognized in trait bounds and derivable, but this proposal adds the formal definition and comprehensive prelude implementations.
Implementation
-
Implement: Formal
Clonetrait definition in type system- Ori Tests:
tests/spec/traits/clone/definition.ori— derived Clone on structs (6 tests) - LLVM Support: LLVM codegen for Clone trait (identity for value types, derive for structs)
- AOT Tests:
ori_llvm/tests/aot/derives.rs— Clone definition codegen (derive_clone_basic, derive_clone_large_struct) - Note: Type checker V2
resolve_*_methodreturns correct types forcloneon all primitives and compound types. Static method dispatch fix enabledType.default()calls in LLVM codegen.hash/equalsresolved for primitives only (compound types deferred to 3.14 — evaluator/LLVM codegen not yet implemented).
- Ori Tests:
-
Implement: Clone implementations for all primitives (int, float, bool, str, char, byte, Duration, Size)
- Ori Tests:
tests/spec/traits/clone/primitives.ori— all 8 primitive types (13 tests) - LLVM Support: LLVM codegen for primitive clone methods (identity operation)
- AOT Tests:
ori_llvm/tests/aot/derives.rs— primitive clone codegen (clone_int, clone_float, clone_bool, clone_str)
- Ori Tests:
-
Implement: Clone implementations for collections ([T], {K: V}, Set
) with element-wise cloning [done] (2026-02-15) - Rust Tests:
ori_types/src/infer/expr/tests.rs—test_clone_satisfied_by_list,test_clone_satisfied_by_map,test_clone_satisfied_by_set - Ori Tests:
tests/spec/traits/clone/collections.ori— list clone (3 tests) - LLVM Support: LLVM codegen for collection clone — identity (ARC shares data) in
lower_list_method() - AOT Tests:
ori_llvm/tests/aot/derives.rs—test_aot_clone_list_int,test_aot_clone_list_empty
- Rust Tests:
-
Implement: Clone implementations for Option
and Result<T, E> [done] (2026-02-15) - Rust Tests:
ori_types/src/infer/expr/tests.rs—test_clone_satisfied_by_option,test_clone_satisfied_by_result - Ori Tests:
tests/spec/traits/clone/wrappers.ori— Option Some/None, Result Ok/Err (4 tests) - LLVM Support: LLVM codegen for Option/Result clone — identity (value types) in
lower_option_method(),lower_result_method() - AOT Tests:
ori_llvm/tests/aot/derives.rs—test_aot_clone_option_some,test_aot_clone_option_none,test_aot_clone_result_ok,test_aot_clone_result_err
- Rust Tests:
-
Implement: Clone implementations for tuples (all arities) [done] (2026-02-15)
- Rust Tests:
ori_types/src/infer/expr/tests.rs—test_clone_satisfied_by_tuple,test_clone_satisfied_by_tuple_triple - Ori Tests:
tests/spec/traits/clone/tuples.ori— pair and triple clone (2 tests) - LLVM Support: LLVM codegen for tuple clone — identity (value type) via
TypeInfo::Tuplematch inlower_builtin_method() - AOT Tests:
ori_llvm/tests/aot/derives.rs—test_aot_clone_tuple_pair,test_aot_clone_tuple_triple
- Rust Tests:
-
Update Spec:
06-types.md— add Clone trait section (already present at § Clone Trait, lines 924–970+) -
Update Spec:
12-modules.md— update prelude traits description (Clone listed in prelude traits table, line 269/279) -
Update:
CLAUDE.md— Clone is documented in spec; CLAUDE.md is a compiler dev guide, not language reference -
Hygiene review (2026-02-15): Phase boundary audit of commit 01051607
- Fixed LEAK: LLVM codegen missing
byte.clone()andchar.clone()— addedIdx::BYTE | Idx::CHARidentity arms inlower_builtin_method()(lower_calls.rs) - Fixed LEAK: Type checker speculatively accepted
hash/equalson collections (list, map, set), wrappers (Option, Result), and tuples — reverted. Evaluator and LLVM codegen have no handlers for these methods. Type checker now only acceptscloneon compound types.hash/equalson compound types tracked under 3.14. - Deferred WASTE:
abi.clone()inlower_calls.rs(4 sites) — pre-existing borrow-conflict workaround, cheap clone. Not worth refactoring risk now. - Deferred WASTE:
method_strString allocation per method call — pre-existing, requiresName-based API change across many call sites. - Hygiene review pass 2 (2026-02-15): Phase boundary audit of commit da22ae17
- Fixed LEAK:
type_satisfies_trait()claimed compound types satisfyEq(COLLECTION_TRAITS,WRAPPER_TRAITS,RESULT_TRAITSall contained"Eq") — but no.equals()method exists in any downstream phase. Removed"Eq"from all 3 arrays. Re-add under 3.14 whenequals()is implemented. - Fixed LEAK:
resolve_tuple_method()acceptedto_list— dubious semantics (only works if all elements same type), no evaluator/LLVM handler. Removed; simplified function signature (dropped unusedengineparam). - Fixed LEAK:
dispatch_map_method()in evaluator had noclonehandler — fell through tono_such_method("clone", "map"). Added clone handler (Arc identity, same as list). - Fixed LEAK:
dispatch_tuple_method()in evaluator had nolenhandler — fell through tono_such_method("len", "tuple"). Added len handler extractingValue::Tuple(elems).len(). - Fixed LEAK:
lower_builtin_method()in LLVM codegen had no Map/Set clone handling — fell through toNone→ “unresolved method call”. AddedMap | Setidentity pattern (Arc-managed structs). - Fixed LEAK:
lower_builtin_method()in LLVM codegen had no Tuple.len() handling. Added compile-time constant fromTypeInfo::Tuple { elements }count. - Added Tests: 6 unit tests verifying compound types do NOT satisfy Eq (
test_eq_not_satisfied_by_{list,map,set,option,result,tuple}).
- Fixed LEAK:
- Fixed LEAK: LLVM codegen missing
3.8 Iterator Traits
STATUS: Evaluator COMPLETE, LLVM PARTIAL (verified 2026-03-29 — evaluator verified complete; LLVM Phase 1 done with 26 AOT tests; Phase 2+ LLVM items unchecked; collect_set.ori has 6 skips with stub bodies — WEAK TESTS)
Proposal: proposals/approved/iterator-traits-proposal.md
Formalizes iteration with four core traits: Iterator, DoubleEndedIterator, Iterable, and Collect. Enables generic programming over any iterable, user types participating in for loops, and transformation methods.
Implementation
-
Implement:
Iteratortrait with functionalnext()returning(Option<Self.Item>, Self)(2026-02-15)- Rust Tests:
ori_patterns/src/value/iterator/tests.rs— 13 unit tests for IteratorValue (2026-02-15) - Ori Tests:
tests/spec/traits/iterator/iterator.ori— 9 spec tests (2026-02-15) - LLVM Support: LLVM codegen for iterator trait methods
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
- Rust Tests:
-
Implement:
DoubleEndedIteratortrait withnext_back()method (2026-02-16)- Rust Tests:
ori_patterns/src/value/iterator/tests.rs— 18 unit tests for next_back (List, Range, Str, interleaved, is_double_ended, size_hint) (2026-02-16) - Ori Tests:
tests/spec/traits/iterator/double_ended.ori— 12 spec tests (2026-02-16) - LLVM Support: LLVM codegen for double-ended iterator methods
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
- Rust Tests:
-
Implement:
Iterabletrait withiter()method — built-in dispatch for list, map, range, str (2026-02-15)- Rust Tests: Consistency tests verify eval/typeck method sync (2026-02-15)
- Ori Tests:
tests/spec/traits/iterator/iterator.ori— covers .iter() on all types (2026-02-15) - LLVM Support: LLVM codegen for iterable trait
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
-
Implement:
Collecttrait withfrom_iter()method — type-directed collect via bidirectional inference (2026-02-16)- Rust Tests:
ori_types/src/check/integration_tests.rs— 4 integration tests for bidirectional collect inference (2026-02-16) - Ori Tests:
tests/spec/traits/iterator/collect.ori— 8 spec tests for Set collect, dedup, chained adapters (2026-02-16) - LLVM Support: LLVM codegen for collect trait
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
- Rust Tests:
-
Implement: Iterator Phase 2 methods — consumers (fold, count, find, any, all, for_each, collect) and lazy adapters (map, filter, take, skip) (2026-02-15)
- Rust Tests:
ori_patterns/src/value/iterator/tests.rs— 10 adapter variant unit tests (2026-02-15) - Ori Tests:
tests/spec/traits/iterator/methods.ori— 31 spec test assertions (2026-02-15) - LLVM Support: LLVM codegen for all iterator methods (2026-02-21) — Phase 1: map, filter, take, skip, enumerate, collect, count; Phase 2: fold, find, any, all, for_each, zip, chain
- AOT Tests:
ori_llvm/tests/aot/iterators.rs— 25 AOT tests (2026-02-21) - Phase 2C/2D: enumerate, zip, chain, flatten, flat_map, cycle (2026-02-15)
- Remaining: DoubleEndedIterator — next_back() implemented (2026-02-16)
- Rust Tests:
-
Implement: DoubleEndedIterator default methods (rev, last, rfind, rfold) (2026-02-16)
- Rust Tests:
ori_patterns/src/value/iterator/tests.rs— 7 unit tests for Reversed variant (is_double_ended, size_hint, Debug, PartialEq, Hash) (2026-02-16) - Ori Tests:
tests/spec/traits/iterator/double_ended_methods.ori— 21 spec tests (rev/last/rfind/rfold on list, range, string, empty, adapters) (2026-02-16) - LLVM Support: LLVM codegen for double-ended methods
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
- Rust Tests:
-
Implement:
repeat(value)function for infinite iterators (2026-02-16)- Rust Tests:
ori_patterns/src/value/iterator/tests.rs— 9 unit tests (basic, string, never_exhausts, not_double_ended, size_hint, debug, equality, inequality, cross-variant) (2026-02-16) - Ori Tests:
tests/spec/traits/iterator/infinite.ori— 13 spec tests (basic, string, bool, take_zero, map, filter, enumerate, skip_take, count, fold, any, all, zip) (2026-02-16) - LLVM Support: LLVM codegen for repeat
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
- Rust Tests:
-
Implement: Standard implementations for built-in types
-
[T]implementsIterable(2026-02-15) (DoubleEndedIterator, Collect pending) -
{K: V}implementsIterable(2026-02-15) (NOT double-ended — unordered) -
Set<T>implementsIterable(2026-02-15) (Collect pending) (NOT double-ended — unordered) -
strimplementsIterable(2026-02-15) (DoubleEndedIterator pending) -
Range<int>implementsIterable(2026-02-15) (DoubleEndedIterator pending) -
Option<T>implementsIterable(2026-02-16) — Some(x) → 1-element list iter, None → empty iter - Note:
Range<float>does NOT implementIterable(precision issues) (2026-02-16) — compile-time rejection with diagnostic in type checker: for loops,.iter(),.collect(),.to_list()all rejected; compile-fail tests intests/compile-fail/range_float_iteration.ori(4 tests) - Ori Tests:
tests/spec/traits/iterator/builtin_impls.ori— 13 spec tests (some/none iter, map, filter, count, fold, any, chain, zip) (2026-02-16) - LLVM Support: LLVM codegen for all builtin iterator impls
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
-
-
Implement: Helper iterator types (ListIterator, RangeIterator, MapIterator, SetIterator, StrIterator) + adapter types (Mapped, Filtered, TakeN, SkipN) (2026-02-15)
- Rust Tests:
ori_patterns/src/value/iterator/tests.rs— 22 unit tests (2026-02-15) - Ori Tests: Coverage across existing files — ListIterator/RangeIterator/StrIterator in
iterator.ori+double_ended.ori, SetIterator infor_loop.ori, MapIterator initerator.ori, adapters inmethods.ori+double_ended.ori(2026-02-16) - LLVM Support: LLVM codegen for all helper iterator types
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
- Rust Tests:
-
Implement: Fused iterator guarantee (once None, always None) (2026-02-15)
- Rust Tests:
ori_patterns/src/value/iterator/tests.rs— list_iterator_fused (2026-02-15) - Ori Tests:
tests/spec/traits/iterator/iterator.ori— test_list_iter_fused (2026-02-15) - LLVM Support: LLVM codegen respects fused guarantee
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
- Rust Tests:
-
Implement:
forloop desugaring toIterable.iter()and functionalnext()(2026-02-16)- Rust Tests:
ori_types/src/infer/expr/tests.rs— 4 for-loop type inference tests (infer_for_do, infer_for_yield, infer_for_with_guard, infer_for_guard_not_bool) (2026-02-16) - Ori Tests:
tests/spec/traits/iterator/for_loop.ori— 19 spec tests (list, range, str, set, option, iterator pass-through, guards, break) (2026-02-16) - LLVM Support: LLVM codegen for desugared for loops
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
- Rust Tests:
-
Implement:
for...yielddesugaring to.iter().map().collect()(2026-02-16)- Rust Tests:
ori_types/src/infer/expr/tests.rs— test_infer_for_yield verifies yield produces List(2026-02-16) - Ori Tests:
tests/spec/traits/iterator/for_loop.ori— 12+ yield tests (list, empty, range, inclusive, str, option, guard, transform, break) (2026-02-16) - LLVM Support: LLVM codegen for desugared for yield
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
- Rust Tests:
-
Implement: Add traits and
repeatto prelude (2026-02-16)-
Iterator,DoubleEndedIterator,Iterable,Collecttraits in prelude (TraitRegistry) (2026-02-16) — defined inlibrary/std/prelude.oriwithpub traitsyntax;Iterator<T>/DoubleEndedIterator<T>added to well-known types match in all three type resolution paths (resolve_parsed_type_simple,resolve_type_with_vars,resolve_parsed_type); type annotations likelet it: Iterator<int>andlet it: DoubleEndedIterator<int>now resolve correctly - Gate double-ended methods (
rev,last,rfind,rfold,next_back) behindDoubleEndedIteratortrait bound in type checker (2026-02-16) —Tag::DoubleEndedIteratoradded; list/range/str return DEI, map/set/option return Iterator; map/filter preserve DEI, take/skip/enumerate downgrade; error diagnostic for DEI-only methods on plain Iterator; tests:tests/spec/traits/iterator/double_ended_gating.ori(16 spec tests),tag/tests.rs(5 unit tests),unify/tests.rs(7 unit tests) -
repeatfunction in prelude (2026-02-16) — registered inregister_prelude()+ type sig ininfer_ident() - Ori Tests:
tests/spec/traits/iterator/prelude.ori(2026-02-16) — 8 spec tests (Iteratorannotation, DoubleEndedIterator annotation, method chains, collect, repeat, for-loop, for-yield)
-
-
Update Spec:
06-types.md— Iterator traits section already present (lines 1304-1344) (verified 2026-02-16) -
Update Spec:
10-patterns.md— for loop desugaring already documented (lines 887-911) (verified 2026-02-16) -
Update Spec:
12-modules.md— Iterator traits in prelude table (lines 281-288) (verified 2026-02-16) -
Update:
CLAUDE.md— Iterator documentation in.claude/rules/ori-syntax.md(lines 177-182) (verified 2026-02-16) -
/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 (3.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-3.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 3.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.
3.8.1 Iterator Performance and Semantics
STATUS: Evaluator COMPLETE, LLVM/optimizations NOT STARTED (verified 2026-03-29 — evaluator items verified; all LLVM items unchecked; optimization items correctly marked as not started)
Proposal: proposals/approved/iterator-performance-semantics-proposal.md
Formalizes the performance characteristics and precise semantics of Ori’s functional iterator model. Specifies copy elision guarantees, lazy evaluation, compiler optimizations, and introduces infinite range syntax (start..).
Implementation
-
Implement: Copy elision for iterator rebinding patterns (2026-02-17)
- Rust Tests:
ori_patterns/src/value/iterator/tests.rs+heap/tests.rs— copy elision verification (2026-02-17) - Ori Tests:
tests/spec/traits/iterator/copy_elision.ori(2026-02-17) - LLVM Support: LLVM codegen respects copy elision
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
- Rust Tests:
-
Implement: Infinite range syntax
start..in lexer/parser- Rust Tests:
ori_patterns/src/value/composite/tests.rs— unbounded range unit tests - Ori Tests:
tests/spec/expressions/infinite_range.ori - LLVM Support: LLVM codegen for infinite ranges
- LLVM Rust Tests:
ori_llvm/tests/range_tests.rs
- Rust Tests:
-
Implement: Infinite range with step
start.. by step- Rust Tests:
ori_patterns/src/value/iterator/tests.rs— unbounded range iterator tests - Ori Tests:
tests/spec/expressions/infinite_range.ori(step tests included) - LLVM Support: LLVM codegen for stepped infinite ranges
- LLVM Rust Tests:
ori_llvm/tests/range_tests.rs
- Rust Tests:
-
Implement: Infinite range iteration (implements Iterable but NOT DoubleEndedIterator)
- Rust Tests:
ori_patterns/src/value/iterator/tests.rs— unbounded range not double-ended - Ori Tests:
tests/spec/traits/iterator/infinite_range.ori - LLVM Support: LLVM codegen for infinite range iteration
- LLVM Rust Tests:
ori_llvm/tests/iterator_tests.rs
- Rust Tests:
-
Implement: Lint warnings for obvious infinite iteration patterns (SHOULD warn) (2026-02-16)
-
repeat(...).collect()withouttake— W2001 warning in type checker -
(start..).collect()withouttake— unbounded range detection viaExprKind::Range { end: INVALID } -
iter.cycle().collect()withouttake— cycle() detected as infinite source - Rust Tests:
ori_types/src/infer/expr/tests.rs— 12find_infinite_source_*unit tests (2026-02-16) - Ori Tests:
tests/lint/infinite_iteration.ori— 14 spec tests (bounded, finite, adapter chains) (2026-02-16)
-
-
Implement: Guaranteed compiler optimizations
- Copy elision when iterator rebound immediately
- Inline expansion for iterator methods
- Deforestation (intermediate iterator elimination)
- Loop fusion (adjacent maps/filters combined)
- Rust Tests:
ori_llvm/tests/optimization_tests.rs
-
Update Spec:
06-types.md— add infinite range type variant (already documented) -
Update Spec:
09-expressions.md— add infinite range syntax section (already documented) -
Update Spec:
grammar.ebnf— update range_expr production (already correct: end is optional) -
Update:
CLAUDE.md— add infinite range syntax and iterator performance notes (verified 2026-02-16:.claude/rules/ori-syntax.mdlines 102+182 already document infinite range syntax, repeat(), take-before-collect guidance, and lazy/fused semantics) -
/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 (3.8.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-3.8.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 3.8.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.
3.9 Debug Trait
STATUS: Evaluator COMPLETE, LLVM NOT STARTED (verified 2026-03-29 — all evaluator items verified; all LLVM items unchecked)
Proposal: proposals/approved/debug-trait-proposal.md
Adds a Debug trait separate from Printable for developer-facing structural representation of values. Debug is automatically derivable and shows complete internal structure, while Printable remains for intentional user-facing output. Mirrors Rust’s Display vs Debug distinction.
Dependencies
asconversion syntax (as-conversion-proposal.md) — forself as strconversionsstr.escape()method — stdlib method for escaping special charactersIterator.join()method — stdlib method for joining iterator elements
Implementation
-
Implement:
Debugtrait definition in type system- Rust Tests:
ori_ir/src/derives/tests.rs— DerivedTrait::Debug parsing/method_name - Ori Tests:
tests/spec/traits/debug/definition.ori
- Rust Tests:
-
Implement: Debug implementations for all primitives (int, float, bool, str, char, byte, void)
- Rust Tests:
ori_eval/src/methods/helpers/tests.rs— escape helpers - Ori Tests:
tests/spec/traits/debug/primitives.ori - LLVM Support: LLVM codegen for primitive debug methods
- LLVM Rust Tests:
ori_llvm/tests/debug_tests.rs
- Rust Tests:
-
Implement: Debug implementations for Duration and Size
- Ori Tests:
tests/spec/traits/debug/primitives.ori(included with primitives) - LLVM Support: LLVM codegen for duration/size debug
- LLVM Rust Tests:
ori_llvm/tests/debug_tests.rs
- Ori Tests:
-
Implement: Debug implementations for collections ([T], {K: V}, Set
) - Ori Tests:
tests/spec/traits/debug/collections.ori - LLVM Support: LLVM codegen for collection debug
- LLVM Rust Tests:
ori_llvm/tests/debug_tests.rs
- Ori Tests:
-
Implement: Debug implementations for Option
and Result<T, E> - Ori Tests:
tests/spec/traits/debug/wrappers.ori - LLVM Support: LLVM codegen for option/result debug
- LLVM Rust Tests:
ori_llvm/tests/debug_tests.rs
- Ori Tests:
-
Implement: Debug implementations for tuples (all arities)
- Ori Tests:
tests/spec/traits/debug/tuples.ori - LLVM Support: LLVM codegen for tuple debug
- LLVM Rust Tests:
ori_llvm/tests/debug_tests.rs
- Ori Tests:
-
Implement:
#[derive(Debug)]macro for user-defined types- Ori Tests:
tests/spec/traits/debug/derive.ori - LLVM Support: LLVM codegen for derived debug
- LLVM Rust Tests:
ori_llvm/tests/debug_tests.rs
- Ori Tests:
-
Implement:
str.escape()method (user-callable) (2026-02-17)- Ori Tests:
tests/spec/traits/debug/escape.ori(2026-02-17) - LLVM Support: LLVM codegen for string escape
- LLVM Rust Tests:
ori_llvm/tests/debug_tests.rs
- Ori Tests:
-
Implement:
Iterator.join()method (user-callable) (2026-02-17)- Ori Tests:
tests/spec/traits/debug/join.ori(2026-02-17) - LLVM Support: LLVM codegen for iterator join
- LLVM Rust Tests:
ori_llvm/tests/debug_tests.rs
- Ori Tests:
-
Update Spec:
06-types.md— add Debug trait section (verified 2026-02-17: already present) -
Update Spec:
08-declarations.md— add Debug to derivable traits list (verified 2026-02-17: already present) -
Update Spec:
12-modules.md— add Debug to prelude traits (verified 2026-02-17: already present) -
Update:
CLAUDE.md— add Debug to prelude traits list (verified 2026-02-17: already present, added .join to iterator methods) -
/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 (3.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-3.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 3.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.
3.10 Trait Resolution and Conflict Handling
STATUS: PARTIAL (verified 2026-03-29 — implemented items verified; blocked items correctly annotated with dependencies)
Proposal: proposals/approved/trait-resolution-conflicts-proposal.md
Specifies rules for resolving trait implementation conflicts: diamond problem, coherence/orphan rules, method resolution order, super trait calls, and extension method conflicts.
Implementation
-
Implement: Diamond problem resolution — single impl satisfies all inheritance paths
- Rust Tests:
ori_types/src/registry/traits/tests.rs—all_super_traits_diamond,collected_methods_deduplication - Ori Tests:
tests/spec/traits/resolution/diamond.ori
- Rust Tests:
-
Implement: Conflicting default detection — error when multiple supertraits provide conflicting defaults (E2022)
- Rust Tests:
ori_types/src/registry/traits/tests.rs—find_conflicting_defaultscovered in unit tests - Ori Tests:
tests/compile-fail/conflicting_defaults.ori,tests/spec/traits/resolution/conflicting_defaults.ori
- Rust Tests:
-
Implement: Coherence/orphan rules — at least one of trait or type must be local
- Rust Tests: orphan rule tests
- Ori Tests:
tests/compile-fail/orphan_impl.ori
-
Implement: Blanket impl restrictions — orphan rules for
impl<T> T: Trait- Rust Tests: blanket impl tests
- Ori Tests:
tests/compile-fail/orphan_blanket.ori
-
Implement: Method resolution order — Inherent > Trait > Extension priority
- Rust Tests:
ori_types/src/registry/traits/tests.rs—lookup_method_checkedtests - Ori Tests:
tests/spec/traits/resolution/method_priority.ori - LLVM Support: LLVM codegen for method resolution order dispatch
- LLVM Rust Tests:
ori_llvm/tests/trait_resolution_tests.rs— method resolution codegen
- Rust Tests:
-
Implement: Ambiguous method detection (E2023) — error when multiple trait impls provide same method
- Rust Tests:
ori_types/src/registry/traits/tests.rs—MethodLookupResult::Ambiguoustested - Ori Tests:
tests/spec/traits/resolution/ambiguous_method.ori - Implement: Fully-qualified syntax
Trait.method(x)for disambiguation
- Rust Tests:
-
Implement: Super trait calls with
Trait.method(self)syntax- Rust Tests: super call tests
- Ori Tests:
tests/spec/traits/resolution/super_calls.ori - LLVM Support: LLVM codegen for super trait call dispatch
- LLVM Rust Tests: super trait call codegen
-
Implement: Extension method conflict detection (including re-exports)
- Rust Tests: extension conflict tests
- Ori Tests:
tests/compile-fail/extension_conflict.ori
-
Implement: Associated type disambiguation with
Type::Trait::AssocTypesyntax- Rust Tests: associated type disambiguation
- Ori Tests:
tests/spec/traits/resolution/assoc_type_disambiguation.ori
-
Implement: Implementation specificity (Concrete > Constrained > Generic)
- Rust Tests:
ori_types/src/registry/traits/tests.rs—ImplSpecificityenum + specificity-aware lookup - Ori Tests:
tests/spec/traits/resolution/specificity.ori— needs generic impls in type checker
- Rust Tests:
-
Implement: Overlapping impl detection — compile error for equal-specificity impls (E2021)
- Rust Tests:
ori_types/src/registry/traits/tests.rs— overlap detection inlookup_method_checked - Ori Tests:
tests/compile-fail/overlapping_impls.ori— needs generic impls in type checker
- Rust Tests:
-
Implement: Error codes E2010, E2021-E2023
- E2010: Duplicate implementation —
TypeErrorKind::DuplicateImpl,tests/compile-fail/duplicate_impl.ori - E2021: Overlapping implementations —
TypeErrorKind::OverlappingImpls,errors/E2021.md - E2022: Conflicting defaults —
TypeErrorKind::ConflictingDefaults,errors/E2022.md - E2023: Ambiguous method call —
TypeErrorKind::AmbiguousMethod,errors/E2023.md
- E2010: Duplicate implementation —
-
Update Spec:
08-declarations.md— coherence, resolution, super calls sections already present (lines 458-583); added error code cross-references (E2010, E2021, E2023) [done] (2026-02-18) -
Update:
CLAUDE.md— trait resolution rules already documented in.claude/rules/ori-syntax.mdvia Len trait and operator traits [done] (2026-02-18) -
/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 (3.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-3.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 3.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.
3.11 Object Safety Rules
STATUS: COMPLETE (verified 2026-03-29)
Proposal: proposals/approved/object-safety-rules-proposal.md
Formalizes the rules that determine whether a trait can be used as a trait object for dynamic dispatch. Defines three object safety rules and associated error codes.
Implementation
-
Implement: Object safety checking in type checker (2026-02-17)
-
ObjectSafetyViolationenum +TraitEntry::is_object_safe()—ori_types/src/registry/traits/mod.rs -
compute_object_safety_violations()at registration —ori_types/src/check/registration/mod.rs -
check_parsed_type_object_safety()at signature sites —ori_types/src/check/signatures/mod.rs - Rust Tests:
ori_types/src/check/registration/tests.rs— 11 tests - Ori Tests:
tests/spec/traits/object_safety.ori
-
-
Implement: Rule 1 — No
Selfin return position (2026-02-17)- Rust Tests:
self_return_violates_object_safety - Ori Compile-Fail Tests:
tests/compile-fail/object_safety_self_return.ori
- Rust Tests:
-
Implement: Rule 2 — No
Selfin parameter position (except receiver) (2026-02-17)- Rust Tests:
self_param_violates_object_safety,self_in_receiver_position_is_allowed - Ori Compile-Fail Tests:
tests/compile-fail/object_safety_self_param.ori
- Rust Tests:
-
Implement: Rule 3 — No generic methods (2026-02-17)
-
ObjectSafetyViolation::GenericMethodvariant exists in enum - Note: Cannot currently be violated —
TraitMethodSighas nogenericsfield; per-method generics are not yet parseable. Detection code ready for when syntax is added.
-
-
Implement: Error code E2024 (not object-safe) (2026-02-17)
- Single error code following Rust’s E0038 pattern (proposal’s E0800-E0802 consolidated)
-
TypeErrorKind::NotObjectSafevariant with violation list -
TypeCheckError::not_object_safe()constructor with per-violation suggestions - Rich formatting with method names and violation descriptions
- Documentation:
compiler/ori_diagnostic/src/errors/E2024.md
-
Implement: Object safety checking at trait object usage sites (2026-02-17)
-
ParsedType::Named— checks if name resolves to a non-object-safe trait -
ParsedType::TraitBounds— checks each bound individually - Recursive walk through compound types (List, Map, Tuple, Function)
- Ori Compile-Fail Tests:
tests/compile-fail/object_safety_nested.ori
-
-
Implement: Bounded trait objects (
Printable + Hashable) — all components must be object-safe (2026-02-17)- Ori Compile-Fail Tests:
tests/compile-fail/object_safety_trait_bounds.ori
- Ori Compile-Fail Tests:
-
Spec:
06-types.mdalready has Object Safety section (lines 864-930) covering all three rules -
Spec:
08-declarations.mdalready references object safety in trait design guidance
3.12 Custom Subscripting (Index Trait)
STATUS: Evaluator COMPLETE, LLVM NOT STARTED (verified 2026-03-29 — evaluator verified; no LLVM codegen tests)
Proposals:
proposals/approved/custom-subscripting-proposal.md— Design and motivationproposals/approved/index-trait-proposal.md— Formal specification and error messages
Introduces the Index trait for read-only custom subscripting, allowing user-defined types to use [] syntax. Supports multiple index types per type (e.g., JsonValue with both str and int keys) and flexible return types (T, Option<T>, or Result<T, E>).
Implementation
-
Implement:
Index<Key, Value>trait definition in prelude (2026-02-17)- Ori Tests:
tests/spec/traits/index/definition.ori(2026-02-17) - Ori Tests:
tests/spec/traits/index/option_return.ori(2026-02-17)
- Ori Tests:
-
Implement: Desugaring
x[k]tox.index(key: k)via type checker + evaluator fallback (2026-02-17)- Type checker:
infer_index()falls back toresolve_index_via_trait()for non-builtin types - Evaluator:
CanExpr::Indexhandler splits built-in (fast path) vs trait dispatch - LLVM Support: LLVM codegen for desugared index calls
- LLVM Rust Tests:
ori_llvm/tests/index_tests.rs
- Type checker:
-
Implement: Type inference for subscript expressions (resolve which
Indeximpl based on key type) (2026-02-17)- Replaced
lookup_method_checked()with directimpls_for_type()iteration + key-type tag filtering
- Replaced
-
Implement: Multiple
Indeximpls per type (different key types) (2026-02-17)- Type checker:
resolve_index_via_traitfilters candidates by key type tag, disambiguates single match - Evaluator:
eval_index_user_typematcheskey_type_hintagainst runtime type - Registry:
UserMethodRegistrystoresVec<UserMethod>per key, withlookup_all()for multi-dispatch - Canon IR:
method_root_for_nthassigns correct canonical body to each impl - Ori Tests:
tests/spec/traits/index/multiple_impls.ori(2026-02-17)
- Type checker:
-
Implement: Built-in
Indeximplementations for[T],[T, max N],{K: V},str(2026-02-17)- These work via direct dispatch (hardcoded in
infer_indexandeval_index) - Formal trait impls (register in TraitRegistry for coherence) — deferred until generic impl support
- Ori Tests:
tests/spec/traits/index/builtin_impls.ori(2026-02-17) - LLVM Support: LLVM codegen for builtin Index impls
- LLVM Rust Tests:
ori_llvm/tests/index_tests.rs
- These work via direct dispatch (hardcoded in
-
Implement: Error messages for Index trait (E2025-E2027) (2026-02-17)
- E2025: type does not implement Index (not indexable)
- E2026: wrong key type for Index impl
- E2027: ambiguous index key type (multiple impls match)
- Error documentation:
E2025.md,E2026.md,E2027.md - Ori Compile-Fail Tests:
tests/compile-fail/index_no_impl.ori,tests/compile-fail/index_wrong_key.ori
-
Update Spec:
09-expressions.md— Index Trait section already complete with multiple impls, return types, built-in impls (2026-02-17) -
Update Spec:
06-types.md— Index already listed in.claude/rules/ori-syntax.mdtraits list (2026-02-17) -
Update:
.claude/rules/ori-syntax.md— added multiple impls dispatch note to Index entry (2026-02-17) -
/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 (3.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-3.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 3.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.
3.13 Additional Core Traits
STATUS: Evaluator COMPLETE, LLVM PARTIAL (verified 2026-03-29 — Printable and Default have LLVM support; Traceable LLVM pending)
Proposal: proposals/approved/additional-traits-proposal.md
Formalizes three core traits: Printable, Default, and Traceable. The Iterable, Iterator, DoubleEndedIterator, and Collect traits are already defined in the spec and implemented in Section 3.8.
Implementation
-
Implement:
Printabletrait formal definition in type system [done] (2026-02-17)- Pre-existing: trait defined in prelude.ori, type checker registration in ori_types, evaluator dispatch, LLVM codegen
- Rust Tests: Existing coverage in ori_types registration, ori_eval dispatch, ori_llvm derive_codegen
- Ori Tests:
tests/spec/traits/printable/definition.ori— 8 tests (int, float, bool, str, char, Ordering, generic bound, interpolation) - LLVM Support: LLVM codegen for Printable trait methods — existing in derive_codegen.rs
- AOT Tests:
ori_llvm/tests/aot/derives.rs— derive_printable_basic test passing
-
Implement: Printable derivation with
Point(1, 2)format (type name + values) [done] (2026-02-17)- Fixed: eval_derived_to_str() and compile_derive_printable() now produce spec-compliant compact format
- Added: format_value_printable() for recursive nested struct formatting (no quotes on strings)
- Rust Tests: Existing coverage in ori_eval/derives, ori_llvm/derive_codegen
- Ori Tests:
tests/spec/traits/printable/derive.ori— 7 tests (basic, single field, mixed types, nested, many fields, printable-vs-debug, interpolation) - LLVM Support: LLVM codegen for Printable derivation — compile_derive_printable() updated
- AOT Tests:
ori_llvm/tests/aot/derives.rs— derive_printable_basic test passing
-
Implement:
Defaulttrait formal definition in type system (2026-02-17)- Pre-existing: trait defined in prelude.ori, type checker registration in ori_types, evaluator dispatch, LLVM codegen
- Rust Tests: Existing coverage in ori_types registration, ori_eval derived_methods, ori_ir derives tests
- Ori Tests:
tests/spec/traits/default/definition.ori— 10 tests (int, float, bool, str defaults via struct fields, Duration/Size defaults, nested structs, deep nesting, idempotency) (2026-02-17) - LLVM Support: LLVM codegen for Default trait — compile_derive_default() in derive_codegen.rs
- AOT Tests:
ori_llvm/tests/aot/derives.rs— 5 tests (basic, mixed_types, eq_integration, str_field, nested) (2026-02-17)
-
Implement: Default derivation for structs only (error on sum types) (2026-02-17)
- Pre-existing: derive processing in ori_eval, LLVM codegen in derive_codegen.rs
- Fixed: Added E2028 compile-time rejection of #[derive(Default)] on sum types (2026-02-17)
- Rust Tests: Existing coverage in ori_ir/derives/tests.rs, ori_eval/derives
- Ori Tests:
tests/spec/traits/default/derive.ori— 7 tests (basic struct, single field, mixed fields, nested, eq integration, modify, multi-derive) (2026-02-17) - Ori Compile-Fail Tests:
tests/compile-fail/default_sum_type.ori— E2028 error (2026-02-17) - LLVM Support: LLVM codegen for Default derivation — compile_derive_default() working
- AOT Tests:
ori_llvm/tests/aot/derives.rs— 5 tests passing (2026-02-17)
-
Implement:
Traceabletrait formal definition in type system (2026-02-17)- Traceable trait with 4 methods (with_trace, trace, trace_entries, has_trace) in prelude.ori
- TraceEntry struct registered as built-in type with 4 fields (function, file, line, column)
- Error constructor added to type checker (infer_ident) and evaluator (function_val_error)
- Rust Tests: ErrorValue construction/trace accumulation tests in ori_patterns, consistency tests in oric (2026-02-17)
- Ori Tests:
tests/spec/traits/traceable/definition.ori— 5 tests (2026-02-17) - LLVM Support: LLVM codegen for Traceable trait methods
- LLVM Rust Tests:
ori_llvm/tests/trait_method_tests.rs— Traceable codegen
-
Implement: Traceable for Error type with trace storage (2026-02-17)
- Value::Error changed from String to Heap
with trace Vec ?operator injects trace entries via inject_trace_entry() in can_eval.rs- Error methods (trace, trace_entries, has_trace, with_trace, message) dispatched in methods/error.rs
- Rust Tests: ErrorValue tests in ori_patterns, method dispatch tests in ori_eval (2026-02-17)
- Ori Tests:
tests/spec/traits/traceable/error_trace.ori— 7 tests,tests/spec/traits/traceable/no_trace.ori— 3 tests (2026-02-17) - LLVM Support: LLVM codegen for Traceable Error type
- LLVM Rust Tests:
ori_llvm/tests/trait_method_tests.rs— Traceable Error codegen
- Value::Error changed from String to Heap
-
Implement: Traceable delegation for Result<T, E: Traceable> (2026-02-17)
- Result.has_trace/trace/trace_entries delegate to inner Error value
- Ok and non-Error Err return empty traces
- Type checker recognizes trace methods on Result via TYPECK_BUILTIN_METHODS
- Rust Tests: Consistency tests updated in oric (2026-02-17)
- Ori Tests:
tests/spec/traits/traceable/result_delegation.ori— 6 tests (2026-02-17) - LLVM Support: LLVM codegen for Traceable Result delegation
- LLVM Rust Tests:
ori_llvm/tests/trait_method_tests.rs— Traceable Result codegen
-
Implement: Error messages (E1040→E2038, E1042→E2028) (2026-02-18)
- E2038: Missing Printable for string interpolation (was E1040) —
TypeErrorKind::MissingPrintable, check in template literal inference,type_satisfies_trait+WellKnownNamesupdated with Printable for compound types; compile-fail testtests/compile-fail/interpolation_missing_printable.ori, Rust unit testprintable_satisfaction_primitives_and_compounds(2026-02-18) - E2028: Cannot derive Default for sum type (was E1042) — implemented with TypeErrorKind::CannotDeriveDefaultForSumType (2026-02-17)
- E2038: Missing Printable for string interpolation (was E1040) —
-
Update Spec:
09-properties-of-types.md— add Printable, Default, Traceable sections (verified 2026-02-17: already present) -
Update:
CLAUDE.md— traits documented in.claude/rules/ori-syntax.md(prelude traits, operator traits, iterator traits) [done] (verified 2026-02-18) -
/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 (3.13) — 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-3.13 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 3.13: 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.
3.14 Comparable and Hashable Traits
STATUS: COMPLETE (verified 2026-03-29 — excellent coverage: 120+ test assertions, all relevant types covered, AOT coverage for list/tuple/option/result; map/set LLVM pending AOT collection infrastructure)
Proposal: proposals/approved/comparable-hashable-traits-proposal.md
Formalizes the Comparable and Hashable traits with complete definitions, mathematical invariants, standard implementations, and derivation rules. Adds Result<T, E> to both trait implementations and introduces hash_combine as a prelude function.
Phase boundary discipline: Each method must be implemented across ALL THREE phases (type checker → evaluator → LLVM codegen) before the type checker may accept it. Commit 01051607 added
hash/equalsto the type checker for compound types without evaluator/LLVM handlers — this was reverted in the hygiene review (see 3.7). When implementing items below, add to type checker LAST, after evaluator and LLVM codegen are working.
equals()on compound types is also tracked here. The Eq trait (3.0.6) covers primitives only. Collection/wrapperequals()methods (list, map, set, Option, Result, tuple) require the same all-phase implementation ashash().
Implementation
-
Implement: Formal
Comparabletrait definition in type system (2026-02-17)- Trait defined in
library/std/prelude.ori:pub trait Comparable: Eq { @compare (self, other: Self) -> Ordering } -
DerivedTrait::Comparablevariant inori_ir/src/derives/mod.rs - Trait registered in
ori_types/src/check/registration/mod.rs - Ori Tests:
tests/spec/traits/core/comparable.ori— 58 tests covering all types + operators
- Trait defined in
-
Implement: Comparable implementations for all primitives (int, float, bool, str, char, byte, Duration, Size) (2026-02-17)
- Evaluator:
ori_eval/src/methods/numeric.rs(int, float),variants.rs(bool, char, byte),collections.rs(str),units.rs(Duration, Size) - Type Checker:
ori_types/src/infer/expr/methods.rs— compare() returns Ordering for all primitives - Ori Tests:
tests/spec/traits/core/comparable.ori— all primitive compare() tests (58 tests) - LLVM Support: Primitive compare already in LLVM —
ori_llvm/tests/aot/traits.rs(7 tests) - AOT Tests:
ori_llvm/tests/aot/traits.rs— compare/is_less/is_equal/is_greater/reverse/is_less_or_equal/is_greater_or_equal
- Evaluator:
-
Implement: Comparable implementations for lists ([T]) (2026-02-17)
- Evaluator:
ori_eval/src/methods/collections.rs— dispatch_list_method with compare() viacompare_lists() - Type Checker:
ori_types/src/infer/expr/methods.rs— compare() returns Ordering for list - Ori Tests:
tests/spec/traits/core/comparable.ori— list compare() tests (6 tests incl. empty, length diff) - LLVM Support:
ori_llvm/src/codegen/lower_collection_methods.rs—emit_list_compare()lexicographic loop with phi-merge (2026-02-18) - AOT Tests:
ori_llvm/tests/aot/traits.rs—test_aot_list_compare,test_aot_list_compare_empty(2026-02-18)
- Evaluator:
-
Implement: Comparable implementations for tuples (2026-02-17)
- Evaluator:
ori_eval/src/methods/compare.rs— lexicographic viacompare_lists()(same logic) - Type Checker:
ori_types/src/infer/expr/methods.rs— compare() returns Ordering for tuple - Ori Tests:
tests/spec/traits/core/tuple_compare.ori— 6 tests (lexicographic ordering, field priority, tiebreakers) - LLVM Support:
ori_llvm/src/codegen/lower_builtin_methods.rs—emit_tuple_compare()lexicographic with phi-merge (2026-02-18) - AOT Tests:
ori_llvm/tests/aot/traits.rs—test_aot_tuple_compare(2026-02-18)
- Evaluator:
-
Implement: Comparable implementation for Option
(2026-02-17) - Evaluator:
ori_eval/src/methods/variants.rs— dispatch_option_method viacompare_option_values()(None < Some) - Type Checker:
ori_types/src/infer/expr/methods.rs— compare() returns Ordering for Option - Ori Tests:
tests/spec/traits/core/comparable.ori— Option compare() tests (4 tests: None-None, None-Some, Some-Some) - LLVM Support:
ori_llvm/src/codegen/lower_builtin_methods.rs—emit_option_compare()with tag/payload branching (2026-02-18) - AOT Tests:
ori_llvm/tests/aot/traits.rs—test_aot_option_compare(2026-02-18)
- Evaluator:
-
Implement: Comparable implementation for Result<T, E> (2026-02-17)
- Evaluator:
ori_eval/src/methods/variants.rs— dispatch_result_method viacompare_result_values()(Ok < Err) - Type Checker:
ori_types/src/infer/expr/methods.rs— compare() returns Ordering for Result - Ori Tests:
tests/spec/traits/core/comparable.ori— Result compare() tests (3 tests: Ok-Ok, Ok-Err, Err-Err) - LLVM Support:
ori_llvm/src/codegen/lower_builtin_methods.rs—emit_result_compare()with tag/payload branching (2026-02-18) - AOT Tests:
ori_llvm/tests/aot/traits.rs—test_aot_result_compare(2026-02-18)
- Evaluator:
-
Implement: Float IEEE 754 total ordering (NaN handling) (2026-02-17)
- Evaluator:
ori_eval/src/methods/numeric.rs— usestotal_cmp()for IEEE 754 ordering - Ori Tests:
tests/spec/traits/core/comparable.ori— float comparison tests - LLVM Support: Primitive float compare in LLVM (existing)
- AOT Tests:
ori_llvm/tests/aot/traits.rs— float compare tests
- Evaluator:
-
Implement: Comparable implementation for Ordering (2026-02-17)
- Evaluator:
ori_eval/src/methods/ordering.rs— dispatch_ordering_method with compare() (Less<Equal<Greater) - Type Checker:
ori_types/src/infer/expr/methods.rs— compare() returns Ordering for Ordering - Ori Tests:
tests/spec/traits/core/comparable.ori— Ordering compare() tests (3 tests) - LLVM Support:
ori_llvm/src/codegen/lower_builtin_methods.rs— ordering compare viaemit_icmp_ordering(2026-02-18) - AOT Tests:
ori_llvm/tests/aot/traits.rs—test_aot_ordering_compare(2026-02-18)
- Evaluator:
-
Implement: Comparison operator derivation (
<,<=,>,>=via Ordering methods) (2026-02-15)- Completed as part of operator traits (3.21) — operators desugared to Comparable trait calls
- Ori Tests:
tests/spec/traits/core/comparable.ori— operator tests - LLVM Support: Operators compile via trait call desugaring
- AOT Tests:
ori_llvm/tests/aot/traits.rs— is_less/is_greater/etc.
-
Implement: Formal
Hashabletrait definition in type system (2026-02-17)- Trait defined in
library/std/prelude.ori:pub trait Hashable: Eq { @hash (self) -> int } -
DerivedTrait::Hashablevariant inori_ir/src/derives/mod.rs - Trait registered in
ori_types/src/check/registration/mod.rs - Ori Tests:
tests/spec/traits/core/compound_hash.ori— 17 tests covering all types + hash_combine
- Trait defined in
-
Implement: Hashable implementations for all primitives (int, float, bool, str, char, byte, Duration, Size) (2026-02-17)
- Evaluator:
ori_eval/src/methods/numeric.rs(int identity, float normalized),variants.rs(bool, char, byte),collections.rs(str),units.rs(Duration, Size),ordering.rs(Ordering) - Type Checker:
ori_types/src/infer/expr/methods.rs— hash() returns int for all primitives - Ori Tests:
tests/spec/traits/core/compound_hash.ori— primitive hash consistency tests - LLVM Support:
ori_llvm/src/codegen/lower_builtin_methods.rs— bool/float/char/byte/ordering/str hash +ori_str_hashruntime (2026-02-18) - AOT Tests:
ori_llvm/tests/aot/traits.rs—test_aot_bool_hash,test_aot_float_hash,test_aot_char_hash,test_aot_str_hash(2026-02-18)
- Evaluator:
-
Implement: Hashable implementations for collections ([T], {K: V}, Set
, tuples) (2026-02-17) - Evaluator:
ori_eval/src/methods/collections.rs— list/map/set hash();compare.rs— tuple hash viahash_value() - Type Checker:
ori_types/src/infer/expr/methods.rs— hash() returns int for all collections - Ori Tests:
tests/spec/traits/core/compound_hash.ori— collection hash tests (order-independent for map/set) - LLVM Support: List hash in
lower_collection_methods.rs—emit_list_hash()fold loop with hash_combine; tuple hash inlower_builtin_methods.rs(2026-02-18). Map/set hash pending AOT collection infrastructure. - AOT Tests:
ori_llvm/tests/aot/traits.rs—test_aot_list_hash,test_aot_list_hash_empty,test_aot_tuple_hash(2026-02-18). Map/set hash tests pending AOT collection infrastructure.
- Evaluator:
-
Implement: Hashable implementations for Option
and Result<T, E> (2026-02-17) - Evaluator:
ori_eval/src/methods/variants.rs— Option hash (None→0, Some→hash_combine(1,hash)); Result hash (Ok→hash_combine(2,hash), Err→hash_combine(3,hash)) - Type Checker:
ori_types/src/infer/expr/methods.rs— hash() returns int for Option/Result - Ori Tests:
tests/spec/traits/core/compound_hash.ori— Option/Result hash tests - LLVM Support:
ori_llvm/src/codegen/lower_builtin_methods.rs—emit_option_hash(),emit_result_hash()with tag-based branching (2026-02-18) - AOT Tests:
ori_llvm/tests/aot/traits.rs—test_aot_option_hash,test_aot_result_hash(2026-02-18)
- Evaluator:
-
Implement: Float hashing consistency (+0.0 == -0.0, NaN == NaN for hash) (2026-02-17)
- Evaluator:
ori_eval/src/methods/compare.rs—hash_float()normalizes ±0.0 and NaN - Ori Tests:
tests/spec/traits/core/compound_hash.ori— float hash consistency tests - LLVM Support:
ori_llvm/src/codegen/lower_builtin_methods.rs—normalize_float_for_hash()(±0.0 → +0.0, NaN → canonical) (2026-02-18) - AOT Tests:
ori_llvm/tests/aot/traits.rs—test_aot_float_hash(2026-02-18)
- Evaluator:
-
Implement:
hash_combinefunction in prelude (2026-02-17)- Evaluator:
ori_eval/src/function_val.rs—function_val_hash_combine()using boost hash combine algorithm - Registration:
ori_eval/src/interpreter/mod.rs— registered in prelude viaregister_function_val() - Type Checker:
ori_types/src/infer/expr/identifiers.rs— type signature(int, int) -> int - Ori Tests:
tests/spec/traits/core/compound_hash.ori— hash_combine tests (3 tests) - LLVM Support:
ori_llvm/src/codegen/lower_builtin_methods.rs—lower_builtin_hash_combine()+emit_hash_combine()(Boost algorithm) (2026-02-18) - AOT Tests:
ori_llvm/tests/aot/traits.rs—test_aot_hash_combine(2026-02-18)
- Evaluator:
-
Implement:
#[derive(Comparable)]for user-defined types — evaluator only (2026-02-17)- Evaluator:
ori_eval/src/interpreter/derived_methods.rs—eval_derived_compare()with lexicographic field comparison - IR:
ori_ir/src/derives/mod.rs—DerivedTrait::Comparable+method_name()returns “compare” - IR Tests:
ori_ir/src/derives/tests.rs— from_name/method_name tests - Ori Tests:
tests/spec/traits/derive/comparable.ori— 6 tests (basic, lexicographic, single-field) - LLVM Support:
ori_llvm/src/codegen/derive_codegen/mod.rs—compile_derived_compare()with lexicographic field comparison (2026-02-18) - AOT Tests:
ori_llvm/tests/aot/derives.rs—test_aot_derive_comparable_basic,comparable_first_field_wins,comparable_single_field,comparable_with_strings(2026-02-18)
- Evaluator:
-
Implement:
#[derive(Hashable)]for user-defined types — all phases (2026-02-17)- Evaluator:
ori_eval/src/interpreter/derived_methods.rs—eval_derived_hash()with field hash combination - IR:
ori_ir/src/derives/mod.rs—DerivedTrait::Hashable+method_name()returns “hash” - LLVM Support:
ori_llvm/src/codegen/derive_codegen/mod.rs— FNV-1a hash in pure LLVM IR - AOT Tests:
ori_llvm/tests/aot/derives.rs— 2 tests (equal values, different values) - Ori Tests:
tests/spec/traits/core/compound_hash.ori— hash consistency + struct hash tests
- Evaluator:
-
Implement: Error messages (E2029-E2031, remapped from E0940-E0942) (2026-02-18)
- E2029: Cannot derive Hashable without Eq — validation in
register_derived_impl(), compile-fail test, Rust unit tests - E2030: Hashable implementation violates hash invariant — infrastructure complete (error code, TypeErrorKind, diagnostics, docs); detection deferred until manual trait impls exist
- E2031: Type cannot be used as map key (missing Hashable) — validation in
check_map_key_hashable(), compile-fail test - Fixed 5 AOT derive hash tests that derived Hashable without Eq (now correctly caught by E2029)
- E2029: Cannot derive Hashable without Eq — validation in
-
Update Spec:
09-properties-of-types.md— Comparable and Hashable sections already present; updated E2029/E2031 error references (2026-02-18) -
Update Spec:
12-modules.md— hash_combine already documented in prelude functions (2026-02-18) -
Update:
CLAUDE.md— added Comparable, Hashable, hash_combine, derive validation docs (2026-02-18) -
Implement:
equals()on compound types (Eq trait extension beyond primitives) (2026-02-17)- Evaluator:
ori_eval/src/methods/collections.rs— list element-wise, map key-set+value, set element-wise equality - Evaluator:
ori_eval/src/methods/variants.rs— Option tag+inner, Result tag+inner equality - Evaluator:
ori_eval/src/methods/compare.rs— tuple element-wise viaequals_values() - Type checker:
ori_types/src/infer/expr/methods.rs—equalsregistered for all compound types - Ori Tests:
tests/spec/traits/core/compound_equals.ori— 12 tests (list, map, Option, Result, tuple) - LLVM codegen: List equals in
lower_collection_methods.rs—emit_list_equals()length check + element-wise loop; Option/Result/Tuple inlower_builtin_methods.rs(2026-02-18). Map/set equals pending AOT collection infrastructure. - AOT Tests:
test_aot_list_equals,test_aot_list_equals_empty,test_aot_option_equals,test_aot_result_equals,test_aot_tuple_equals(2026-02-18). Map/set equals tests pending AOT collection infrastructure.
- Evaluator:
3.15 Derived Traits Formal Semantics
STATUS: Evaluator COMPLETE, LLVM PARTIAL (verified 2026-03-29 — 90+ evaluator tests across 12 files; LLVM gaps: sum type Eq, Debug, generic conditional, recursive derive)
Proposal: proposals/approved/derived-traits-proposal.md
Formalizes the #derive attribute semantics: derivable traits list, derivation rules, field constraints, generic type handling, and error messages.
Implementation
-
Implement: Eq derivation for structs — field-wise equality (2026-02-18)
- Ori Tests:
tests/spec/traits/derive/eq.ori— 22 struct tests - LLVM Support: LLVM codegen for Eq struct derivation (pre-existing)
- AOT Tests:
ori_llvm/tests/aot/derives.rs— 5 Eq struct AOT tests
- Ori Tests:
-
Implement: Eq derivation for sum types — variant matching (2026-02-18)
- Ori Tests:
tests/spec/traits/derive/eq_sum.ori— 15 sum type tests - LLVM Support: LLVM codegen for Eq sum type derivation
- AOT Tests: AOT tests for Eq sum type derive codegen
- Ori Tests:
-
Implement: Hashable derivation — combined field hashes via
hash_combine(2026-02-18)- Ori Tests:
tests/spec/traits/derive/hashable.ori— 11 tests - LLVM Support: LLVM codegen for Hashable derivation (pre-existing)
- AOT Tests:
ori_llvm/tests/aot/derives.rs— 4 Hashable AOT tests
- Ori Tests:
-
Implement: Comparable derivation — lexicographic field comparison (2026-02-18)
- Ori Tests:
tests/spec/traits/derive/comparable_sum.ori— 10 tests - LLVM Support: LLVM codegen for Comparable derivation (pre-existing)
- AOT Tests:
ori_llvm/tests/aot/derives.rs— 4 Comparable AOT tests
- Ori Tests:
-
Implement: Clone derivation — field-wise clone (2026-02-18)
- Ori Tests:
tests/spec/traits/derive/clone.ori— 8 tests - LLVM Support: LLVM codegen for Clone derivation (pre-existing)
- AOT Tests:
ori_llvm/tests/aot/derives.rs— 6 Clone AOT tests
- Ori Tests:
-
Implement: Default derivation for structs only (2026-02-18)
- Ori Compile-Fail Tests:
tests/compile-fail/default_sum_type.ori(pre-existing) - LLVM Support: LLVM codegen for Default derivation (pre-existing)
- AOT Tests:
ori_llvm/tests/aot/derives.rs— 5 Default AOT tests
- Ori Compile-Fail Tests:
-
Implement: Debug derivation — structural representation with type name (2026-02-18)
- Ori Tests:
tests/spec/traits/derive/debug.ori— 5 tests - LLVM Support: LLVM codegen for Debug derivation (deferred — evaluator-only)
- AOT Tests: AOT tests for Debug derive codegen
- Ori Tests:
-
Implement: Printable derivation — human-readable format
TypeName(field1, field2)(2026-02-18)- Ori Tests:
tests/spec/traits/derive/printable.ori— 6 tests - LLVM Support: LLVM codegen for Printable derivation (pre-existing)
- AOT Tests:
ori_llvm/tests/aot/derives.rs— 1 Printable AOT test
- Ori Tests:
-
Implement: Generic type conditional derivation — bounded impls (2026-02-18)
- Ori Tests:
tests/spec/traits/derive/generic.ori— 5 tests (Eq + Clone on Pair) - LLVM Support: LLVM codegen for generic conditional derivation
- AOT Tests: AOT tests for generic derive codegen
- Ori Tests:
-
Implement: Recursive type derivation (2026-02-18)
- Ori Tests:
tests/spec/traits/derive/recursive.ori— 8 tests (Eq + Clone + Printable on Tree) - LLVM Support: LLVM codegen for recursive type derivation
- AOT Tests: AOT tests for recursive derive codegen
- Ori Tests:
-
Implement: Error messages for derive validation (2026-02-18)
- E2032: Field type does not implement trait required by derive (was E0880)
- E2033: Trait cannot be derived (was E0881)
- E2028: Cannot derive Default for sum type (was E0882, pre-existing)
- Compile-Fail Tests:
tests/compile-fail/derive_field_missing_trait.ori,tests/compile-fail/derive_not_derivable.ori
-
W0100 superseded by E2029 — Hashable has supertrait Eq, making this a hard error (2026-02-18)
-
Update Spec:
06-types.md— Derive section already comprehensive (lines 775-837): derivable traits table, rules, generics, recursion, non-derivable [done] (verified 2026-02-18) -
Update Spec:
09-properties-of-types.md— derive semantics covered via individual trait sections (Eq, Comparable, Hashable each reference derivation) [done] (verified 2026-02-18) -
/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 (3.15) — 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-3.15 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 3.15: 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.
3.16 Formattable Trait
STATUS: COMPLETE (verified 2026-03-29 — 8 evaluator test files + 17 AOT tests; one documented GAP: user-defined Formattable::format() LLVM codegen blocked by general trait method call codegen)
Proposal: proposals/approved/formattable-trait-proposal.md
Formalizes the Formattable trait and format specification syntax for customized string formatting. Defines FormatSpec type structure, format spec syntax, and the relationship between Formattable and Printable via blanket implementation.
Implementation
-
Implement:
Formattabletrait definition in type system (2026-02-18)- Trait registered in
ori_types/src/check/registration/mod.rs - Trait signature uses
spec: FormatSpecper spec - Ori Tests:
tests/spec/traits/formattable/definition.ori
- Trait registered in
-
Implement:
FormatSpectype and related types (Alignment,Sign,FormatType) in prelude (2026-02-18)-
Alignmentenum (Left, Center, Right) registered in type system -
Signenum (Plus, Minus, Space) registered in type system -
FormatTypeenum (Binary, Octal, Hex, HexUpper, Exp, ExpUpper, Fixed, Percent) registered -
FormatSpecstruct with 6 Option fields registered - Variant identifiers resolve in type checker (
ori_types/src/infer/expr/identifiers.rs) - Variant globals registered in evaluator prelude (
ori_eval/src/interpreter/mod.rs) - Type definitions in
library/std/prelude.ori - Ori Tests:
tests/spec/traits/formattable/format_spec_type.ori
-
-
Implement: Format spec parsing in template strings (pre-existing)
- Parser in
ori_ir/src/format_spec.rs— handles[[fill]align][sign][#][0][width][.precision][type] - Validation in type checker with E2034/E2035 errors
- LLVM Support: LLVM codegen for FormatWith expressions (
ori_llvm/src/codegen/lower_constructs.rs) - AOT Tests:
ori_llvm/tests/aot/formattable.rs— 17 AOT tests (2026-02-18)
- Parser in
-
Implement: Blanket
Formattableimplementation forPrintabletypes (2026-02-18)- Evaluator fallback via
display_value()+ alignment inori_eval/src/interpreter/format.rs - Ori Tests:
tests/spec/traits/formattable/blanket.ori
- Evaluator fallback via
-
Implement:
Formattableforintwith binary, octal, hex format types (pre-existing, LLVM 2026-02-18)- Evaluator:
ori_eval/src/interpreter/format.rs— full int formatting - Ori Tests:
tests/spec/traits/formattable/int.ori - LLVM Support:
ori_rt/src/format.rs—ori_format_intruntime function - AOT Tests: AOT tests cover hex, binary, octal, sign, zero-pad, width/align
- Evaluator:
-
Implement:
Formattableforfloatwith scientific, fixed, percentage format types (pre-existing, LLVM 2026-02-18)- Evaluator:
ori_eval/src/interpreter/format.rs— full float formatting - Ori Tests:
tests/spec/traits/formattable/float.ori - LLVM Support:
ori_rt/src/format.rs—ori_format_floatruntime function - AOT Tests: AOT tests cover fixed, precision, percent, sign
- Evaluator:
-
Implement:
Formattableforstrwith width, alignment, precision (pre-existing, LLVM 2026-02-18)- Evaluator:
ori_eval/src/interpreter/format.rs— full str formatting - Ori Tests:
tests/spec/traits/formattable/definition.ori - LLVM Support:
ori_rt/src/format.rs—ori_format_strruntime function - AOT Tests: AOT tests cover width, fill, precision
- Evaluator:
-
Implement: Sign specifiers (
+,-,) for numeric formatting (pre-existing)- Covered in int.ori and float.ori tests
-
Implement: Alternate form (
#) for prefix formatting (0b, 0o, 0x) (pre-existing)- Covered in int.ori tests
-
Implement: Zero-pad shorthand (
0) for numeric formatting (pre-existing)- Covered in int.ori tests
-
Implement: Custom fill characters (2026-02-18)
- Ori Tests:
tests/spec/traits/formattable/fill.ori - AOT test:
test_aot_format_fill_center
- Ori Tests:
-
Implement: User-defined Formattable with FormatSpec dispatch (2026-02-18)
- Evaluator constructs
Value::Struct(FormatSpec{...})for user-type dispatch - Ori Tests:
tests/spec/traits/formattable/user_impl.ori - GAP(formattable-aot): LLVM codegen for user
Formattable::format()impls requires general trait method call codegen. Currently blocked withrecord_codegen_error()atlower_constructs.rs. Evaluator works correctly.
- Evaluator constructs
-
Implement: Edge cases (bool, char, empty spec, negative hex, zero precision) (2026-02-18)
- Ori Tests:
tests/spec/traits/formattable/edge_cases.ori - LLVM Support:
ori_rt/src/format.rs—ori_format_bool,ori_format_charruntime functions
- Ori Tests:
-
Implement: Error messages E2034-E2035 (pre-existing, renumbered from E0970-E0971)
- E2034: Invalid format specification syntax
- E2035: Format type not supported for this type
-
Update Spec:
09-properties-of-types.md— Formattable trait section present (pre-existing) -
Update Spec:
12-modules.md— FormatSpec, Alignment, Sign, FormatType in prelude types (pre-existing) -
LLVM str.concat() support: Added string concatenation method to LLVM backend (2026-02-18)
- Required for template string desugaring (
.concat()chains) -
ori_llvm/src/codegen/lower_builtin_methods.rs—emit_str_concat_call()
- Required for template string desugaring (
3.17 Into Trait
STATUS: Evaluator COMPLETE, LLVM PARTIAL (verified 2026-03-29 — int->float LLVM done; str->Error blocked by Error type LLVM repr; orphan rules blocked by module system)
Proposal: proposals/approved/into-trait-proposal.md
Formalizes the Into trait for semantic, lossless type conversions. Defines trait signature, standard implementations, relationship to as/as?, and rules for custom implementations.
Implementation
-
Implement:
Into<T>trait definition in type system- Rust Tests:
ori_types/src/infer/expr/tests.rs—into_not_on_named_types_via_builtins(trait dispatch path) - Ori Tests:
tests/spec/traits/into/definition.ori
- Rust Tests:
-
Implement: Into implementation for str→Error
- Rust Tests:
ori_types/src/infer/expr/tests.rs—into_str_resolves_to_error - Ori Tests:
tests/spec/traits/into/str_to_error.ori - LLVM Support: LLVM codegen for str→Error conversion (blocked: Error type has no LLVM representation — TypeInfo::Error is a sentinel)
- AOT Tests:
ori_llvm/tests/aot/traits.rs— str→Error AOT
- Rust Tests:
-
Implement: Into implementation for int→float (numeric widening)
- Rust Tests:
ori_types/src/infer/expr/tests.rs—into_int_resolves_to_float - Ori Tests:
tests/spec/traits/into/int_to_float.ori - LLVM Support: LLVM codegen for int→float conversion (sitofp)
- AOT Tests:
ori_llvm/tests/aot/traits.rs— 3 AOT tests (basic, negative, zero)
- Rust Tests:
-
Implement: Into implementation for Set
→[T] (with T: Eq + Hashable constraint) - Rust Tests:
ori_types/src/infer/expr/tests.rs—into_set_resolves_to_list,into_set_preserves_element_type - Ori Tests:
tests/spec/traits/into/set_to_list.ori - LLVM Support: LLVM codegen for Set→List conversion (identity — same layout)
- AOT Tests:
ori_llvm/tests/aot/traits.rs— Set→List AOT
- Rust Tests:
-
Implement: Custom Into implementations for user types
- Rust Tests:
ori_types/src/infer/expr/tests.rs—into_not_on_named_types_via_builtins(verifies trait registry dispatch path) - Ori Tests:
tests/spec/traits/into/definition.ori(Celsius→str, Wrapper→int)
- Rust Tests:
-
Implement: No blanket identity (no impl
Into for T) - Ori Tests:
tests/compile-fail/into_no_identity.ori
- Ori Tests:
-
Implement: No automatic conversion chaining
- Ori Tests:
tests/compile-fail/into_no_chaining.ori
- Ori Tests:
-
Implement: Orphan rule enforcement for Into implementations
- Rust Tests:
ori_types/src/check/tests.rs— orphan rule tests - Ori Compile-Fail Tests:
tests/compile-fail/into_orphan_rule.ori
- Rust Tests:
-
Implement: Error messages (E2036-E2037)
- E2036: Type does not implement Into
- E2037: Multiple Into implementations apply (ambiguous)
- E2036: Type does not implement Into
-
Update Spec:
09-properties-of-types.md— Into trait section (already present, fixed error codes E0960→E2036, E0961→E2037) -
Update Spec:
12-modules.md— Into already in prelude traits list (verified) -
Update:
.claude/rules/ori-syntax.md— Into already documented in prelude traits (verified)
Note:
str.into()returnsIdx::ERRORdirectly (pre-interned primitive) rather thanpool.named("Error"). TheWellKnownNames.error_typefield was removed as unused. If a future feature needs to resolve “Error” by name at type-check time, re-add it towell_known.rs. Error.message field access is implemented in both type checker (infer_fieldinstructs.rs) and evaluator (eval_field_accessinexpr.rs) — if more Error fields are added (e.g..source), update both.
-
/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 (3.17) — 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-3.17 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 3.17: 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.
3.18 Ordering Type
STATUS: COMPLETE (verified 2026-03-29 — 41 spec tests, all methods complete; only Ordering.default() deferred, blocked by static method support)
Proposal: proposals/approved/ordering-type-proposal.md
Formalizes the Ordering type that represents comparison results. Defines the three variants (Less, Equal, Greater), methods (is_less, is_equal, is_greater, is_less_or_equal, is_greater_or_equal, reverse, then, then_with), and trait implementations.
Implementation
-
Implement:
Orderingtype definition (already in spec astype Ordering = Less | Equal | Greater) [done] (2026-02-10)- Type checking via
Type::Named("Ordering") - Runtime values via
Value::Variant { type_name: "Ordering", ... } - Variants available as bare names:
Less,Equal,Greaterare registered as built-in enum variants- Type registry:
register_builtin_types()inori_types/src/check/registration/mod.rs - Evaluator:
register_prelude()inori_eval/src/interpreter/mod.rs
- Type registry:
- Ori Tests:
tests/spec/types/ordering/methods.ori— 32 tests (all pass)
- Type checking via
-
Implement: Ordering predicate methods (
is_less,is_equal,is_greater,is_less_or_equal,is_greater_or_equal) [done] (2026-02-10)- Type checker:
ori_types/src/infer/ordering.rs - Evaluator:
ori_eval/src/methods.rs—dispatch_ordering_method - Ori Tests:
tests/spec/types/ordering/methods.ori— 15 predicate tests (all pass) - LLVM Support: i8 comparison/arithmetic in
lower_calls.rs
- Type checker:
-
Implement:
reversemethod for Ordering [done] (2026-02-10)- Type checker: Returns
Type::Named("Ordering") - Evaluator: Swaps Less↔Greater, preserves Equal
- Ori Tests:
tests/spec/types/ordering/methods.ori— 4 reverse tests including involution
- Type checker: Returns
-
Implement:
thenmethod for lexicographic comparison chaining [done] (2026-02-15)- Keyword conflict resolved: keywords now valid as member names after
.(grammar.ebnf § member_name) - Parser:
expect_member_name()in cursor, used by postfix.rs - Type checker:
resolve_ordering_method()— returnsIdx::ORDERING - Evaluator:
dispatch_ordering_method()— Equal chains, non-Equal keeps self - IR registry:
builtin_methods.rs—MethodDefwithParamSpec::SelfType - Eval registry:
EVAL_BUILTIN_METHODS—("Ordering", "then") - Ori Tests:
tests/spec/types/ordering/methods.ori— 5 tests (equal chains, non-equal keeps self, chaining) - Rust Tests:
ori_eval/src/tests/methods_tests.rs—then_equal_chains,then_non_equal_keeps_self
- Keyword conflict resolved: keywords now valid as member names after
-
Implement:
then_withmethod for lazy lexicographic chaining (2026-02-18)- Dispatched via
CollectionMethodResolver→OrderingThenWith(closure needs interpreter access) - Type checker:
resolve_ordering_method()— returnsIdx::ORDERING - Collection resolver:
CollectionMethod::OrderingThenWithvariant + resolution onValue::Ordering - Method dispatch:
eval_ordering_then_with()— Equal calls closure, non-Equal returns self - Rust Tests:
ori_types/src/infer/expr/tests.rs—then_with_ordering_resolves_to_ordering - Ori Tests:
tests/spec/types/ordering/then_with.ori— 9 tests (equal/non-equal, laziness, chaining)
- Dispatched via
-
Implement: Trait methods for Ordering (Clone, Printable, Hashable) [done] (2026-02-10)
-
clone()→ returns self — verified in ordering/methods.ori -
to_str()→ “Less”/“Equal”/“Greater” — verified in ordering/methods.ori -
debug()→ “Less”/“Equal”/“Greater” — implemented via generic Debug dispatch [done] (2026-02-18) -
hash()→ distinct values for each variant — verified in ordering/methods.ori
-
-
Implement: Default value is
Equal(via associated functionOrdering.default()) — NOT testable (static methods not supported) -
Update Spec:
06-types.md— Ordering section already comprehensive (lines 571-615): variants, methods, then/then_with, trait impls, default [done] (verified 2026-02-18) -
Update:
CLAUDE.md— Ordering methods documented in.claude/rules/ori-syntax.md[done] (verified 2026-02-18)
3.19 Default Type Parameters on Traits
STATUS: COMPLETE (verified 2026-03-29 — WEAK TESTS: only 2 spec tests for this feature)
Proposal: proposals/approved/default-type-parameters-proposal.md
Allow type parameters on traits to have default values, enabling trait Add<Rhs = Self> where Rhs defaults to Self if not specified. Essential prerequisite for operator traits.
Implementation
-
Implement: Parse default type in
type_paramgrammar rule (identifier [ ":" bounds ] [ "=" type ]) [done] (2026-02-10)- Rust Tests:
ori_parse/src/grammar/item/generics.rs—parse_generics()handles= Typeafter bounds - Ori Tests:
tests/spec/traits/default_type_params.ori— 2 tests (all pass)
- Rust Tests:
-
Implement: Store default types in trait definition AST [done] (2026-02-10)
- Rust Tests:
GenericParaminori_ir/src/ast/items/traits.rshasdefault_type: Option<ParsedType> - Rust Tests:
TraitEntryinori_types/src/check/registration/ (trait types)hasdefault_types: Vec<Option<ParsedType>>
- Rust Tests:
-
Implement: Fill missing type arguments with defaults in impl checking [done] (2026-02-10)
- Rust Tests:
resolve_trait_type_args()intrait_registration.rs - Ori Tests:
tests/spec/traits/default_type_params.ori—impl Point: Addableomits Rhs, uses Self default
- Rust Tests:
-
Implement: Substitute
Selfwith implementing type in defaults [done] (2026-02-10)- Rust Tests:
resolve_parsed_type_with_self_substitution()intrait_registration.rs - Ori Tests:
tests/spec/traits/default_type_params.ori—test_adduses Self default
- Rust Tests:
-
Implement: Ordering constraint enforcement (defaults must follow non-defaults) [done] (2026-02-10)
- Rust Tests:
validate_default_type_param_ordering()intrait_registration.rs - Error Code: E2015 (type parameter ordering violation)
- Rust Tests:
-
Implement: Later parameters can reference earlier ones in defaults [done] (2026-02-10)
- Design: Stored as
ParsedType, resolved at impl time with substitution - Verified:
trait Transform<Input = Self, Output = Input>in default_type_params.ori
- Design: Stored as
-
Update Spec:
grammar.ebnf§ Generics —type_param = identifier [ ":" bounds ] [ "=" type ] .[done] (verified 2026-02-15, already present) -
Update Spec:
08-declarations.md— Default Type Parameters section under Traits [done] (verified 2026-02-15, already present at line 230) -
Update:
CLAUDE.md—trait N<T = Self>syntax documented [done] (verified 2026-02-15, already in ori-syntax.md)
3.20 Default Associated Types
STATUS: COMPLETE (verified 2026-03-29 — bounds checking on defaults deferred)
Proposal: proposals/approved/default-associated-types-proposal.md
Allow associated types in traits to have default values, enabling type Output = Self where implementors can omit the associated type if the default is acceptable. Works alongside default type parameters to enable operator traits.
Implementation
-
Implement: Parse default type in
assoc_typegrammar rule ("type" identifier [ ":" bounds ] [ "=" type ]) [done] (2026-02-10)- Rust Tests:
ori_parse/src/grammar/item/trait_def.rs— default assoc type parsing - Ori Tests:
tests/spec/traits/default_assoc_types.ori— 4 tests (all pass)
- Rust Tests:
-
Implement: Store default types in trait definition AST for associated types [done] (2026-02-10)
- Rust Tests:
ori_ir/src/ast/items/traits.rs—TraitAssocType.default_type: Option<ParsedType>
- Rust Tests:
-
Implement: Fill missing associated types with defaults in impl checking [done] (2026-02-10)
- Rust Tests:
ori_types/src/check/registration/ (trait registration)—validate_associated_types()uses defaults - Ori Tests:
tests/spec/traits/default_assoc_types.ori— Point impl omits Output, uses Self default
- Rust Tests:
-
Implement: Substitute
Selfwith implementing type in defaults [done] (2026-02-10)- Rust Tests:
ori_types/src/check/ (trait registry)—resolve_parsed_type_with_self_substitution() - Ori Tests:
tests/spec/traits/default_assoc_types.ori— verified with Point (default Output=Self) and Number (overridden Output=int)
- Rust Tests:
-
Implement: Defaults can reference type parameters and other associated types [done] (2026-02-10)
- Note: Basic support implemented; complex cascading defaults deferred
-
Implement: Bounds checking — verify default satisfies any bounds after substitution
- Note: Deferred to future enhancement; bounds on associated types not yet fully implemented
-
Update Spec:
grammar.ebnf— update assoc_type production [done] (verified 2026-02-15, already present:assoc_type = "type" identifier [ ":" bounds ] [ "=" type ]) -
Update Spec:
08-declarations.md— add Default Associated Types section [done] (verified 2026-02-15, already present at line 272 with bounds section) -
Update:
CLAUDE.md— add default associated type syntax to Traits section [done] (verified 2026-02-15, already in ori-syntax.md:type Output = Selfdefault)
3.21 Operator Traits
STATUS: COMPLETE (verified 2026-03-29 — type checker desugaring, evaluator dispatch, LLVM codegen, error messages all working; derive for newtypes optional/deferred; MatMul 3.21.1 not started)
Proposal: proposals/approved/operator-traits-proposal.md
Defines traits for arithmetic, bitwise, and unary operators that user-defined types can implement to support operator syntax. The compiler desugars operators to trait method calls. Enables Duration and Size types to move to stdlib.
Dependencies
- Default Type Parameters on Traits (3.19) — for
trait Add<Rhs = Self>[done] (2026-02-10) - Default Associated Types (3.20) — for
type Output = Self[done] (2026-02-10)
Implementation
-
Implement: Define operator traits in prelude (via trait registry lookup) [done] (2026-02-15)
-
Add<Rhs = Self>,Sub<Rhs = Self>,Mul<Rhs = Self>,Div<Rhs = Self>,FloorDiv<Rhs = Self>,Rem<Rhs = Self> -
Neg,Not,BitNot -
BitAnd<Rhs = Self>,BitOr<Rhs = Self>,BitXor<Rhs = Self>,Shl<Rhs = int>,Shr<Rhs = int> - Files:
library/std/prelude.ori— all operator traits defined with associatedOutputtype - Ori Tests:
tests/spec/traits/operators/user_defined.ori— 16 tests covering all operators
-
-
Implement: Operator desugaring in type checker [done] (2026-02-15)
-
a + b→a.add(rhs: b)(etc. for all binary operators) -
-a→a.negate(),!a→a.not(),~a→a.bit_not()(unary operators) - Files:
ori_types/src/infer/expr/operators.rs—resolve_binary_op_via_trait(),resolve_unary_op_via_trait() - Files:
ori_types/src/infer/mod.rs—intern_name()helper on InferEngine
-
-
Implement: Operator dispatch in evaluator via trait impls [done] (2026-02-15)
- Files:
ori_eval/src/interpreter/mod.rs—eval_binary(),binary_op_to_method() - Files:
ori_eval/src/methods.rs— operator methods for primitives - Ori Tests:
tests/spec/traits/operators/user_defined.ori— 16 tests (Add, Sub, Neg, Mul, Div, Rem, FloorDiv, BitAnd, BitOr, BitXor, Shl, Shr, BitNot, Not, chaining, double negation) - LLVM Support: LLVM codegen for operator trait dispatch — Tier 1 (
lower_operators.rs) and Tier 2 (arc_emitter.rs) [done] (2026-02-15) - AOT Tests:
ori_llvm/tests/aot/traits.rs— 7 AOT tests (add, sub, neg, mul_mixed, chained, bitwise, not) [done] (2026-02-15)
- Files:
-
Implement: Built-in operator implementations for primitives (NOT trait-based, direct evaluator dispatch) [done] (2026-02-10)
-
int: Add, Sub, Mul, Div, FloorDiv, Rem, Neg, BitAnd, BitOr, BitXor, Shl, Shr, BitNot -
float: Add, Sub, Mul, Div, Neg -
bool: Not -
str: Add (concatenation) -
list: Add (concatenation) -
Duration: Add, Sub, Mul (with int), Div (with int), Rem, Neg -
Size: Add, Sub, Mul (with int), Div (with int), Rem - Files:
ori_eval/src/methods.rs—dispatch_int_method(),dispatch_float_method(), etc.
-
-
Implement: User-defined operator implementations [done] (2026-02-15)
- Ori Tests:
tests/spec/traits/operators/user_defined.ori— 16 tests all passing - Type checker desugars
a + btoa.add(rhs: b)via TraitRegistry lookup - Evaluator dispatches to impl methods for non-primitive types
- Ori Tests:
-
Implement: Mixed-type operations with explicit both-direction impls [done] (2026-02-10)
- Example:
Duration * intandint * Duration - Files:
ori_eval/src/interpreter/mod.rs—is_mixed_primitive_op()
- Example:
-
Implement: Error messages for missing operator trait implementations [done] (2026-02-15)
- E2020: Type does not implement operator trait (for user-defined types)
- Primitives keep original error messages (e.g., “cannot apply
-tostr”) - Files:
ori_types/src/type_error/check_error/mod.rs—UnsupportedOperatorvariant - Files:
ori_diagnostic/src/error_code/mod.rs— E2020 error code - Files:
ori_diagnostic/src/errors/E2020.md— error documentation - Ori Compile-Fail Tests:
tests/compile-fail/operator_trait_missing.ori— 5 tests (Add, Neg, Not, BitNot, BitAnd)
-
Implement: Derive support for operator traits on newtypes (OPTIONAL)
-
#derive(Add, Sub, Mul, Div)generates field-wise operations - Rust Tests:
ori_types/src/check/ (derives)— operator derive tests - Ori Tests:
tests/spec/traits/operators/derive.ori
-
-
Update Spec:
09-expressions.md— Operator Traits section [done] (verified 2026-02-15, already present at line 403 with full trait/method/desugaring tables) -
Update:
CLAUDE.md— operator traits in prelude and operators section [done] (verified 2026-02-15, already in ori-syntax.md lines 93 and 191)
3.21.1 MatMul Operator (@)
Proposal: proposals/approved/matmul-operator-proposal.md
Add @ as a binary operator for matrix multiplication at multiplicative precedence (level 3), desugaring to the MatMul trait method matrix_multiply(). Follows Python PEP 465 convention for ML/scientific computing adoption. The @ token is disambiguated by parser context (item position = function sigil, expression position = matmul operator, pattern position = binding).
Dependencies
- Operator Traits (3.21) — trait dispatch infrastructure [done]
Implementation
-
Implement: Add
MatMulvariant toBinaryOpin IR-
BinaryOp::MatMul+ arms inas_symbol(),precedence(),trait_method_name(),trait_name() - Files:
ori_ir/src/ast/operators.rs - Rust Tests:
ori_ir/src/ast/operators/tests.rs
-
-
Implement: Parser — add
TokenKind::Atto multiplicative precedence level- Add entry to
OPER_TABLEingrammar/expr/operators.rs - Files:
ori_parse/src/grammar/expr/operators.rs - Rust Tests:
ori_parse/src/grammar/expr/operators/tests.rs— matmul parsing - Ori Tests:
tests/spec/operators/matmul.ori— precedence, associativity, disambiguation
- Add entry to
-
Implement: Evaluator — add
BinaryOp::MatMulerror arms to primitive type handlers- ~17 match arms returning “type does not implement MatMul” for all primitive handlers
- Files:
ori_eval/src/operators.rs
-
Implement: Define
MatMultrait in prelude-
trait MatMul<Rhs = Self> { type Output = Self; @matrix_multiply (self, rhs: Rhs) -> Self.Output } - Files:
library/std/prelude.ori - Ori Tests:
tests/spec/traits/operators/matmul.ori— user-defined MatMul impl
-
-
Implement: LLVM codegen support
- Falls through via trait dispatch — verify no special-casing needed
- AOT Tests:
ori_llvm/tests/aot/traits.rs— matmul codegen test
-
Update Spec:
operator-rules.md— add@to multiplicative group and trait dispatch table -
Update Spec:
grammar.ebnf— add"@"tomul_exprproduction -
Update:
.claude/rules/ori-syntax.md— document@operator andMatMultrait -
/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 (3.21) — 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-3.21 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 3.21: 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.
3.22 Bound Syntax — ELIMINATED (Capability Unification)
STATUS: ELIMINATED (verified 2026-03-29 — correctly eliminated per 2026-03-04 capability-unification decision)
Proposal: proposals/approved/capability-unification-generics-proposal.md — Phase 2 (eliminated)
Status: This section is no longer needed. The 2026-03-04 addendum to the capability-unification-generics-proposal decided to retain : for all bound positions (generic parameters, where clauses, supertrait declarations, impl block bounds). No parser changes, no test migration, no spec updates for bound syntax. Only the #derive → : trait clause on type declarations is a new syntax change (tracked in Section 5).
-
/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 (3.22) — 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-3.22 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 3.22: 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.
3.23 Impl Colon Syntax
STATUS: NOT STARTED (verified 2026-03-29 — all items unchecked)
Proposal: proposals/approved/impl-colon-syntax-proposal.md
Replace impl Trait for Type with impl Type: Trait — subject-first ordering, completes : = “conforms to” unification across all five conformance positions.
Implementation
-
Implement: Parser change —
impl Type: Traitreplacesimpl Trait for Type- Update
ori_parse/src/grammar/item/impl_def/mod.rs— parse type first, then:+ trait - Update parser tests in
impl_def/tests.rs - Rust Tests: Parser unit tests for new syntax
- Ori Tests: Migrate all
.oritest files fromimpl Trait for Typetoimpl Type: Trait(~34 files, ~111 occurrences — deferred until parser supports new syntax)
- Update
-
Implement: Error recovery — detect old
impl Trait for Typesyntax and suggest fix- Rust Tests: Recovery test for old syntax
-
Migrate: Update all
.oritest/spec files to new syntax-
tests/spec/traits/— 30 files -
tests/compile-fail/— 3 files -
tests/fmt/declarations/impls/— 1 file
-
-
Verify: All spec tests pass with new parser
-
cargo st— full spec test suite -
cargo t— full Rust test suite
-
-
/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 (3.23) — 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-3.23 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 3.23: 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.
3.24 Value Trait (ARC-Free Value Types)
STATUS: NOT STARTED (verified 2026-03-29 — all items unchecked across 5 phases)
Proposal: proposals/approved/value-trait-proposal.md
Marker trait guaranteeing inline storage, bitwise copy, no ARC, and no Drop. Supersedes the Copy trait slot and inline type keyword reservation.
Phase 1: Type Checker Validation
-
Implement: Register
Valuein prelude as marker trait (no methods) —ori_types/check/registration/- Supertrait:
Clone + Eq - Cannot be manually implemented (like
Sendable) - Rust Tests: Registration tests in
ori_types/check/registration/tests.rs
- Supertrait:
-
Implement:
Valuevalidation pass —ori_types/check/- All fields recursively satisfy
Value - No
Dropimpl registered for the type - No recursive type structure
- Size within threshold (warning >256 bytes, error >512 bytes)
-
Valuetypes automatically satisfySendableandClone - Rust Tests: Validation tests in
ori_types/check/
- All fields recursively satisfy
-
Implement: Error codes E2040-E2043, warning W2040
- E2040: Field does not satisfy
Value - E2041:
Valuetype cannot implementDrop - E2042:
Valuetype exceeds maximum size (512 bytes) - E2043: Type does not satisfy
Valuebound - W2040:
Valuetype is large (>256 bytes) - Ori Tests:
tests/compile-fail/traits/value/— field violations, Drop conflict, size error - Ori Tests:
tests/spec/traits/value/— valid value types, generics, patterns
- E2040: Field does not satisfy
-
Implement: Primitive types implicitly satisfy
Value-
int,float,bool,char,byte,void,Duration,Size,Ordering,Never -
strdoes NOT satisfyValue - Rust Tests: Primitive Value satisfaction tests
-
Phase 2: ARC Pipeline Fast Path
-
Implement: Fast path in
ori_arc/src/classify/mod.rs— types withValuetrait ->ArcClass::Scalar- Skip field traversal for Value types
- Rust Tests:
ori_arc/src/classify/tests.rs
-
Implement: Skip borrow inference for
Valueparameters —ori_arc/src/borrow/- Always cheap to copy, no borrow optimization needed
- Rust Tests: Borrow inference tests
-
Implement: Skip RC insertion for
Value-typed variables —ori_arc/src/rc_insert/- Rust Tests: RC insertion skip tests
Phase 3: Evaluator Support
- Implement:
Valuetrait recognition in evaluator —ori_eval/- Auto-satisfy Clone for Value types (bitwise copy)
- Rust Tests: Evaluator Value type tests
- Ori Tests:
tests/spec/traits/value/— runtime behavior
Phase 4: LLVM Codegen Optimization
- Implement:
memcpyforValuetypes —ori_llvm/- Value types passed by value (no indirection through pointers) when <=2 registers
- No RC inc/dec emitted for Value types
- LLVM SROA and constant folding work on Value types
- LLVM Rust Tests:
ori_llvm/tests/aot/value_types.rs - Ori Tests: AOT tests for Value type operations
Phase 5: Const Generic Integration (Future)
-
Implement:
Value + Hashabletypes eligible as const generic parameters- Ori Tests: Const generic with Value types
-
/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 (3.24) — 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-3.24 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 3.24: 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.
3.25 Structural Trait Defaults
Status: Not Started
Goal: Formalize and complete structural trait defaults — Eq/Clone/Debug/Printable work without declaration on all types; eq → equals method rename; LLVM codegen parity with evaluator for enum structural equality and structural Clone/Debug/Printable fallbacks.
Context: Ori is a pure value-type language. The evaluator has always performed structural equality for all types without requiring #derive(Eq). The type checker does not gate ==/!= on the Eq trait. The LLVM codegen has structural eq fallback for structs but not enums. This subsection formalizes this behavior per the approved structural-trait-defaults-proposal (2026-04-02) and closes the LLVM codegen gaps.
Proposal: docs/ori_lang/proposals/approved/structural-trait-defaults-proposal.md
Reference implementations:
- Gleam
compiler-core/src/type_/expression.rs: all types structurally comparable — no Eq trait requirement - Elm
compiler/src/Type/Error.hs: structural equality built-in for all values - Roc
crates/compiler/mono/src/ir.rs: structural equality as default for all types
Depends on: None (evaluator and type checker already implement this behavior).
Key design decisions:
- Two-tier model: Structural
==/!=works on all types without declaration. Declaringtype T: Eq = {...}generates a namedequalsmethod for trait dispatch in genericT: Eqcontexts. - Comparable/Hashable/Default require explicit declaration — no structural default (field ordering is semantic, not structural).
eq→equalsmethod rename — unifies a partial rename already in progress (evaluator and mangling use"equals", IR and codegen use"eq").
-
/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 (3.25) — 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-3.25 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 3.25: 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.
3.25.1 eq → equals Method Rename
File(s): ori_ir/src/derives/mod.rs, library/std/prelude.ori, ori_llvm/src/codegen/arc_emitter/builtins/compound_traits.rs, ori_llvm/src/codegen/arc_emitter/operators/mod.rs, ori_llvm/src/codegen/derive_codegen/field_ops/thunks.rs, ori_eval/src/derives/tests.rs, ori_ir/src/derives/tests.rs
The codebase has a partial inconsistency: the evaluator runtime (MethodNames.equals), mangling ($equals), type checker registration, and some test files already use "equals". The IR source of truth (DerivedTrait::Eq.method_name()) and LLVM codegen hardcode "eq". This subsection unifies to "equals" everywhere.
Rename targets (must change):
| File | Current | Change To |
|---|---|---|
compiler/ori_ir/src/derives/mod.rs line 145 | "eq" in define_derived_traits! macro | "equals" |
library/std/prelude.ori line 20 | @eq (self, other: Self) -> bool | @equals (self, other: Self) -> bool |
compiler/ori_ir/src/derives/tests.rs line 29 | assert_eq!(DerivedTrait::Eq.method_name(), "eq") | "equals" |
compiler/ori_llvm/src/codegen/arc_emitter/operators/mod.rs lines 203-204 | "eq" in operator dispatch | "equals" |
compiler/ori_llvm/src/codegen/arc_emitter/builtins/compound_traits.rs line 216 | self.interner.intern("eq") | self.interner.intern("equals") |
compiler/ori_llvm/src/codegen/derive_codegen/field_ops/thunks.rs | fc.intern("eq") | fc.intern("equals") |
compiler/ori_eval/src/derives/tests.rs (3 occurrences) | interner.intern("eq") | interner.intern("equals") |
Already correct (no change needed):
-
Evaluator runtime
MethodNames.equals— already uses"equals" -
Mangling (
_ori_int$$Eq$equals) — already uses"equals" -
Type checker registration — already uses
"equals" -
BinaryOp::Eqenum variant — this is the operator, not the method name -
LLVM IR builder labels (e.g.,
icmp_eq(a, b, "eq")) — these are IR instruction names, not method names -
Write failing tests first: Add test in
ori_ir/src/derives/tests.rsassertingDerivedTrait::Eq.method_name() == "equals"; verify it fails -
Rename source of truth: Change
"eq"to"equals"inori_ir/src/derives/mod.rsline 145 (define_derived_traits!macro entry for Eq) -
Update prelude: Change
@eqto@equalsinlibrary/std/prelude.ori -
Update LLVM codegen: Change all
intern("eq")tointern("equals")in:-
compound_traits.rs—emit_derived_eq_call -
operators/mod.rs— operator dispatch tuple -
derive_codegen/field_ops/thunks.rs— derive thunk emit
-
-
Update evaluator tests: Change
interner.intern("eq")→interner.intern("equals")inori_eval/src/derives/tests.rs(3 occurrences) -
Update pattern tests: Change
method_name() == "eq"→"equals"inori_patterns/src/user_methods/tests.rs -
Verify existing tests pass:
timeout 150 cargo t— all existing tests must pass after rename (evaluator/mangling already use “equals”) -
Semantic pin: Add Ori spec test
tests/spec/traits/derive/eq_method_name.orithat calls.equals()directly on a derived Eq type — proves the method is accessible by the new name
Test matrix:
- Types: struct (single-field, multi-field), newtype, enum (unit variants, payload variants)
- Patterns: direct
==, direct!=, method call.equals(other:), use in genericT: Eqcontext - Backends: eval + LLVM (debug + release)
3.25.2 LLVM Enum Structural Equality
File(s): compiler/ori_llvm/src/codegen/arc_emitter/builtins/compound_traits.rs
Currently, when emit_element_equals encounters an enum type at line 205, it only tries emit_derived_eq_call — there is no structural fallback. Structs have this fallback (line 200-203: try derived, .or_else(|| self.emit_structural_eq(...))). This means enums without #derive(Eq) cannot be compared in LLVM codegen, even though the evaluator compares them structurally.
Pattern to follow: compiler/ori_llvm/src/codegen/derive_codegen/enum_bodies/enum_comparable.rs (lines 21-73) — emit_enum_lexicographic() shows the exact tag-extraction + payload-switch pattern for enum comparison in LLVM IR.
Algorithm for emit_structural_enum_eq:
- Extract discriminant (tag) from both
lhsandrhsviaextract_value(val, 0, ...) - Compare tags with
icmp_eq - If tags differ → return
false - If tags match → switch on tag value, for each variant:
- If unit variant (no payload) → contribute
true - If payload variant → extract payload fields, recursively call
emit_element_equalson each, accumulate with AND
- If unit variant (no payload) → contribute
- Return accumulated result via phi node
- Write failing test first: Add AOT test
compiler/ori_llvm/tests/aot/structural_eq.rswith enum type having no#derive(Eq), assert==/!=work correctly- Unit-variant enum:
type Color = Red | Green | Blue - Payload enum:
type Shape = Circle(r: float) | Rect(w: float, h: float) - Verify test fails (LLVM can’t emit structural enum eq)
- Unit-variant enum:
- Implement
emit_structural_enum_eqincompound_traits.rs:- Add function signature:
fn emit_structural_enum_eq(&mut self, lhs: ValueId, rhs: ValueId, variants: &[...], ty: Idx) -> Option<ValueId> - Implement tag extraction and comparison
- Implement variant-switch payload comparison (reuse
emit_element_equalsfor recursion) - Handle edge cases: all-unit enum (no payload switch needed), single-variant enum
- Add function signature:
- Wire into dispatch: Change line 205 from:
to:TypeInfo::Enum { .. } => self.emit_derived_eq_call(lhs, rhs, elem_ty),TypeInfo::Enum { variants, .. } => { let variants = variants.clone(); self.emit_derived_eq_call(lhs, rhs, elem_ty) .or_else(|| self.emit_structural_enum_eq(lhs, rhs, &variants, elem_ty)) } - Verify tests pass: All new AOT tests pass in debug and release
- Dual-execution parity: Run
diagnostics/dual-exec-verify.shon test programs — evaluator and LLVM must produce identical results - Semantic pin: Test that verifies enum structural eq works WITHOUT
#derive(Eq)— would fail if fallback is removed - Negative pin: Test that verifies a type with custom
impl T: Equses the custom method, not structural default
Test matrix:
- Types: unit enum, payload enum (single field, multi-field), nested enum (enum containing enum), enum with struct payload, Option-like enum, Result-like enum
- Patterns:
==same variant,==different variant,!=, nested comparison - Backends: LLVM debug + release (FastISel divergence check)
3.25.3 LLVM Structural Clone/Debug/Printable Fallbacks
File(s): compiler/ori_llvm/src/codegen/arc_emitter/builtins/compound_traits.rs, compiler/ori_llvm/src/codegen/arc_emitter/builtins/debug_helpers.rs
Currently:
- Clone: No structural fallback. Types without
#derive(Clone)cannot be cloned in LLVM codegen (evaluator clones all types structurally). - Debug: Falls back to
"<?>"literal when no derived debug method exists (line 189-190 ofdebug_helpers.rs). Should produceTypeName { field: value, ... }structurally. - Printable: Same as Debug — falls back to
"<?>". Should produce the same structural format as Debug default.
Implementation order: Clone first (simplest — no string building), then Debug (requires string concatenation), then Printable (identical to Debug structural default).
Phase A: Structural Clone
- Write failing test: AOT test with struct/enum without
#derive(Clone), call.clone()structurally - Implement
emit_structural_cloneincompound_traits.rs:- For structs: extract each field, recursively clone, rebuild struct via
insert_value - For enums: extract tag + payload, switch on tag, clone payload fields per variant, rebuild
- Wire into clone dispatch with
.or_else(|| self.emit_structural_clone(...))
- For structs: extract each field, recursively clone, rebuild struct via
- Verify: Tests pass, dual-exec parity
Phase B: Structural Debug
- Write failing test: AOT test with struct/enum without
#derive(Debug), call.debug(), verify output format - Implement
emit_structural_debugindebug_helpers.rs:- Build string:
TypeName { field1: <debug(f1)>, field2: <debug(f2)>, ... } - Use
emit_literal_ori_strfor type/field names,emit_element_debugfor field values - Concatenate via
emit_str_concat(runtime callori_str_concat) - Handle enums:
VariantName(unit) orVariantName(field1: <debug>, ...) - Handle Sret return convention (debug returns
str= 24 bytes)
- Build string:
- Wire into dispatch: Replace
"<?>"fallback at line 189-190 with structural debug - Verify: Tests pass, dual-exec parity, output matches evaluator format
Phase C: Structural Printable (to_str)
- Write failing test: AOT test with struct/enum without
#derive(Printable), call.to_str()or use in string interpolation - Implement
emit_structural_to_str: Identical to structural debug (same format per proposal) - Wire into dispatch in the to_str emission path
- Verify: Tests pass, dual-exec parity
Test matrix (all three phases):
- Types: empty struct, single-field struct, multi-field struct, newtype, unit enum, payload enum, nested types (struct containing enum), generic types
- Patterns: direct method call (
.clone(),.debug(),.to_str()), use in string interpolation (Printable), use indbg()(Debug) - Backends: eval + LLVM (debug + release)
- Format verification: structural output matches
TypeName { field: value }format exactly
3.25.4 Spec and Documentation Updates
File(s): docs/ori_lang/v2026/spec/operator-rules.md, docs/ori_lang/v2026/spec/09-properties-of-types.md, .claude/rules/ori-syntax.md
- Update
operator-rules.md: RemoveT : Eqprecondition from EQ type rule (Annex B, Comparison section)- Change from:
e1 : T e2 : T T : Eq → e1 ==|!= e2 : bool - Change to:
e1 : T e2 : T → e1 ==|!= e2 : bool - Add NOTE: structural equality is the default; declaring
Eqenables trait dispatch - ORD rule (Comparable) remains unchanged
- Change from:
- Update
09-properties-of-types.md: Redefine Eq as “custom equality override” rather than “enables equality”- Document structural defaults for Eq, Clone, Debug, Printable
- Document that Comparable/Hashable/Default require explicit declaration
- Document the two-tier model
- Rename
@eqto@equalsin trait definition
- Update
08-types.mdNewtype section: Document that newtypes inherit structural comparison from inner type - Update
.claude/rules/ori-syntax.md:- Update Eq trait description to reflect structural defaults
- Update method name from
eqtoequals - Add note about two-tier model (structural vs declared)
- Update design doc: Remove Eq requirement from binary operations diagram in
docs/compiler/design/05-type-system/index.md(line ~250:T == T → bool (where T: Eq)) - Update LLVM codegen comment: Remove stale comment in
ori_llvm/src/codegen/arc_emitter/operators/mod.rsline 201 referencing old “eq” method name - Verify spec consistency: No contradictions between operator-rules.md, 09-properties-of-types.md, and ori-syntax.md
3.25.R Third Party Review Findings
- None.
3.25.N Completion Checklist
-
eq→equalsrename complete across all crates (ori_ir, ori_llvm, prelude.ori, all tests) - Enum structural equality works in LLVM codegen without
#derive(Eq) - Structural Clone fallback works in LLVM codegen without
#derive(Clone) - Structural Debug fallback works in LLVM codegen without
#derive(Debug)(producesTypeName { field: value }format) - Structural Printable fallback works in LLVM codegen without
#derive(Printable) - Spec updated: EQ rule no longer requires
T : Eq -
09-properties-of-types.mddocuments structural defaults and two-tier model -
.claude/rules/ori-syntax.mdupdated withequalsmethod name - All AOT tests pass in both debug and release:
timeout 150 cargo b && timeout 150 cargo b --release && timeout 150 ./test-all.sh - Dual-execution parity verified for all new test programs
-
ORI_CHECK_LEAKS=1reports zero leaks on all new test programs - Plan annotation cleanup: no stale plan annotations in
.rsfiles -
/tpr-reviewpassed -
/impl-hygiene-reviewpassed -
/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.
Exit Criteria: All types (structs, enums, newtypes) support ==/!=, .clone(), .debug(), and .to_str() structurally in both evaluator and LLVM codegen without requiring #derive(...). The equals method name is consistent across all compiler crates. Spec reflects structural defaults. Zero regressions in ./test-all.sh (debug and release). Dual-execution parity confirmed for all new test programs.