Skip to content

Protocol dispatch through a deftype/reify's declared interfaces - #702

Merged
yogthos merged 1 commit into
mainfrom
fix/iface-tags-reify-deftype
Aug 22, 2026
Merged

yogthos merged 1 commit into
mainfrom
fix/iface-tags-reify-deftype

Conversation

@yogthos

@yogthos yogthos commented Aug 22, 2026

Copy link
Copy Markdown
Member

Stacked on #701 (round 4), which is stacked on #697.

value-host-tags reported only ("Object") for a reify and (tag "Object") for a bare deftype, so an extend-protocol filed under an interface name could never reach one — clojure.lang.IReduceInit, java.lang.Iterable, or an ancestor like Associative for a type declaring IPersistentVector. Both now report their declared interfaces plus the ancestry the class graph already holds; register-inline-protocol! files each declared interface as a super of the type's tag, so the derivation is transitive and matches instanceof. A defrecord's extra declared interfaces join its automatic map set the same way.

satisfies? agreed with the old dispatch rather than with the JVM — it consulted only the type's own registry and answered false where an interface extension applied. It now falls through to the same interface walk, so dispatch and satisfies? give the same answer.

The type's own tag is still tried first (an extend-type on the type wins), and Object extensions still catch types that declare nothing.

This is the last core item from the Grain gap audit (bead jolt-o3sw.13), split out of the round-1 reducible work.

Validation

  • 8 corpus rows, each certified against JVM Clojure 1.12.5 first
  • make test green: exit 0, 0 new divergences, unit 1394/1394, 82 CI targets
  • make gambitgen re-run (protocols.ss is concatenated into records-gambit.ss); gambitseedcheck passes

value-host-tags reported only ("Object") for a reify and (tag "Object") for a
bare deftype, so an extend-protocol filed under an interface name could never
reach one — clojure.lang.IReduceInit, java.lang.Iterable, or an ancestor like
Associative for a type declaring IPersistentVector. Both now report their
declared interfaces plus the modeled ancestry the class graph already holds
(register-inline-protocol! files each declared interface as a super of the
type's tag), which is what instanceof answers on the JVM. A defrecord's extra
declared interfaces join its automatic map set the same way.

satisfies? agreed with the old dispatch, not with the JVM: it checked only the
type's own registry and answered false where an interface extension applied.
It now falls through to the same interface walk.

The type's own tag is still tried first, so an extend-type on the type wins,
and Object extensions still catch types that declare nothing.
@yogthos
yogthos changed the base branch from fix/grain-core-round4 to main August 22, 2026 20:07
@yogthos
yogthos merged commit cbd86da into main Aug 22, 2026
6 checks passed
@yogthos
yogthos deleted the fix/iface-tags-reify-deftype branch August 22, 2026 20:07
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