Skip to content

Retire the Arrange trait in favour of inherent methods - #843

Merged
frankmcsherry merged 1 commit into
master-nextfrom
retire-arrange
Aug 25, 2026
Merged

Retire the Arrange trait in favour of inherent methods#843
frankmcsherry merged 1 commit into
master-nextfrom
retire-arrange

Conversation

@frankmcsherry

Copy link
Copy Markdown
Member

Arrange was an extension trait whose only implementors were Collection itself, in the same crate. It existed to let two overlapping impls coexist: one for (K, V) collections arranged by key, and one for K collections arranged by the whole record. As inherent methods those would collide, since K instantiated at a pair covers the first impl's shape.

The record-arranging impl was sugar for .map(|k| (k, ())) before arranging, and it is worth deleting for its own sake. Which of the two impls a call site selected was decided by the builder type's Input, three type arguments away from the choice, so the same turbofish could arrange by key or by record depending on a parameter that named neither.

That is not hypothetical. Three call sites — one in graspan1, two in spines — were reaching the record-arranging impl while spelling ValBatcher / ValBuilder / ValSpine. They now say .map(|k| (k, ())) explicitly and keep exactly the spine they had. Six others, which spelled the Key* types, move to arrange_by_self.

With one impl left there is no overlap, so arrange and arrange_named become inherent methods on Collection<(K, V)> with unchanged signatures. Call sites are untouched, since inherent resolution matches what the trait provided; only the use ...::Arrange; imports go away.

+27 −60 across seven files. Whole workspace builds warning-free and the test suite passes.

🤖 Generated with Claude Code

`Arrange` existed to let two overlapping impls coexist on `Collection`: one
for `(K, V)` collections arranged by key, and one for `K` collections
arranged by the whole record. As inherent methods they would collide, since
`K` instantiated at a pair covers the first impl's shape.

The second impl was sugar for `.map(|k| (k, ()))` before arranging, and it
is worth deleting for its own sake. Which of the two impls a call site
selected was decided by the builder type's `Input`, three type arguments
away from the choice, so the same turbofish could arrange by key or by
record depending on a parameter that named neither. Three call sites in
`graspan1` and `spines` were reaching the record-arranging impl while
spelling `ValBatcher`/`ValBuilder`/`ValSpine`. They now say `.map(|k| (k,
()))` and keep the spine they had; six others move to `arrange_by_self`.

With one impl left there is no overlap, so `arrange` and `arrange_named`
become inherent methods on `Collection<(K, V)>` with unchanged signatures.
Call sites are untouched: inherent resolution matches what the trait
provided. Only the `use ...::Arrange;` imports go away.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@frankmcsherry
frankmcsherry merged commit 7b8d4ea into master-next Aug 25, 2026
6 checks passed
@frankmcsherry
frankmcsherry deleted the retire-arrange branch August 25, 2026 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant