Repository navigation
feat(ts): key collections by a bound type through its binding's Hash, Eq, and Ord - #299
Conversation
Quest-Claim: 0e312ce6be571f3a
… Eq, and Ord A hash or B-tree key holding a bound type, alone or in a tuple, Option, or Arc, hashes, compares, and orders through the exports of its Rust impls, as one of the crate's own types does through its translated impls. A hash collection finds even a bound value that is a JS primitive by them. A binding missing an export a key needs fails at that impl's span. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 13 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: d591e9e
No actionable bugs found. Reusing resolved Rust trait instances for bound keys is a sound direction and avoids a parallel binding-dispatch mechanism. Forcing custom hashing/equality for primitive-valued bindings addresses the important representation mismatch, while retaining the existing refusal paths for unsupported comparison/hash overrides and drop-sensitive B-tree collection.
The Blob and Nibble fixtures exercise both object-valued and primitive-valued bindings. Consider adding nested Option/Reverse/tuple/Arc bound-key cases to directly cover the documented wrapper support and the all-hashing flag propagation.
Verification: static review of the lowering changes, surrounding key dispatch, documentation and fixtures only. Tests, builds and the reported differential/mutation checks were not run or independently verified.
Problem
A hash or B-tree collection keyed by a type bound in
ts.tomlwas refused ("hashing/comparing/orderingkey::Nibble..., which is not supported yet" at the collection'snew), so a consumer that binds a type such asbytes::Bytescould not key a map by it. Completes quest/m3/ts-bind-gaps.md.Approach
collections.rskey dispatch (eq_fn,hash_fn,cmp_fn,std_key,own_ne,own_test,own_hash_slice, B-treerange) treats a bound type as it does the crate's own: through its Rust impl's instance, whichfn_valuealready resolves to the binding's export. One helper,local, replaces the repeatedownchecks. No parallel dispatch.rt.hashinggetsall = truefor a bound key (or anOption/Reverseof one), since aCopybinding may be a JS primitive whose===disagrees with itsEq, as feat(ts): translate accessors of elements whose None is rt.None #292 did for fieldless enums.own_ordcounts a boundOrdas hand-written, so a B-treecollectof entries that drop is refused as for a hand-writtenOrd.tsccheck at that impl's span (seewrong.txt).ts/README.mdBindings states the contract:hash$Hash(self, state: rt.Hasher): undefinedandeq$PartialEqfor hash collections,cmp$Ordfor B-trees,partialCmp$PartialOrdfor a B-tree'srange, each agreeing with the Rust impl.Consumer: none in moq today (
ts/moq/ts.tomlbinds nothing); this closes the m3 bindings-contract gap #127 recorded, for any consumer keying a map by a bound type. Exercised by thebindfixture.Tests (
bindfixture, differential against native wasm32):Blob([u8]-like,Hash/Ordasbytes::Bytes) keysHashSet,HashMap(entry),BTreeSet,BTreeMap; a fresh copy finds slices of a different buffer (HashandEqmust agree), pluscontains,get,remove,range, and B-tree order.key::Nibble, aCopybinding that is a JS number equal by its low 4 bits: which key each collection keeps,insertresults, lookups, and order. Droppingall = truemakes the differential fail (14601 differences).wrong.toml: aBlobbinding lackinghash$Hash,cmp$Ord, andpartialCmp$PartialOrdfails at each impl.Impact
ts.tomlbindings (additive): a bound type may keyHashMap,HashSet,BTreeMap,BTreeSet, alone or in a tuple,Option, orArc, givenhash$Hash,eq$PartialEq,cmp$Ord, andpartialCmp$PartialOrd(forrange) exports. Nothing that translated before changes requirements, so noMIGRATE.mdentry.Alternatives
ts.tomlkey naming hash/eq functions): rejected, since the Rust impls already name the exports andtscalready checks them.Eqis not===.Choices made without asking
key::Nibbleto thebindfixture as a primitive-valued binding, sinceBlobalone can't show theallflag.Follow-ups
None.
Review
quest review --deep, Codexgpt-6-astraat medium effort, headd591e9eae8d2910b82a4d6520aa14bef90621686againstorigin/mainf7f0e722: no findings.just cipassed ond591e9ea.Clean merge of main at
955ac19f(#296, #297, #300) intod591e9ea, as83c8978c. Recorded skip, too trivial to review;just cipassed on83c8978c.🤖 Generated with Claude Code
(written by Claude Opus 5.5)