From 45c0720f789136337c484ee11de49e95abb84a4e Mon Sep 17 00:00:00 2001 From: Danil Date: Fri, 3 Jul 2026 20:30:44 +0300 Subject: [PATCH] Fix cross-namespace defmethod: build dispatch table from relocatable contribution names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit expand-method-impl rebuilt the multimethod dispatch table from (keys contributions) — the bare synthetic class names. A bare name only resolves when the defmethod lives in the same namespace as its defmulti; for a cross-namespace defmethod, compiling the multimethod's namespace fails with: Unknown symbol: multi$SLASH_kind... (no source location) emit-contribute* already stores the relocatable ($lib:-qualified) class name as the contribution value (relocatable-class-name), keyed by contributing namespace — the same resolution mechanism protocol extensions use. Build the table from those values instead. Minimal repro (fails before, compiles and dispatches correctly after — same-namespace methods keep working, their relocatable names resolve locally too): ;; repro/multi.cljc (ns repro.multi) (defmulti kind :type) (defmethod kind :same-ns [_] "same-ns") ;; repro/ext.cljc (ns repro.ext (:require [repro.multi :as multi])) (defmethod multi/kind :cross-ns [_] "cross-ns") --- clj/src/cljd/compiler.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clj/src/cljd/compiler.cljc b/clj/src/cljd/compiler.cljc index b734f511..273feb2f 100644 --- a/clj/src/cljd/compiler.cljc +++ b/clj/src/cljd/compiler.cljc @@ -915,7 +915,7 @@ :clj true #_#_:cljd/contrib (case kind :defmethod true :defmulti false)) (let [table# (-> {} transient ; idea (-> {} (^:const (SomeIFnClass)) ...) - ~@(for [cname (keys contributions)] + ~@(for [cname (mapcat vals (vals contributions))] `(~(with-meta (list cname) {:const :required}))) persistent!)] (cljd.core/-mk-multimethod '~name