v0.19.0 Phase 2 Collection Ordering Review
Result: passed (2026-08-28). This review covers the public readwrite-slice sort contract, strict-order selection, in-place movement of move-only values, destruction, Vec coercion reuse, complexity and allocation bounds, module responsibility, native behavior, and editor behavior introduced by v0.19.0 Phase 2.
Review Criteria
The review traced:
- every comparison from the generic
(&T < &T): boolrequirement to the concrete selected operation; - every owner moved out of and back into a slice slot, including duplicate-key and early-return paths;
- arithmetic used for heap children and element byte offsets;
- the public declaration selected for explicit slice views and coerced Vec receivers;
- all new standard-library source and module dependencies;
- public contract and implementation-source hover, member completion, and navigation;
- duplicate algorithms, Vec forwarding methods, unnecessary private wrappers, allocation, compatibility behavior, new compiler primitives, and editor-only reconstruction.
Findings and Remediation
Stability would conflict with the bounded-storage goal
A stable general-purpose sort either needs additional owned storage or a substantially more complex in-place merge algorithm. Neither cost should be hidden behind a first practical ordering API. The accepted contract explicitly permits equivalent elements to move, guarantees constant auxiliary storage and O(n log n) worst-case work, and leaves a future stable operation as a separate contract. The method name remains sort; instability is a documented semantic property, not an implementation accident.
Ordering initially entered the slice observation source
The first body was added to slice/views.nct, which would have made borrowed observation and owner-moving mutation share one source responsibility. The completed structure places all heap ordering and raw movement in slice/ordering.nct. slice/views.nct retains only length, pointer, borrowed search, equality, and lexicographic comparison.
The first completed method retained a redundant private forwarding function
An intermediate implementation placed the heap loops in a private free sort function and made the method body forward to it. Since no second consumer existed, that wrapper added another name without defining a boundary. The loops now live directly in the contract-completing method body; only sift_down and swap_elements, which each isolate reused invariants, remain helpers.
Fixed-array unsizing is an independent language capability
Nocter currently has no public fixed-array-to-slice conversion. Adding one would affect coercion, provenance, method selection, and the language specification beyond collection ordering. Phase 2 does not add an implicit conversion merely to broaden a test. Direct slice behavior is exercised through an explicit Vec readwrite view, while ordinary Vec method syntax separately proves the existing receiver coercion. Fixed-array unsizing can be designed independently if a practical consumer requires it.
The native fixture obscured its orchestration function
Embedding the complete Nocter acceptance package inside the Rust test function crossed the workspace line-count guard. The source is now an immutable file-scope fixture, while the test function owns only temporary package creation, discovery, compilation, and execution. No lint exception was added.
Final Boundary Assessment
spec/21-practical-standard-library.mdexclusively owns ascending result, instability, complexity, failure, allocation, and ownership behavior.std/slice/index.nctowns the sole public declaration.std/slice/ordering.nctowns the sole algorithm and raw movement;std/veccontains nosortdeclaration or wrapper.- strict-order selection remains the existing compiler-checked generic operation. The algorithm
calls
<directly and does not reconstruct dispatch, call equality, or accept a parallel comparator abstraction. - every comparison runs while the complete slice is initialized.
swap_elementsperforms no user call or fallible operation after opening its first slot and fills both slots before returning. - valid slice layout makes element offsets representable. The
root < end / 2condition makesroot * 2 + 1representable and within the active heap. - the algorithm allocates no storage and introduces no recoverable failure. Two moved locals are its only element-sized auxiliary owners.
- native acceptance proves reverse and mixed integer order, empty and one-element inputs, already ordered input, duplicate keys, String ordering through coercion, move-only values, and exactly one destruction per original owner.
- LSP completion exposes
sorton Vec, and definition navigation reaches the slice contract rather than an invented Vec declaration. Contract and body hover use the same checked program as native compilation. - no compiler source, primitive registry, compatibility path, or reviewed module dependency set changed.
No unresolved correctness or responsibility-boundary finding remains in Phase 2 scope.
Verification
The completed tree passed with /private/tmp/nocter-v019-phase2 as the external Cargo target:
cargo test --locked --manifest-path development/compiler/Cargo.toml --workspace
cargo clippy --locked --manifest-path development/compiler/Cargo.toml \
--workspace --all-targets -- -D warnings
cargo fmt --manifest-path development/compiler/Cargo.toml --all -- --check
node docs/build-docs.js
git diff --check